The Navier-Stokes equation is below
is density.
is the velocity vector.
is the pressure.
is the stress tensor.
is any body acceleration on the particles.
For this simulation the only body acceleration is the mouse dragging. We can just ignore it.
The material derivative for a velocity field is defined below.
So original equation expanded is below.
The stress tensor is defined as
where is the identity matrix, and are viscosity constants. Simple algebreic manipulation yields a solution for the change in time.
But we still need to define what is. To do this we add the additional constraint that the fluid is incompressable, meaning the density is constant over space and time.
The change in density follows from the continuity equation in a velocity field.
The time derivative is zero from our constraint, and we apply the chain rule on the right.
And the gradient is zero also zero from our constraint, and we can divide out the density (assuming it isn't zero).
Thus our incompressability condition implies that the velocity field has zero divergence.
Now we can try to find solve for pressure given the constraint that divergence of velocity is zero everywhere. First start with the time evolution equation with the stress tensor expanded.
The term is equal to zero since the velocity divergence is zero by the constriant.
Distribute the divergence operator.
And because once again the divergence is defined to be zero.
Then take the divergence of both sides
And derivatives usually commute unless it's some really weird function. So we can move the divergence inside on the left hand side. Also the middle term is zero because .
And once again the gradient is always zero so the left is zero.
So we get a constraint on the pressure.
We need to show that the formula above should give uniquelly up to a constant. Consider two solutions
One can see that
But we can add any function to a solution and it's still valid. So the solution's aren't unique up to a constant. The fix is we apply a boundary conditions.
If we enforce the boundary condition by setting so that it doesn't slip on the wall.
Becomes
Then
If we have the boundary condition by setting so that the fluid doesn't flow into or out of the wall. Then dotting both sides by gives.
And the left is zero so
Let the difference between two solutions be the below. We want to show that it's a constant everywhere.
And we know
. And because the two solutions have the same gradient on the boundary on the wall. Thus dotting it with the normal vector it's also zero.And there's also the vector calculus identity below.
But the right most term is zero.
Then if we integrate over the volume
But we can also apply the divergence rule
And we know on the boundary.
And since magnitude is always positive it must be that:
Which means it's a constant.
We have the proof that it works on a vector field but in reality we'll need to discreetize it for the simulation. We will have our velocity field live on a grid with spacing . We then update it with two steps. We first advect it without accounting for pressure into an intermediate velocity .
Here we define the divergence with a symmetric finite differences
We define the next velocity to be
As usual we want the divergence of it to be zero so
And if we substitute it in
Then rearrange
And the denominators don't matter.
Then expand even more
Note that this is like a discrete version of the from earlier, because . Now if you solve for pressure of the current cell it gives the below.
And this is just a linear system of equations you can solve with whatever method. Its technically just a really big matrix.
We also have to define how it handles the boundary conditions. We skipped over how the gradient operator should be handled when it goes off the grid. We focus on the case of no viscosity. So we want
Then try and figure it out
Then substitue
And expand again
In the simulation we have 4 possible normal vectors for each of the four sides. On the left and right sides
Then
And similarily for the top and bottom sides
Thus on the boundary you can solve for the pressure that's outside grid. For example when . And for velocity you can just assume its zero outside the grid because it would be divergence free anyways since the boundary cells are constrained to be orthogonal to the normal vector.
VortexShedding github for a lot of the webgl shader code