Data and Checkpoints¶
There is no use for running a simulation if it doesn’t export anything. Despite that, if everything produced is exported the amount of data would be overwhelming, probably it wouldn’t even fit into a common hard drive.
The field data describes specifications for data save and some checkings to do with these data.
Some of the features available are:
Runtime guards (divergence and sanity checks)
Exports (
data.exports): a single, unified concept for every field/series export. Each export picks a target (named entities grouped by kind: volumes, lines, csvs, points, bodies, planes - kinds mix freely) and one or more outputs (instantaneous snapshots and/or running statistics)Monitors for global statistics over time
IBM nodes export
Body friction nodes export
Guards¶
Runtime guards are the single mechanism for divergence and sanity control. A guard
pairs a source (what to measure), a condition (when it trips) and an
action (what to do), checked on its interval. Guards are declared under
data.guards.
With no guards declared, an implicit default set applies the standard divergence
behaviour: the fluid density rho is checked is_nonfinite -> stop every 10 steps,
each passive transported field is checked is_nonfinite -> freeze (a field that goes
NaN/Inf is frozen and dropped from exports while the fluid and healthy fields keep
running), and each coupled field (Boussinesq scalar or coupled DDF energy) is checked
is_nonfinite -> stop. A declared guard whose source targets a given field (the
fluid, or a specific transported field) replaces that field’s implicit default -
this is the single customization path.
Source - exactly one of:
field: a macroscopic peeked cheaply from one random block (the fluidrho, or a transported field’s conserved macro such astemperature_phi). A cheap peek is only sound for theis_nonfinitecondition, so afieldsource rejects threshold conditions.monitor(withstat, andmacrwhen the monitor watches several): a whole-region reduction over the blocks of a declareddata.monitors.fieldsentry. Threshold conditions must use amonitorsource.
Condition: is_nonfinite (NaN/Inf), gt / lt / abs_gt (need value), or
outside (needs lo < hi).
Action: stop aborts the run; freeze flags a transported field as diverged so
it is frozen and dropped from exports (only valid for a transported field, not the
fluid); warn only logs; ignore is a no-op, used to override and disable an implicit
default (for example to turn divergence checking off for a field).
simulations:
- name: example
data:
guards:
# Cheap NaN/Inf check on the fluid density every 20 steps (overrides the
# implicit fluid default to change its cadence).
fluid_nan:
field: rho
condition: is_nonfinite
action: stop
interval: {frequency: 20}
# Threshold guard backed by a monitor reduction: abort if the domain-max
# density exceeds a bound.
rho_cap:
monitor: rho_max # a declared data.monitors.fields entry
macr: rho
stat: max
condition: gt
value: 2.0
action: stop
Macroscopics¶
The data available is mostly based on the macroscopics fields for the simulation. The list below describe the name of the fields and what they represent:
rho: Densityu: Velocity (ux,uy,uz)S: Stress tensor (Sxx,Sxy,Sxz,Syy,Syz,Szz)theta: Relative temperature (only for simulations with thermal model)omega_LES: Value of total omega (only for simulations that use LES)omega_mask: Mask value to use for omega (only for simulations that use wall model)f_IBM: IBM force (only for simulations that use IBM) (f_IBMx,f_IBMy,f_IBMz)sigma: Sigma value for HRRBGK (only for simulations that use HRRBGK)
All fields that require one or a list of macroscopics must use these names to refer to them. If the field doesn’t exist, it won’t be exported or used.
Beyond these built-in fields, you can define derived fields (named expressions
over the macroscopics, such as ux*uy) at the data root and use them anywhere a macroscopic name
is accepted.
Export rescale¶
Output rescale, rename and time-rescale are declared as named profiles in the registry
data.export_rescales. Each export (and monitor) then selects which profile to apply through
its own rescale field; an export with no rescale applies no rescaling. Per-export
macroscopic selection (macrs and the statistics macrs_1st_order / macrs_2nd_order lists)
stays on each export.
data:
export_rescales:
physical: # profile name
# Lattice-to-physical rescale per macroscopic: result = value * mul + cte.
# Keys are macroscopic names that exist in the config (base or derived).
macrs_rescale:
rho: { mul: 1e3, cte: 0 } # lattice rho -> kg/m3
ux: { mul: 41, cte: 0 } # lattice velocity -> m/s
# Rename macroscopic output names (keys are macroscopic names, e.g. ux not u).
macrs_rename: { rho: pressure }
# Multiply the time-step index by this factor for the output time axis.
# Defaults to 1.
time_rescale: 1
raw: {} # an empty profile, or simply omit `rescale` on an export, for no rescaling
exports:
field_volume:
macrs: ["rho", "u"]
rescale: physical # this export uses the `physical` profile
# ... interval / target / outputs ...
macrs_rescale: per-macroscopic affine rescalevalue * mul + cte, converting lattice values to physical units. For a derived field it is applied to each base before the expression is evaluated.macrs_rename: remaps a macroscopic’s exported name (the rename applies on output only).time_rescale: multiplies the time-step index for the output time axis (use the lattice-to-physical time ratio to convert to seconds).An export’s / monitor’s
rescalemust name a declared profile; an unknown name fails to load.
Important
Rescale, rename and time-rescale are declared as profiles under data.export_rescales and
selected per export via rescale. There are no per-export macrs_rescale, macrs_rename or
time_rescale fields on the instantaneous, statistics, series and monitor blocks; a config that
sets them fails to load.
Export coordinate system¶
data.export_rescales rescales macroscopic values; the coordinates an export writes
(volume node positions, probe/monitor positions, geometry) are selected separately by the
export’s system field, naming a coordinate system. The
lattice (lbm) coordinates are mapped into that frame on export; omitting system (or lbm)
writes lattice coordinates. The chosen system and its lbm-to-system transform are recorded in
the export’s XDMF/HDF5 metadata. Output systems must be non-rotated (scale + translation
only).
data:
exports:
field_volume:
macrs: ["rho", "u"]
rescale: physical # value rescale profile (independent of `system`)
system: site # write node coordinates in the `site` frame (metres)
# ... interval / target / outputs ...
monitors:
fields:
near_building:
system: site # monitor positions written in `site`
# ... macrs / stats / interval ...
Important
Output coordinates are expressed per export with system (declaring the frame under
domain.systems); there is no global output-only coordinate rescale. An export system is a
similarity transform: isotropic scale only, no per-axis scaling.
Exports¶
Every field and time-series export is configured under one field, data.exports. Each named
export carries its macroscopic selection (macrs), one interval, a target (where it
samples) and an outputs block (what it produces). This single concept covers instantaneous
volume snapshots, statistics, and probe time series. Output rescale, rename and time-rescale are
declared as named profiles in
data.export_rescales and each export selects one via its rescale field.
simulations:
- name: example
data:
exports:
# Volume snapshots with running statistics.
field_volume:
macrs: [rho, u, S]
interval: { frequency: 1000, lvl: 0 }
target:
# Named volume entities. Each exports the macroscopic field over a
# domain volume; any block fully outside the volume is skipped.
volumes:
wake:
volume:
start: [32, 0, 0]
end: [448, 128, 64]
is_abs: true # defaults to true
max_lvl: -1 # max level to export; -1 exports all levels
max_h5_size_gb: 4.0 # HDF5 rollover threshold in GB
full: {} # a second entity: the whole domain, defaults
outputs:
instantaneous: true # write the raw field every interval
stats: # running mean (1st order) and mean-of-squares (2nd order)
macrs_1st_order: [rho, u]
macrs_2nd_order: [u]
flush_interval: 0 # 0 = snapshot only at end; >=100 = also periodic + checkpoint
# A plane probe time series, sharing one export with a volume snapshot
# of the same region (kinds mix freely).
inlet_plane:
macrs: [ux, uy, uz]
interval: { frequency: 50, lvl: 0 }
target:
# A series target holds any of: lines, csvs, points, bodies, planes.
planes:
mid:
axis: z
axis_pos: 32
dist: 1
volumes:
inlet_box:
volume: { start: [0, 0, 0], end: [64, 128, 64], is_abs: true }
outputs:
instantaneous: true
Each export saves an XDMF+HDF5 file set that can be viewed using ParaView.
Targets¶
A target holds named entities grouped by kind. Every kind is an entity collection, the kinds mix freely in one export, and at least one entity must be defined across them.
target.volumes: named volume entities, each exporting the macroscopic field over a domain volume (the regions statistics also accumulate over these). Each entity carries itsvolumebox,max_lvl(maximum refinement level to export;-1exports all levels) andmax_h5_size_gb. Thevolumebox accepts asystemfield naming the coordinate system its corners are given in (defaultdomain.default_system); is_abs, non-rotated systems only, mapped tolbmat load. This is the box’s input frame and is independent of the export’s ownsystem(which sets the output coordinate frame). See Coordinate systems.target.{lines,csvs,points,bodies,planes}: a collection of point-like entities sampled by interpolation. See Series targets below for each entity kind. Lines, points, planes and CSVs accept asystemfield naming the coordinate system their coordinates are given in (defaultdomain.default_system); the points are mapped tolbmbefore sampling. See Coordinate systems.
Outputs¶
The outputs block selects what an export produces. The two outputs are independent, so all
combinations are valid (instantaneous only, stats only, or both); at least one must be
enabled.
instantaneous(bool): write the raw field/series value at eachintervalstep.stats({macrs_1st_order, macrs_2nd_order, flush_interval}or null): accumulate runtime statistics over the export’sinterval. First order is the running mean; second order is the running mean of the squared value (the basis for the standard deviation). The accumulators roll in place. By default (flush_interval: 0) they are written once, as a single snapshot at the end of the run, so statistics add negligible disk footprint. Setflush_intervalto a positive number of level-0 steps (at least 100) to also snapshot the partial averages periodically and on checkpoint - useful for inspecting convergence on long runs. The order lists may name built-in macroscopics or derived fields; a derived name accumulates the statistics of its per-step value (souxuyinmacrs_1st_ordergives<ux*uy>, never<ux><uy>). Stats macroscopics must be a subset of the export’smacrs, except derived names, whose bases are pulled in automatically.
Note
There is no dedicated spectrum output kind: a series export with
outputs.instantaneous: true and interval: {frequency: 1, lvl: max} samples at the
maximum rate. See Spectrum analysis.
Note
The selected profile’s macrs_rescale is applied to the
instantaneous value before statistics accumulation, so a rescaled second-order field stays
correct. Renaming (macrs_rename) is applied on output only.
Note
Some arrays, such as f_IBM, are not present in all blocks. For the blocks where they do
not exist, the exported values are filled with NaN (not a number).
Derived fields¶
Derived fields are named SymPy expressions over base macroscopic instance names, declared once at
the data root in data.derived_macrs:
data:
derived_macrs:
uxuy: "ux*uy"
uxuz: "ux*uz"
uyuz: "uy*uz"
exports:
...
A derived name can then be used like any built-in macroscopic in any export: in an export’s
macrs list (instantaneous volume, series) and in the stats order lists. When an
export references a derived name, its base instances are pulled into that output’s read/sample/
interpolation set automatically, the expression is evaluated per node (or per sample) on the
materialized base values, and the result is emitted under the derived name. Bases pulled in only
to support a derived field are not written unless the export also requests them. The selected
profile’s macrs_rescale is applied to each base before the
expression is evaluated, and macrs_rename applies to the derived output name like any field.
Rules:
An expression may reference only base instance names (
rho,ux,uy,uz,Sxy, …) plus the whitelisted math functions; it may not reference another derived field (no derived-on-derived).A derived name must not collide with a built-in macroscopic name.
A common use is the full Reynolds stress tensor: combine the second-order means of the velocity components with the first-order means of their derived products.
data:
derived_macrs:
uxuy: "ux*uy"
uxuz: "ux*uz"
uyuz: "uy*uz"
exports:
reynolds:
macrs: [u]
interval: { frequency: 1000, lvl: 0 }
target:
volumes:
reynolds:
volume: { start: [0, 0, 0], end: [128, 128, 64], is_abs: true }
outputs:
stats:
macrs_1st_order: [u, uxuy, uxuz, uyuz] # <ui> and <ui uj>
macrs_2nd_order: [u] # <ui^2>
The Reynolds stresses then follow offline as <ui^2> - <ui>^2 (diagonal) and
<ui uj> - <ui><uj> (off-diagonal).
Interval¶
interval controls when an export’s instantaneous and statistics outputs run.
interval:
start_step: 0 # first step (in `lvl` units); defaults to 0
end_step: 0 # last step (0 = run to the end)
frequency: 0.3 # may be fractional
lvl: 0 # reference level, or the literal "max"
constant_dt: true # default: uniform (floored) interval; false = closest-snap
frequencymay be fractional, andlvlmay be the literal"max"(always the grid’s finest refinement level, so a config never hard-codes the grid depth).Because every level advances with a constant
dt, exports can only land on an integer multiple of the finest level’sdt(the internal iterations). How the requested interval maps onto those iterations is set byconstant_dt:constant_dt: true(default, uniform): the requested interval is rounded down to a whole number of finest-level steps,floor(frequency * 2**(max_lvl - lvl))(clamped to at least one), and exports fire at every multiple of that fixed period, so consecutive snapshots are equally spaced in time. For example,frequency: 0.1on a grid withmax_lvl: 4(finest step0.0625) exports exactly every0.0625(floor(0.1 / 0.0625) = 1finest step); the realised interval is at or below the requested one. This is what evenly-sampled series, animations, and spectral post-processing want.constant_dt: false(closest-snap): the ideal export timesn * frequencyare snapped to the closest achievable finest-level iteration. For example, withfrequency: 0.3on a grid whose finest step is0.25, exports land at0.25, 0.5, 1.0, 1.25, 1.5, ...- the spacing alternates but the long-run average interval stays0.3.
Volume transformations¶
A volume entity is an axis-aligned box, referenced for transformation by the qualified name
volume.<export>.<entity> (or volume.<export> to match every volume entity of the export)
in domain.global_transformations.probes_apply. Only translation and scaling are
supported; rotation and inversion are ignored with a warning, since an axis-aligned box
cannot be rotated. The transformed box is re-validated to stay legal (start < end).
Monitors¶
Sometimes keeping track of global statistics over time is important, to know wheter the simulation is stabilizing or diverging, if mass is being gained, velocity is out of control or other multiple use cases. For this Nassu implements monitors to keep track of macroscopics statistics during simulation.
simulations:
- name: example
data:
monitors:
fields:
# Monitor name
rho_max:
# Macroscopics to monitor
macrs: [rho, ux]
# Optionally select a `data.export_rescales` profile (omit for none).
rescale: physical
# Statistics to check, available ones are: min, max, mean, pos
# pos exports the position of maximun and minimun value (if they are selected)
stats: [max, pos]
# Interval in which to monitor statistics
interval: {start_step: 500, end_step: 10000, frequency: 50}
# Steps between successive writes of the CSV and plot.
# Defaults to 250
interval_flush: 250
# Another example of macroscopics statistics
macrs_stats:
macrs: [rho, uy, Sxy, Sxz]
stats: [min, max, mean]
interval: {start_step: 0, end_step: 0, frequency: 500}
# It's possible to define a series of volumes to monitor only blocks in it.
# If none is specified, it checks the full domain.
# The checking is done based on blocks, so the volume may be a bit larger than specified
volumes_monitor:
- start: [10, 20, 0]
end: [100, 100, 100]
is_abs: true
# A monitor volume may name a coordinate system its corners are given in
# (default domain.default_system). Only absolute, non-rotated systems are
# supported; see domain.md#coordinate-systems.
- start: [0, 0, 0]
end: [40, 40, 20]
is_abs: true
system: site
- start: [0.1, 0.1, 0.1]
end: [0.9, 0.9, 0.9]
is_abs: false
# In case any volume should be ignored, it can be specified here. All blocks that are
# fully inside a volume to ignore are not used for monitoring.
volumes_ignore:
- start: [50, 60, 5]
end: [70, 120, 10]
is_abs: true
Each monitor exports a .csv file and plots the statistics over time for each macroscopic.
Monitor rows are buffered in memory and committed (CSV append and plot re-render) in
batches every interval_flush steps, mirroring a series export’s interval_flush.
Lower values keep the on-disk files more up to date and reduce peak memory at the cost of
more frequent disk I/O; the buffer is also force-flushed at end of run and on checkpoint.
IBM Nodes¶
IBM Lagrangian nodes carry per-node values (interpolated velocity, spread
force, friction velocity, the filtered streamwise pressure gradient, …).
The field data.export_IBM_nodes configures the export.
simulations:
- name: example
data:
export_IBM_nodes:
export_main:
body_name: my_body
start_step: 500
end_step: 10000
frequency: 100
# Export mode: `triangle` (default) or `point_cloud`. See below.
mode: triangle
# `stride` / `target_num_nodes` apply to `point_cloud` mode only.
# Export every Nth Lagrangian node. 1 keeps all nodes; 2 keeps
# nodes 0, 2, 4, ...; etc. Defaults to 1.
stride: 1
# Desired approximate number of exported nodes. When set, overrides
# `stride` by deriving an effective stride from the body's total
# node count. Leave unset (null) to use `stride`. Defaults to null.
target_num_nodes: null
# H5 rollover threshold in gigabytes. A new chunk is started as
# soon as the current chunk exceeds this size. Defaults to 4.0.
max_h5_size_gigabytes: 4.0
# Number of (lvl-0) simulation steps between successive HDF5
# writes. Per-step snapshots are accumulated in memory and
# committed to disk in batches; lower values trade memory for
# more frequent I/O. Defaults to 250.
interval_flush: 250
Per-step snapshots are accumulated in memory and committed to disk in batches every
interval_flush (lvl-0) simulation steps, mirroring a series
export’s interval_flush. The buffer is also force-flushed at
end of run and on every checkpoint, so the on-disk stream is always consistent
with the checkpointed state.
The exporter writes a single XDMF temporal collection per body at
<sim_output>/geometry/body.<body>.nodes.xdmf, backed by rolling HDF5 chunks
<sim_output>/geometry/body.<body>.nodes.NNN.hdf. The static geometry is
written once into the first chunk and reused by every timestep grid; per-step
fields are appended as new datasets.
ParaView (and any XDMF-aware reader) opens the .xdmf directly and
exposes a working time slider plus all fields as attribute arrays.
For programmatic access, SimulationOutput.bodies[name].read_ibm_xdmf()
returns a vtkXdmfReader wired to the file.
Export modes¶
The mode field selects how the nodes are written.
triangle (the default) writes a triangle-conformed mesh: the topology is
the source geometry’s own faces (vertices + triangle connectivity), and each
triangle carries one representative value as a Cell-centered attribute. The
runtime IBM node set does not map one-to-one to the geometry’s triangles (the
solver subdivides and redistributes them by area and refinement level), so the
nodes are aggregated back onto their source triangle: forces and area are
summed over a triangle’s nodes (the area sum recovers the source face area),
normal comes from the geometry, and the remaining fields (velocities,
pressure gradient, …) are area-weighted means. An extra n_nodes attribute
reports how many runtime nodes mapped to each face; faces with no node get
zero forces and NaN means. This view conforms exactly to the input geometry,
which makes it the natural choice for inspection and validation. It is only
valid for body geometries; point-cloud bodies have no source triangulation and
must use point_cloud.
point_cloud writes the raw Lagrangian nodes as a Polyvertex topology, with
each node’s fields (force, u_interp, pres_grad, …) as Node-centered
point attributes. This mode exposes the exact node set the solver uses and
supports sub-sampling for very large bodies:
For very large bodies (tens of thousands of Lagrangian nodes), the
stride knob sub-samples every Nth node at export time, keeping the
output proportionally smaller without changing how the solver itself
runs. The stride is applied to both the positions in the XDMF geometry
(written once) and every subsequent timestep’s attribute arrays.
If you would rather target a node count directly than guess a stride, set
target_num_nodes. When present it overrides stride: on the first export
the effective stride is derived from the body’s total node count as
max(1, round(total_nodes / target_num_nodes)), so the exported count is
close to (but not exactly) the target. A target at least as large as the
body’s node count keeps every node. The resolved stride is logged and frozen
for the run; leave target_num_nodes unset to use stride as-is.
stride and target_num_nodes apply to point_cloud mode only; setting
either with mode: triangle is a configuration error.
Body nodes¶
The field data.body_nodes configures a lean, probe-style export of
BC-independent wall friction and pressure for an IBM body, separate from the
heavy data.export_IBM_nodes mesh export above. At its frequency a read-only
friction-sampling (“post-proc”) pass measures the near-wall fluid state at each
body node and writes a dedicated per-node post-processing struct - it never
touches the IBM solver / wall-model state and spreads no force, so it never
perturbs the flow. The result is written as a flat CSV/HDF time series rather
than an XDMF mesh.
simulations:
- name: example
data:
body_nodes:
cube_friction:
body_name: my_body
start_step: 0
end_step: 0
frequency: 100
# `triangle` (default) aggregates the runtime nodes onto the body's
# source triangles; `point_cloud` writes the raw per-node rows.
mode: triangle
# Steps between successive HDF5 writes; force-flushed at end of run
# and on checkpoint. Defaults to 250.
interval_flush: 250
In the default triangle mode the runtime Lagrangian nodes (which the solver
subdivides and redistributes, so they do not map one-to-one to the geometry’s
faces) are aggregated back onto the source triangles: the intensive diagnostics
(friction_u_tau, friction_y_plus, traction_x/y/z, pressure) become
area-weighted means, area sums, and the normal comes from the source
triangle. This collapses the millions of runtime nodes down to the geometry’s
~10k faces. point_cloud mode writes one row per Lagrangian node instead;
triangle is only valid for body geometries.
There is no column selection: the export always writes the whole
post-processing set - the viscous traction_x/y/z, the friction velocity
friction_u_tau and its friction_y_plus, and the wall surface pressure
(p = rho*(1+theta)*c_s^2, sampled at the reference point co-located with the
reference velocity; the theta term folds in temperature and is 0 for
isothermal flow), plus the summed area and, in triangle mode, the n_nodes
aggregation count. The geometry columns (the centroid pos_* and the
source-triangle normal_*) go to the static topology sidecar. Only these
primitives are stored; the nonlinear scalars (wall shear tau_w, the
skin-friction coefficient Cf, the tangential direction, and the form/friction
drag split) are derived later at read time in nassu.viz.friction.
The export writes a static topology sidecar
<sim_output>/outputs/body_nodes.<body>.friction.csv (entity index, centroid,
normal) once, plus the per-timestep friction series in
<sim_output>/outputs/body_nodes.<body>.friction.h5. Per-step rows are
buffered in memory and committed to disk in batches every interval_flush
(lvl-0) steps, force-flushed at end of run and on every checkpoint.
SimulationOutput.body_nodes[name].read_full_data() returns the full series as
a pandas DataFrame.
Series targets¶
A series-target export samples a time series over a set of points. These points may be a line,
a single point, the values on a body, a CSV list or an axis-aligned plane. The entity
collections live under the export’s target; the shared knobs (macrs, interval, …) and
outputs are exactly as described under Exports. Series targets additionally accept
interval_group (steps per HDF table, default 1000) and interval_flush (steps between disk
flushes, default 250).
simulations:
- name: example
data:
exports:
series1:
macrs: [rho, u]
# rescale / rename / time_rescale come from the selected data.export_rescales profile
interval: { start_step: 78, end_step: 0, frequency: 10, lvl: 4 }
interval_group: 1000 # steps per HDF table; defaults to 1000
interval_flush: 250 # steps between disk flushes; defaults to 250
target:
# Lines to sample
lines:
line1:
# Start, end and distance between points.
start_pos: [200.46875, 79.4285, 2.905]
end_pos: [200.46875, 80.5715, 2.905]
dist: 0.28575
# Single points
points:
point1:
pos: [200.46875, 79.4285, 2.905]
# Bodies
bodies:
my_CAARC:
body_name: "CAARC"
normal_offset: 0.03125
# cell uses triangle centres; vertex uses triangle vertices
element_type: "cell" # or "vertex"
my_surface:
# A single surface of a body
body_name: "CAARC.surface_name"
normal_offset: -0.03125
element_type: "cell"
# CSV point lists (header x, y, z, separated by ,)
csvs:
my_csv:
filename: "my_filename.csv"
# Planes (3D only)
planes:
plane1:
axis: z # plane normal direction (x, y or z)
axis_pos: 2.905 # coordinate along `axis`
# In-plane bounds, ordered by global axis index excluding `axis`
# (axis=z -> (x, y)). Omit both to span the full domain.
min: [200.0, 79.0]
max: [201.0, 81.0]
# Grid spacing: scalar (uniform) or a pair (one per in-plane axis).
dist: 0.28575
outputs:
instantaneous: true
# stats is also valid on series targets:
# stats: { macrs_1st_order: [u], macrs_2nd_order: [u] }
Each entity of points (such as line, body and its names) exports a .points.csv with the actual points being exported and an XDMF+HDF5 file set with the macroscopics time series indexed by the points.
Line probes additionally export their .xdmf with an XDMF Polyline topology (TopologyType="Polyline", NodesPerElement=N), so ParaView renders the segment as a connected line instead of a scatter of dots. Point and CSV probes still use Polyvertex, which is the correct topology for them. The companion .points.csv is still written for every probe kind.
Plane probes (planes, 3D only) sample an axis-aligned rectangular grid of points at the grid vertices, spaced by dist on the two in-plane axes (endpoint-inclusive, same convention as lines). dist is either a scalar (uniform spacing on both axes) or a pair giving one spacing per in-plane axis, ordered by global axis index excluding axis - the same ordering as min/max. They are built internally as a tessellated rectangle, so they export their .xdmf with a Triangle topology and node-centered scalars: ParaView renders the plane as a surface instead of a point cloud. min/max are optional: provide both to bound the plane, or omit both to span the full domain on the in-plane axes. The plane is axis-aligned by construction; for an arbitrarily oriented plane apply a rotation (and/or translation) through the probe transformation mechanism, exactly as for other probes. Unlike body probes, transformations on a plane are intended and do not emit a warning.
Important
The time series values are indexed in reference to the original points.
For example, if the original list of points is [(1, -1, 1), (1, 1, 1), (2, 2, 2), (2, -4, 2)] only the points at index 1 and 2 are inside the domain.
So the export time series will have only point_idx values of 1 and 2, referecing to the index in the original list of points.
This is particularly useful when exporting from a body, to relate the index with the .lnas list of vertices or triangles
Spectrum analysis¶
Spectral (Fourier) analysis of a time series needs the values at the full numerical time
resolution - every internal iteration. This is an ordinary instantaneous series export at the
maximum sampling rate: interval: {frequency: 1, lvl: max} fires at every finest-level
internal iteration.
simulations:
- name: example
data:
exports:
spectrum_probe:
macrs: [rho, u]
# rescale / rename / time_rescale come from the selected data.export_rescales profile
interval: { frequency: 1, lvl: max } # every finest-level internal iteration
target:
points:
upstream:
pos: [200.46875, 80.0, 4.81]
downstream:
pos: [201.48375, 80.0, 4.81]
outputs:
instantaneous: true
Each point exports a .points.csv with the actual position used and an XDMF+HDF5 file set with the time series data.
Note
A series export samples via the GPU interpolation kernel at the exact probe position, the
better default for spectral analysis. It carries a single interval: with lvl: max, a probe
in a coarse block records repeated (zero-order-hold) values between its block’s updates - set
the export’s lvl to the probe’s block level, or split exports per region, to avoid the
repeats. The spectrum data lands in the export’s regular series files.
Checkpoint¶
One key feature is the capability of restarting a simulation, maintaining the fields and state from a previous time step.
This is provided through the checkpoint field, which tries to best fit this goal, providing the capacity to restart a simulation or to run a new one using the state of another simulation.
simulations:
- name: example
checkpoint:
export:
# Interval to export checkpoint. It defaults to no export.
interval: {end_step: 30000, frequency: 5000, start_step: 10000}
# True to save checkpoint after simulation is finished or not.
# Defaults to false.
finish_save: false
# Keep only the last checkpoint on disk, removing other saved ones in the `checkpoint` folder
# Defaults to false
keep_only_last_checkpoint: true
load:
# Start simulation from checkpoint. Defaults to False
checkpoint_start: true
# Reset simulation time step, start at 0 instead of checkpoint time step.
# Defaults to false.
reset_time_step: false
# Path to folder to load checkpoint from. If not specified, tries to load
# from the simulation output folder the last checkpoint saved
# Defaults to null
folderpath: null
There are some known limitations to the checkpoint capabilities. Some notable ones are:
The multiblock communication that requires temporal interpolation lost their previous state, starting with a constant time field.
The
statsaccumulators of an export (the runningkand averages) are backed up and restored, so accumulation resumes consistently across a checkpoint. Whenstats.flush_intervalis set, the partial averages are also snapshotted to disk on each checkpoint.For series exports the simulation overwrites the files.
Despite this, the original ones are saved in the checkpoint as well, so it’s possible to join them afterwards.