| / /| | \ | |/|/ \ \| | / | | | \| |/ | | | / - \ | - \ |/- |\|/ / \ / | |\|/| - - | | |/ |/| | / / \| / | | | |/\| \ | - \|/ / \ |\| | | ---| / o @ - | - \ - | |/| / \|/ O \ / /\|/ |/ \|/| |/ @ | / \ / | | -- | \ | | | / | / O ---| / |/ | |--- \ | |\| / \ / / \|/ ---| \|/ - \| | / -- / | --|\| | \|| | - \ |\ - -- |/ | | | \ | \|/ \| -----/ \| /|/ / \|/ | | / | |-- | - . | | |/ / \ \|\ / -.\ | | | --- o - | -- \|\ | / |/ \ \|/ |/\|/ | \ | | | | | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Fluid Simulation

Processing sketch · 4/12/2016

I read Jos Stam's paper Real-Time Fluid Dynamics for Games, and decided to take a shot at implementing his fluid simulation algorithm in Processing.

A gif of the simulation.

A gif of the simulation.

Stam models the fluid as a regular grid of square cells. A fluid density and velocity are stored for each cell. At each timestep of the simulation, the density and velocity are updated according to a set of rules that define how the quantities move between cells.

The general outline of the algorithm is:

  1. Diffuse the density of the fluid to neighboring cells. A cell's density will bleed into neighboring cells.
  2. Move—or, in fluid dynamics parlance, "advect"—the density of the fluid according to the fluid's velocity. If a cell has a velocity pointing up, then the fluid's density will move up.
  3. Diffuse the velocity of the fluid to neighboring cells. A cell with a velocity pointing up will cause the velocity of neighboring cells to point up, too.
  4. Advect the velocity of the fluid according to the fluid's velocity.

I found the loopiness of that last step particularly pleasing. Stam writes, "Self-advection may seem obscure but we can simply interpret it as the fact that the velocity field is moved along itself."