The module phi.physics
provides a library of common operations used to solve partial differential equations like fluids.
It builds on the field, geometry and math modules and constitutes the highest-level API for physical simulations in ΦFlow.
Similar to the field module, physics functions act on data structures represented by the Field
class.
In previous version of ΦFlow, all custom simulations were based on the abstract classes State
and Physics
.
This is no longer the case.
It is recommended to define custom re-usable operations as functions and call them directly from the top-level Python script. The following script runs 100 steps of an inviscid fluid simulation.
from phi.flow import *
DOMAIN = Domain(x=64, y=80, boundaries=CLOSED, bounds=Box(x=100, y=100))
velocity = DOMAIN.staggered_grid(Noise())
pressure = DOMAIN.scalar_grid(0)
for _ in range(100):
velocity = advect.semi_lagrangian(velocity, velocity, dt=1)
velocity, pressure, iterations, _ = fluid.make_incompressible(velocity, DOMAIN, pressure_guess=pressure)
Note that advect.semi_lagrangian
and fluid.make_incompressible
are standard functions in ΦFlow, contained in the standard import.
The simplest way to visualize a simple simulation with module-level variables (velocity
and pressure
in the example above) is to use the ModuleViewer
class.
In the above example, simply replace the line containing the for
loop with the following line.
for _ in ModuleViewer().range(100):
This launches a web interface displaying the velocity and pressure fields and allows you to step through the simulation step by step.
Slightly more complex examples can be found in marker.py which passively advects an additional marker field, smoke_plume.py which additionally introduces a buoyancy force, fluid_logo.py which adds obstacles to the scene and rotating_bar.py which adds geometry movement.
MantaFlow is a simulation framework that also offers deep learning functionality and TensorFlow integration. However, in contrast to ΦFlow, it focuses on fast CPU-based simulations, and does not support differentiable operators. Nonetheless, it can be useful to, e.g., pre-compute simulation data for learning tasks in ΦFlow.
One central difference of both fluid solvers is that mantaflow grids all have the same size, while in ΦFlow, the staggered velocity grids are larger by one layer on the positive domain sides (also see the data format section).
Mantaflow always stores 3-component vectors in its Vec3
struct, while ΦFlow changes the vectors size with the
dimensionality of the solver. E.g., a 2D solver in mantaflow with a velocity Vec3 v
has v[0]
for X, and v[1]
for the Y component. v[2]
for Z is still
defined, but typically set to zero. For a 3D solver in mantaflow, this indexing
scheme does not change.
ΦFlow, on the other hand, uses a two component numpy array for the velocity component of a 2D solver, where the first or last index denotes X, depending on the configuration. This scheme is closer to the typical ordering of numpy arrays, and simplifies the implementation of operators that are agnostic of the solver dimension.
As a side effect of this indexing, gravity is defined to act along the last or first dimension in ΦFlow, i.e., Z in 3D, and Y in 2D. In contrast, gravity always acts along the Y direction in Mantaflow.