I am trying to implement the Clavet method for simulating fluids in JavaScript, so debugging is a nightmare, which is why I'm asking here, hoping that someone who has gone through the same thing will tell me what I'm doing wrong.
I have it working OKAY so far:
But I have two problems:
1) Since in this method everything is sort of "offset" by half a step, I'm not sure how to bounce the particles off the walls correctly. Right now I take the particle's position and previous position and flip them around the crossed wall, then scale around the crossing point by a bounce factor.
My logic tells me that this should work. The next step in the algorithm is to update particle velocities, so I reflect the previous position also. But in practice this gives me a result which I don't understand:
This shows the "forces" on the particles. The walls reflect way too much force, which keeps everything in perpetual motion.
Formula 4.58 in this paper apparently shows a way to prevent this, but I haven't been able to get it to work.
Also there's stuff in the paper I don't get, like what "we only want to reflect the velocity that was omitted in the collision" means. Why? Could someone ELI5 this stuff to me please?
2) Even when walls aren't involved, the simulation "explodes" periodically. This happens more with higher pressure:
This is JavaScript, so there's that, but I've gone over the code and there are no divisions by zero or situations where I can imagine a NaN happening.
I've seen some talk in the papers about sim instability, and I wonder if this is it. Most of what's in this literature is beyond me.
From what I did understand (I think), one of the ways to eliminate instability is viscosity, but I added it and it didn't help with the explosions:
I can post code, but at the get-it-to-work-first stage it's kind of hard to read right now.
One final question: how do I figure out how to convert from the pseudo constants in this method to physical units?
Edit: I've discovered that the sim freezes occasionally, it seems it does produce a NaN somewhere, but Chrome catches it way too late.
assuming this is a cg project without rigorous physical significance...
first of all, you should really consider using a fixed time step for your simulation code, otherwise you'll get erratic (and visually disturbing) behaviour as dt ( and error ) jitters around. If you cannot get a consistent framerate as per your final requirements, positions should be interpolated rather than simulated at non fixed time points.
regarding your wall calculations, it clearly depends on the effect you want to ultimately achieve; so, if you apply a more or less momentum preserving mirror condition ( as you're doing now ) particles will continue 'circulating' around even if a damping is applied. If you want the fluid to 'stick' to the walls somehow, you need to introduce wall forces or some other stronger dissipative effect.
I ran your code, and after setting a consistent dt and tuning viscosity and simplifying the wall calculation to simpler "if (p.px < left) p.px = left + (left - p.px)*canvas.wallBounce; else if()..." conditions I get a nice 'relaxation' behaviour ( if this is what you're looking for ). Updating also the previous position is counterproductive as it will increase wall 'reflectiveness' so to speak.