Particle fluid simulation

Started by
12 comments, last by BRabbit27 9 years, 7 months ago

I am trying to implement fluid simulation using SPH. My problem is that the system never comes to rest, particles are always moving. When doing the simulation particles start with some velocity and if they come close to each other they repel, however, once they repel they keep going on and never form a cluster of particles in order to preserve density.

So I start to believe that the problem could be the parameters I have, rest density, mass of particles, h (support of the smoothing kernels).

Could you give me some advise on how should I set those?

Advertisement

You need repulsive and attractive forces.

Repulsive forces should dominate when very close, and attractive forces should dominate at a greater distance.

You also need some kind of friction to reduce the kinetic energy of your system over time.

Can you be more explicit about all of the forces you have affecting the particles?

Right now is only pressure that is acting on the particles, however as I said, the particles do repel each other but then, there is no attraction. I have read more about the smoothing kernels and I found they should be normalized. I am using two kernels suggested in Müller et al, Particle-Based fluid simulation for interative applications. For the density is the poly6 kernel and for the pressure is the spiky one. Since I found the normalization property of the smoothing kernel, I believe I have to found what the value for h should be, am I right?

If I'm correct the value of h for the poly6 should be 3/sqrt(2*?), while for the spiky kernel should be sort(60/?)

About the friction, when the particles hit the boundaries there is a damping factor to the velocity. However, with a simple scenario, say, two particles at a certain distance, wouldn't the simulation keep both particles at that distance? Intuitively, if they start at the exact positions where the steady state is, they will stay. On the other hand if one of the particles moves closer to the other (which is fixed at a certain position) I would expect the other particle to oscillate somehow in order to arrive to the steady state, am I right?

There are many ways of doing fluid simulations, especially if they don't need to be strictly physical correct, ie. simulating real fluids. In my sph simulation I have three different kernels:

1. a very spiky repulsive only kernel, whose sole purpose is to keep two interacting particles away from each other, based only on distance. Without this kernel, the particles may overlap and come to rest on top of each others at distance 0, which results in unwanted behaviour.

2. a less spiky repulsive / attractive kernel, whose purpose is to push or pull all the neighbouring particles of any particle, depending on the local pressure ie. how many particles are crammed into the interaction space of the given particle. At most distances this kernel applies more force to the particles than the repulsive-only kernel, keeping them "sucked" together, but not overlapping.

3. a damping kernel, whose purpose is to dampen the radial relative velocity of two interacting particles, ie. the velocity along the line connecting them. This works for both particles moving towards and away from each other. The spiky-ness of this kernel depends on wether you want to simulate thin liquids like water or thicker substances like slime or dough.

Together, these three kernels produce a liquid with complex emergent behaviour, like "ocean" waves at the surface, sound waves, current eddies, and surface tension resulting in droplets and molten-cheese style strings, depending on what values I feed it.

It's a good idea to test each kernel with the other ones turned off. This makes it easier to pinpoint bugs and unwanted behaviour.

Cheers,

Mike

There are many ways of doing fluid simulations, especially if they don't need to be strictly physical correct, ie. simulating real fluids. In my sph simulation I have three different kernels:

1. a very spiky repulsive only kernel, whose sole purpose is to keep two interacting particles away from each other, based only on distance. Without this kernel, the particles may overlap and come to rest on top of each others at distance 0, which results in unwanted behaviour.

2. a less spiky repulsive / attractive kernel, whose purpose is to push or pull all the neighbouring particles of any particle, depending on the local pressure ie. how many particles are crammed into the interaction space of the given particle. At most distances this kernel applies more force to the particles than the repulsive-only kernel, keeping them "sucked" together, but not overlapping.

3. a damping kernel, whose purpose is to dampen the radial relative velocity of two interacting particles, ie. the velocity along the line connecting them. This works for both particles moving towards and away from each other. The spiky-ness of this kernel depends on wether you want to simulate thin liquids like water or thicker substances like slime or dough.

Together, these three kernels produce a liquid with complex emergent behaviour, like "ocean" waves at the surface, sound waves, current eddies, and surface tension resulting in droplets and molten-cheese style strings, depending on what values I feed it.

It's a good idea to test each kernel with the other ones turned off. This makes it easier to pinpoint bugs and unwanted behaviour.

Cheers,

Mike

And in that case, how do you set the search radius for the nearest particles in your system? Now I am using nanoflann (KD-Tree) to look for the nearest neighbors where the search radius is the same as the support for the kernel I use to compute the density.

- I know KD-Trees are not the best way, soon I will change it to some hashing algorithm (need to do some research on this tough) -

I've simply set up a grid with cell width and height equal to the distance supported by the kernel, or "fluid particle diameter" if you prefer. For each loop, it is determined which cell the particles are currently overlapping. Each cell has a list of pointers to its neighbouring cells, and particle collision checks are only carried out between particles within the same cell or the cellls neigbours. This increases speed wit roughly a factor 10 compared to naive brute-force particle - particle collision check.

https://docs.google.com/presentation/d/1fEAb4-lSyqxlVGNPog3G1LZ7UgtvxfRAwR0dwd19G4g/edit#slide=id.p

Have you looked at LiquidFun for ideas? The above link is a slideshow describing the code.

http://google.github.io/liquidfun/

I've been doing a code review of Box2D in my spare time. It is amazing what you learn when you pick apart code like this.

I think, therefore I am. I think? - "George Carlin"
My Website: Indie Game Programming

My Twitter: https://twitter.com/indieprogram

My Book: http://amzn.com/1305076532

I've simply set up a grid with cell width and height equal to the distance supported by the kernel, or "fluid particle diameter" if you prefer. For each loop, it is determined which cell the particles are currently overlapping. Each cell has a list of pointers to its neighbouring cells, and particle collision checks are only carried out between particles within the same cell or the cellls neigbours. This increases speed wit roughly a factor 10 compared to naive brute-force particle - particle collision check.

Thanks for the advise ! So when you say you set "the grid equal to the distance supported by the kernel" in my case I would have the neighborhood-radius of a particle equal to the support of the kernel? However, I have one kernel for the density estimation and one kernel for the pressure ... in this case, how to set the neighborhood-radius of a particle?

You mean the two have different support radii? There's one bug already. If density is computed from particles within some distance from the center particle, then you would need to apply pressure force to those same particles, or you would get some very strange results.

This topic is closed to new replies.

Advertisement