• Advertisement
Sign in to follow this  

Particle fluid simulation

This topic is 1228 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Edited by BRabbit27

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites

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 for the poly6 should be 3/sqrt(2*?), while for the spiky kernel should be sort(60/?)

Edited by BRabbit27

Share this post


Link to post
Share on other sites

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? 

Share this post


Link to post
Share on other sites

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

Edited by h4tt3n

Share this post


Link to post
Share on other sites

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) -

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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?

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

 

Thank you very much for the links, I will take a look at it ! :)

Share this post


Link to post
Share on other sites

@h4tt3n yes ... I guess what you say makes actually a lot of sense. The thing is that I was reading through some SPH papers and in those, one of the properties of the smoothing kernels is that they must be normalized. So, I have two different kernels (which you can see at the paper referenced above) which have different normalization factors, therefore, I was computing the support h for each of them. What I can actually do is set the same kernel support and then compute the correct normalization factor, am I right on this?

Share this post


Link to post
Share on other sites

It's worth considering that whilst the equations in SPH might be "physically based", the behaviour in reality, certainly with a naive implementation, can be rather bouncy, very sensitive to things like the timestep (i.e. you have to tune your parameters for the timestep), and a tendency towards being unstable. I haven't done anything on this for quite a few years now, so may be completely out of date. However, it may be that you can get results that look more physically plausible in spite of being less physically based by using more ad hoc methods - for example see Dennis Gustafsson's blog posts.

Share this post


Link to post
Share on other sites

After some more reading and thinking, I guess I found something that could help.

Basically the poly6 kernel has the form   W(|r|, h) = k * (h^2 - r^2)^3   where I have to determine the value of k in order to have my kernel normalized for the desired value of the support h. Am I right on this? So if I want a smoothing kernel in the range [-0.1, 0.1] I just need to integrate this right?

Now in many of the papers proposing smoothing kernels they always have the normalization factor k depending on ? and h. Can someone explain me how to get to a normalization factor like that? Because I actually can compute the integral just as W is and get the value of the factor.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement