Architecture¶
pyOFTools turns OpenFOAM simulation state into CSV tables in three moves:
Wrap — an
fvMesh(or a sampled surface, or a sampled set) is wrapped in a geometry adapter and paired with a field to form a dataset.Transform — the dataset flows through a chain of nodes (filters, binners, aggregators) via a
WorkFlow.Write — a
TableWriterruns the workflow once per OpenFOAM write interval and appends a row to a CSV.
That is the whole model. Everything else in this page elaborates on those three pieces.
graph LR
subgraph "Step 1: Wrap"
A["fvMesh + field name"]
B["InternalDataSet"]
end
subgraph "Step 2: Transform"
C["WorkFlow (chain of nodes)"]
end
subgraph "Step 3: Write"
D["TableWriter"]
E["postProcessing/*.csv"]
end
A --> B
B --> C
C --> D
D --> E
For the shape of each dataset type and how they relate, see
Core data structures. For what happens inside WorkFlow and
TableWriter, see WorkFlow internals.
Minimal example¶
from pyOFTools.postprocessor import PostProcessorBase
from pyOFTools.builders import field
from pyOFTools.aggregators import VolIntegrate
postProcess = PostProcessorBase()
@postProcess.Table("volume.csv")
def water_volume(mesh):
return field(mesh, "alpha.water") | VolIntegrate()
This writes one CSV row per write interval, each with the volume integral of
alpha.water. The @Table decorator registers the function;
PostProcessorBase.__call__(mesh) turns the registrations into
TableWriter instances. The solver drives them through the OpenFOAM
function-object interface.
Why a pipeline?¶
A pipeline keeps each step small and orthogonal:
Spatial selectors (
Box,Sphere) restrict where.Binners (
Directional) restrict how grouped.Aggregators (
Sum,Mean,VolIntegrate,SurfIntegrate) restrict what reduction.
The same selectors and aggregators compose across datasets — a Box masks
volume cells, surface faces, and sampling points the same way — because the
middle stage speaks only in dataset types, not in OpenFOAM objects.
In-situ vs standalone¶
pyOFTools is designed for in-situ execution: the pipeline runs inside a
live OpenFOAM solver, reading the current state at each write interval. The
@PostProcessorBase / @Table API wires this to OpenFOAM’s
function-object machinery via system/controlDict
(see Wire pyOFTools into system/controlDict).
The same building blocks also work standalone: construct a WorkFlow
directly from Python against a loaded case. The gallery scripts under
Tutorials use the standalone path for testability.
Parallel execution¶
Under mpirun -np N, TableWriter runs the workflow on every rank (so
MPI reductions inside the aggregator collect from all cells) and writes the
file on rank 0 only. You do not wire the reduction yourself; the aggregator
nodes already call Foam::reduce through pybFoam. The details are in
WorkFlow internals.