There are two main viewpoints for simulating fluids:
ΦFlow supports both methods to some extent but mainly focuses on Eulerian simulations.
Before we discuss the various operations required for fluid simulations, let's define our variables and initial state. In this case, we will create a 64×96 grid, sampling velocity vectors in staggered form and marker values at the centroids.
!pip install phiflow
Requirement already satisfied: phiflow in /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages (2.5.3) Requirement already satisfied: phiml==1.2.1 in /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages (from phiflow) (1.2.1) Requirement already satisfied: matplotlib>=3.5.0 in /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages (from phiflow) (3.7.4) Requirement already satisfied: packaging in /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages (from phiflow) (23.2) Requirement already satisfied: numpy in /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages (from phiml==1.2.1->phiflow) (1.24.3) Requirement already satisfied: scipy>=1.5.4 in /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages (from phiml==1.2.1->phiflow) (1.10.1) Requirement already satisfied: contourpy>=1.0.1 in /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages (from matplotlib>=3.5.0->phiflow) (1.1.1) Requirement already satisfied: cycler>=0.10 in /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages (from matplotlib>=3.5.0->phiflow) (0.12.1) Requirement already satisfied: fonttools>=4.22.0 in /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages (from matplotlib>=3.5.0->phiflow) (4.45.1) Requirement already satisfied: kiwisolver>=1.0.1 in /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages (from matplotlib>=3.5.0->phiflow) (1.4.5) Requirement already satisfied: pillow>=6.2.0 in /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages (from matplotlib>=3.5.0->phiflow) (10.1.0) Requirement already satisfied: pyparsing>=2.3.1 in /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages (from matplotlib>=3.5.0->phiflow) (3.1.1) Requirement already satisfied: python-dateutil>=2.7 in /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages (from matplotlib>=3.5.0->phiflow) (2.8.2) Requirement already satisfied: importlib-resources>=3.2.0 in /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages (from matplotlib>=3.5.0->phiflow) (6.1.1) Requirement already satisfied: zipp>=3.1.0 in /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages (from importlib-resources>=3.2.0->matplotlib>=3.5.0->phiflow) (3.17.0) Requirement already satisfied: six>=1.5 in /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages (from python-dateutil>=2.7->matplotlib>=3.5.0->phiflow) (1.16.0)
from tqdm.notebook import trange
from phi.jax.flow import * # imports sub-modules + core classes
velocity = StaggeredGrid(Noise(), 'periodic', x=64, y=96)
plot({"velocity": velocity, "vorticity": field.curl(velocity)})
No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.) /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/phi/field/_field.py:142: FutureWarning: Instance checks on Grid are deprecated and will be removed in version 3.0. Use the methods instance.is_grid, instance.is_point_cloud, instance.is_centered and instance.is_staggered instead. return isinstance(self, Grid) /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/phi/field/_field.py:148: FutureWarning: Instance checks on PointCloud are deprecated and will be removed in version 3.0. Use the methods instance.is_grid, instance.is_point_cloud, instance.is_centered and instance.is_staggered instead. return isinstance(self, PointCloud)
<Figure size 1200x500 with 3 Axes>
The Navier-Stokes equations for fluids, $\frac{\partial u}{\partial t} = - (u \cdot \nabla) u - \nu \nabla^2 u - \frac 1 \rho \nabla p + g$, comprise multiple terms.
Operator splitting enables writing fast and stable fluid simulations by sequentially evaluating the different terms. For each of the terms, ΦFlow provides functions to compute them:
advect.semi_lagrangian
[Stam 1999], advect.mac_cormack
[MacCormack 2002]diffuse.explicit
, diffuse.implicit
fluid.make_incompressible
[Chorin and Temam 1968]All of these functions take in a state variable and return the new state after a certain time dt
has passed.
In the following example, the velocity is self-advected and made incompressible, while the marker is passively advected.
@jit_compile
def operator_split_step(v, p, dt, viscosity=0.1):
v = advect.semi_lagrangian(v, v, dt) # velocity self-advection
v = diffuse.explicit(v, viscosity, dt)
v, p = fluid.make_incompressible(v, (), Solve(x0=p))
return v, p
velocity0, pressure0 = fluid.make_incompressible(velocity)
velocity1, pressure1 = operator_split_step(velocity0, None, dt=1.)
plot({'initial vorticity': field.curl(velocity0), 'after step': field.curl(velocity1)})
/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/phi/field/_field.py:142: FutureWarning: Instance checks on Grid are deprecated and will be removed in version 3.0. Use the methods instance.is_grid, instance.is_point_cloud, instance.is_centered and instance.is_staggered instead. return isinstance(self, Grid) /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/phi/field/_field.py:148: FutureWarning: Instance checks on PointCloud are deprecated and will be removed in version 3.0. Use the methods instance.is_grid, instance.is_point_cloud, instance.is_centered and instance.is_staggered instead. return isinstance(self, PointCloud)
<Figure size 1200x500 with 4 Axes>