This example simulates a rising plume of hot smoke. It demonstrates how to advect and couple other quantities with the fluid.
%pip install phiflow
from phi.jax.flow import *
from tqdm.notebook import trange
# from phi.flow import * # If JAX is not installed. You can use phi.torch or phi.tf as well.
We begin by defining our simulation size and smoke inflow.
domain = Box(x=100, y=100)
inflow = Sphere(x=50, y=9.5, radius=5)
inflow_rate = 0.2
Our simulation advects the velocity and smoke fields, computes the buoyancy force proportional to the smoke density, and enforces incompressibility. We sample the velocities on a $64\times 64$ staggered grid, and the smoke density on a $200\times 200$ grid.
@jit_compile
def step(v, s, p, dt):
s = advect.mac_cormack(s, v, dt) + inflow_rate * resample(inflow, to=s, soft=True)
buoyancy = resample(s * (0, 0.1), to=v)
v = advect.semi_lagrangian(v, v, dt) + buoyancy * dt
v, p = fluid.make_incompressible(v, (), Solve('CG', 1e-3, x0=p))
return v, s, p
v0 = StaggeredGrid(0, 0, domain, x=64, y=64)
smoke0 = CenteredGrid(0, ZERO_GRADIENT, domain, x=200, y=200)
v_trj, s_trj, p_trj = iterate(step, batch(time=300), v0, smoke0, None, dt=.5, range=trange, substeps=3)
0%| | 0/300 [00:00<?, ?it/s]
plot(s_trj, animate='time', frame_time=80)