Smoothed Particle Hydrodynamics

Started by
8 comments, last by Micha3L 12 years, 3 months ago
Hi all,

Recently I have been working on an implementation of Smoothed Particle Hydrodynamics (basically water physics), which is fast and scalable.

As I dont have any higher maths or physics training (14 yr old here biggrin.png), most of the equations in various papers I have read are way above my head. So, I decided to base my work off Rene Schulte, in C++. Not a straight rip, just the main calculations.

I have been able to achieve a some-what workable result. The simulation is quite erratic, the water doesnt flow nicely, and the particles sometimes dip through my invisilble walls. I plan to put in a grid based sorter and other optimizations in soon (atm I only have the O(n^2) method), so the performance will be bad.

Basically, I am trying to go for a believable water look for a simple game I have in mind. (if you have the DirectX SDK by chance, there is a really good SPH sim included, just search 'fluid' in the sample browser)

Rendering and Vectors done by SFML, so you will need that to compile it, however I have included a pre-built Debug exe with the MSVC++ runtimes v11.0 ( Win 8 dev preview version). Only GL point rendering as well, I want a believable result beofre I move on.

Please dont lol too hard at my code, I am the only one working on it (not too many people my age I could collab with) and I am quite inexperinced (~1 year of cpp).

wow that was long.

tl;dr Help me with my physics please.

Thanks guys!
Advertisement
Hi Micha,

I have downloaded the code and play around with it a little. The main problem as I see it is that you have not initialized the mass of the particles but it is obviously important and used in several places to determine the resultant forces on the particles. So I think the mass is being set to zero by default and the only thing that is affecting the movement of the particles is gravity and your ad hoc method of pushing the particles apart. It looks like you've put a bunch of workarounds into the code, probably because the simulation was not working as expected. The problem you're going to have now is that when you set the mass everything is going to behave badly due to these workarounds. In any case, setting the mass has to be done but then you're probably going to have to do a bunch more debugging.

-Josh

--www.physicaluncertainty.com
--linkedin
--irc.freenode.net#gdnet

Thanks Josh,
As predicted setting each particles mass to 1 completely destroyed my simulation. You speak of workarounds, but I can't really find any. Could you just point them out for me??
Thanks,
Michael smile.png
Ok, so I have made the simulation somewhat workable now, but it is still not working as expected.
Sorry for not getting back to you sooner Micah. I have been trying to work on your code so that I could show you what I meant but just haven't really had the time. The 'workaround' that I was talking about are the way that you resolve interactions between the particles in the simulation and the way that you update the position and velocity of the particles. In the update function I would expected to see something fairly straightforward once you have accumulated the forces on the particles. For example, one simple way to update the particles is through a method called 'semi-implicit Euler'


for (size_t i = 0; i < Particles.size(); ++i)
{
Particles.Velocity += TimeStep * Particles.Force;
Particles.Position += TimeStep * Particles.Velocity;
}


What I would suggest is that you step back briefly from the SPH way of doing things and just get your particles to collide with one another and the walls as a starting point. From there, you will know that your update function is working. I'll try to get some time to work on your code, and hopefully that will help to demonstrate what I am saying.

-Josh

--www.physicaluncertainty.com
--linkedin
--irc.freenode.net#gdnet

Thanks Josh, dont worry about the time, any help is appreciated, regardless of the time.
I have put in that updater, it is much more simple and logical than the previous one.

I just quickly did a test, putting in one particle and then let it fall. It stopped, as one would expect on the floor. I then did a second test, with a second particle directly above the first. Both particles fell, then as the first stopped, the second particle simply sat above it, with a small gap, not falling to the floor as well. This looked quite bad.

Thanks,
Michael

edit: I was just looking at code on github, it seems as though many projects are grid-based, and they look quite a lot simpler. Would a method like this work with rigid but static bodies and force attraction/repulsion?

Thanks Josh, dont worry about the time, any help is appreciated, regardless of the time.
I have put in that updater, it is much more simple and logical than the previous one.

I just quickly did a test, putting in one particle and then let it fall. It stopped, as one would expect on the floor. I then did a second test, with a second particle directly above the first. Both particles fell, then as the first stopped, the second particle simply sat above it, with a small gap, not falling to the floor as well. This looked quite bad.

Thanks,
Michael

edit: I was just looking at code on github, it seems as though many projects are grid-based, and they look quite a lot simpler. Would a method like this work with rigid but static bodies and force attraction/repulsion?


I'm not entirely sure what you mean here. Grid based methods for fluid dynamics are a lot trickier than particle-based methods, IMHO. I would suggest persevering with the particle approach.

Are you using git or were you just browsing through github? I actually have your code in a private git repo (not on github) that I can share with you if you like. I'm going to try the suggestion I made to you about just implementing a standard elastic collision between the particles to get that part of it sorted out.

-Josh

--www.physicaluncertainty.com
--linkedin
--irc.freenode.net#gdnet



I'm not entirely sure what you mean here. Grid based methods for fluid dynamics are a lot trickier than particle-based methods, IMHO. I would suggest persevering with the particle approach.

Are you using git or were you just browsing through github? I actually have your code in a private git repo (not on github) that I can share with you if you like. I'm going to try the suggestion I made to you about just implementing a standard elastic collision between the particles to get that part of it sorted out.

-Josh


Ok then. I read a post on Gamasutra on grid based fluids, and it looked a lot less algebra heavy. Anyway, I dont think was very fast.

I dont use any source control, I was just looking through other people's work on there. Some of the stuff is very impressive actually.
That would be great. I'm not very experienced with source control, and in particular git, I have only checked out some svn anonymously, and never contributed. So yeah, Id love to see it, I just dont know how.

I dont use any source control, I was just looking through other people's work on there. Some of the stuff is very impressive actually.
That would be great. I'm not very experienced with source control, and in particular git, I have only checked out some svn anonymously, and never contributed. So yeah, Id love to see it, I just dont know how.


Ok, no problem. There are one or two things you'll need to do to get started with git. First, you will obviously need to download and install it (http://help.github.com/win-set-up-git/). Part of that process involves creating a public key, which is also provided on that page. You will need to send me only the public (*.pub) key (never share the private key). The public key is used to manage authentication without having to create passwords or accounts for every potential user of the repo.

I was playing around with the code on linux, so I originally had to make a couple of changes to your code and also converted the project to use CMake, which allows me to generate makefiles on linux or project files on windows. So you will also need to install CMake.

-Josh

--www.physicaluncertainty.com
--linkedin
--irc.freenode.net#gdnet


Ok, no problem. There are one or two things you'll need to do to get started with git. First, you will obviously need to download and install it (http://help.github.com/win-set-up-git/). Part of that process involves creating a public key, which is also provided on that page. You will need to send me only the public (*.pub) key (never share the private key). The public key is used to manage authentication without having to create passwords or accounts for every potential user of the repo.


I have followed that help page, and PMed you my key. It was actually quite easy.


I was playing around with the code on linux, so I originally had to make a couple of changes to your code and also converted the project to use CMake, which allows me to generate makefiles on linux or project files on windows. So you will also need to install CMake.



I have some experience with CMake, and to a lesser extent Linux. Just invite me to the repo and Ill get cracking.

This topic is closed to new replies.

Advertisement