# Stable Fluids - Jos Stam - GDC03 code

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

## Recommended Posts

Hi,

I try to fully understand the Stable Fluids method of Jos Stam. I am experimenting with the code of Stam's GDC03 implementation - paper .

In the process of understanding the solver it's vital to learn the behaviour of one step only - density diffusion, density advection and so on.
So, I would like to just play with the density solver only (no velocity update and no velocities whatsoever).
static void idle_func ( void ){	get_from_UI ( dens_prev, u_prev, v_prev );	//vel_step ( N, u, v, u_prev, v_prev, visc, dt );	dens_step ( N, dens, dens_prev, u, v, diff, dt );	glutSetWindow ( win_id );	glutPostRedisplay ();}

With no active velocities I guess this is now just a diffusion solver. And its working as it should in my mind.
Note: default value for density diffusion is zero so one have to modify it to make it work - my diffusion coefficient is 0.00075f.

But with no velocities I think it's ok to neglect the advection term in the density step.
void dens_step ( int N, float * x, float * x0, float * u, float * v, float diff, float dt ){	add_source ( N, x, x0, dt );	SWAP ( x0, x ); diffuse ( N, 0, x, x0, diff, dt );	//SWAP ( x0, x ); advect ( N, 0, x, x0, u, v, dt );}

But this seems to be incorrect. The density values are frozen as they are added from the user input, no diffusion at all - and I don't know why.

I would really appreciate if someone could point out what I miss.

##### Share on other sites

It might be that it's because diffusion causes self-advection (search for the term in the paper). Diffusion automatically implies that different parts of the cloud do/will have non-zero relative speed with respect to each other.

As you've already perceived, this self-generated velocity due to cloud expansion is different than velocity caused by mouse/external-driven forces.

In the end, it seems to me that it's all just velocity no matter what the source is, and so you've always got to use the advect() function.

You might want to email Stam for further information. He might reply, you never know.

If you're not familiar with entropy, it might be an interesting subject for you. Diffusion causes randomly directed (e.g., disordered) velocity vectors, where an external force causes coherently directed (e.g., ordered) velocity vectors.

Randomness seems natural: The molecules of a book falling in a gravitational field at a very high speed have very coherent velocity vectors. When the book hits the ground all of that kinetic energy is turned to heat and sound waves, which disperse in random directions. As well, the velocity vectors of the books molecules also randomize at this time. You will (practically) never find the reverse of this -- heat and sound waves from the environment don't magically come together to force the book's molecules to take up a coherent velocity and send the book shooting straight up into the sky. Why? Because it seems that there's no such thing as anti-diffusion.

This is what Eddington called the "arrow of time"... Disorder naturally tends to increase over time in an isolated system such as the Universe, not decrease.

[Edited by - taby on July 20, 2010 2:36:06 PM]

##### Share on other sites

Self-advection can be interpreted as “velocity should move along itself” - as Stam mentioned in his papers. This self-advection term can be found in the velocity update.

In the density update advection moves the density (dye) through the known velocity field. I can't identify any term that could generate velocity in the density update (dye diffusion + dye advection) - from theoretical and from coding point of view as well.

But I won't give in so easily, hopefully I can post the answer in the near future.

##### Share on other sites
Quote:
 Original post by TooropThanks for your thoughts.Self-advection can be interpreted as “velocity should move along itself” - as Stam mentioned in his papers. This self-advection term can be found in the velocity update.In the density update advection moves the density (dye) through the known velocity field. I can't identify any term that could generate velocity in the density update (dye diffusion + dye advection) - from theoretical and from coding point of view as well.But I won't give in so easily, hopefully I can post the answer in the near future.

Yes, sorry, I think I meant to say self-generated self-advection. If you keep the advect call in, do the vectors of the velocity field gradually become non-zero in length in the region surrounding the place where you put the initial bit of gas, even when there are zero external forces? If so, then it must be diffusion that's responsible for this apparently spontaneous creation of velocity on the macroscopic scale -- this is how it works in the real world anyway. Commenting out the diffuse call should confirm or deny that notion.

##### Share on other sites
Maybe I can't describe the situation in an adequate way or I miss your point.

There are no forces at initialization and I won't give any external forces to the simulation while on the run - I can check this because no velocity vectors can be exhibited in the grid.

I add simply dye density sources and with a positive dye diffusion coefficient everything is just fine - they are forming nice white puffs, gradually fading to gray. No spontaneous creation of velocity.

I can turn off the velocity update, it's still working fine since there's no velocity in the system and the dye diffusion step can't produce any velocity. My further guess is with no active velocity there's no point to advect the dye properties further in time through the velocity field (it's zero), so I turn off the advection part in the density update. But this backfires on the simulation, the dye won't diffuse at all, it's frozen - and I can't figure it out why is that.

Thank you for your input on the issue!

##### Share on other sites
Quote:
 Original post by TooropMaybe I can't describe the situation in an adequate way or I miss your point.

It's not your fault. It's been a long time since I went through this paper, and I'm having trouble explaining it. Thanks for your patience.

Still, my hunch is that the diffusion process creates some velocity.

If you look at Figure 1 in Stam's paper, you'll see on the right hand side that the equations have a wavelike (second-order derivative) term:

e.g.,
$+ \nu \nabla^2 \rho$

Now see the second equation in this wikipedia subsection called "Incompressible flow of Newtonian fluids":
http://en.wikipedia.org/wiki/Navier%E2%80%93Stokes_equations#Incompressible_flow_of_Newtonian_fluids

You'll find that the wavelike term is related to viscosity. Wikipedia uses the mu symbol for the viscosity coefficient. Stam uses a = N*N*dt*diff;

Diffusion implies wave behaviour. A wave implies that something is travelling outward in a radially symmetric fashion. Travel implies velocity.

Basically, my hunch is that any differences in the density field between steps that is caused by the diffuse call is self-generating some velocity, if you don't comment out the advect step. Familiarity with viscosity (the diffusion of momentum) is why.

Sorry I can't be of much more help.

##### Share on other sites
I think you get the diffusion terms (kinematic viscosity and dye (density) diffusion) wrong.

velocity update - The Navier-Stokes equation describes how we should update the velocity field in the fluid - GDC03.pdf Figure 1 (top) with nu (=kinematic viscosity) + the projection step.

dye (density) update - Advection diffusion type equation describes how to move substances (dye) through the fluid - GDC03.pdf Figure 1 (bottom) with kappa (=dye diffusion).
In my opinion this step cannot generate any velocity. On the other hand a temperature scalar field would generate buoyant forces.

I would like to create a case with zero velocity field. So I skip the velocity update entirely. Since there's no velocity I thought I can leave the advect term in the density update as well. But as I mentioned earlier something is wrong and I can't figure it out from theoretical viewpoint why can't I neglect this advection term.

Thank you for not giving up!

##### Share on other sites
Quote:
 Original post by TooropI think you get the diffusion terms (kinematic viscosity and dye (density) diffusion) wrong.

That's kind of true, though diffusion of momentum and diffusion of ink are both wavelike phenomena following identical rules.

A fast moving ball loses speed in honey faster than water because the viscosity coefficient is higher.

A high ink diffusion rate equates to fast dispersal of ink, which is equivalent to high viscosity in the previous scenario of ball/honey.

The first scenario involves an expanding cloud of kinetic energy (the ball's momentum). The second scenario involves an expanding cloud of mass-energy (ink).

If you figure it out within the next couple of days, please let me know. I'll have some time soon to look into the code more thoroughly. This is now officially driving me nuts. :)

##### Share on other sites
I've been tracking this thread for three days but did not have the time to write. A month ago I tried to implement the simulation in C# actually using Stam's paper and code. I had similar errors and "gave up" then. Yesterday I looked into it again.

I'm glad Stam provided a good to follow explanation and working code. The latter is a rarity with papers. But the code is so concise it's hard to follow. So my reverse engineering and using a different representation and catchier naming is not complete, so buggy.

I agree with Turop that you can turn on and off the various stages, but to keep it stable you have to make sure the conservation laws still work (at least, probably the boundary conditions are important, too). Can't say what's going wrong in your implementation, Toorop, but I narrowed down my bug(s) by explicitly dumping everything after each step: In my case something is going wrong with the Swap() logic of the grid values, some states freeze, no matter how I add density or forces.

@taby: I can more or less follow your explanation and I agree that diffusion is an effect of moving masses: But this happens on a microscopic level, and in this simulation is "abstracted away" with a time-varying density field. If you turn off advection there won't be velocities at all.

I hope this helps a bit. Maybe I find time to get it running, I promise to report back. And thanks for the link to the other paper. It would be so cool to get it stable and O(n). ("Only" have to learn yet another math trick. Never heard of method of characteristics before)

unbird

##### Share on other sites
Quote:
 Original post by unbird@taby: I can more or less follow your explanation and I agree that diffusion is an effect of moving masses: But this happens on a microscopic level, and in this simulation is "abstracted away" with a time-varying density field. If you turn off advection there won't be velocities at all.

I agree entirely. I'm just about done my project and then I'll look through the code to confirm this. :)

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 15
• 14
• 46
• 22
• 27
• ### Forum Statistics

• Total Topics
634046
• Total Posts
3015220
×