High-Level Solution Overview

Incompressibility Condition Reviewed

Recall Equation 1 from the last chapter:

u=0  (Incompressible Flow)(1)\tag{1} \nabla \cdot \vec{u} = 0 \; \textrm{(Incompressible Flow)}

This equation enforces the incompressibility condition. It says that the divergence of the fluid’s velocity field (called $\vec{u}$) is zero.

If the divergence of the velocity field is non-zero, then that means the amount of fluid entering a cell is not equal to the amount of fluid exiting that same cell. This would indicate either:

  1. Matter is being created or destroyed within that cell
  2. The fluid is compressible

Statement 1 would violate the law of conservation of mass, and statement 2 contradicts our assumption that the fluid is incompressible. We want to avoid compressible fluids because the math governing them is significantly more complex. We know both statements must be false:

Therefore the divergence of the velocity field must be zero.\textbf{Therefore the divergence of the velocity field must be zero.}

The Problem

Our issue is that in the process of updating our fluid simulation we need to make changes to the velocity field, which is will almost definitely result in us creating some kind of non-zero divergence within the velocity field.

Solution Overview

Our goal then for each step of our fluid simulation can be broken down into the following extremely high-level steps:

  1. Calculate a new velocity field that has a non-zero divergence
  2. Correct the vectors in the new velocity field to create a divergence-free velocity field somehow… (spoiler: it’s the next chapter)

Going back to what we learned in the last chapter, step 1 involves changing the velocity field, and as we’ve learnt, changing a velocity means applying an acceleration. So step 1 involves the successive application of all acceleration terms to the velocity field, neglecting, at this stage, any considerations regarding the divergence of the resulting flow.

This can be further decomposed into 3 shader stages:

  1. Advection
  2. Viscous Diffusion
  3. Adding External Forces

Now we move on to step 2, which actually has a technical name known as “projection”. As we will see later, the projection step really comes down to doing three things:

  1. Calculating the pressure field (by solving a Poisson equation)
  2. Calculating the gradient of this pressure field
  3. Subtracting the gradient of the pressure field from our intermediate velocity field

Which makes our final simulation flowchart look like this:

flowchart TD u[Old Velocity Field] A[Advection] e1@==> sum((+)) D[Viscous Diffusion] e2@==> sum F[External Forces] e3@==> sum u e5@==> A u e6@==> D u e7@==> F sum e4@==> u_prime["Intermediate Velocity Field (Has Divergence)"] P[Calculate Pressure Field] GP[Calculate Gradient of Pressure Field] HH[Subtract Gradient of Pressure Field from Intermediate Velocity Field] v["New Velocity Field (Divergence-free)"] u_prime e8@==> P P e9@==> GP GP e10@==> HH HH e11@==> v