Documentation of the main branch
These pages follow Mallard's main branch, which is ahead of release 0.8.0: some features they describe come with the next release.
Input file reference¶
Mallard reads a single TOML file: Mallard -i input.toml.
This page lists every key; the user guide explains
by topic when to use them, with examples and figures.
Kokkos options such as --kokkos-num-threads=N or --kokkos-device-id=N can be appended.
The spatial dimension is fixed at build time with the CMake option
-DMallard_DIM=2 (default) or 3. Vectors in the input (u, gravity,
rhou) have that many components, and expressions are in x, y, z
(z is 0 in 2D) and, where noted, t. Below, [u_x, u_y] reads
[u_x, u_y, u_z] in 3D.
[run]¶
| Key | Description |
|---|---|
cfl |
CFL number in the usual unstructured convention (Blazek eqs. 6.20-6.21; see time step): on a uniform 2D grid of spacing h, dt = cfl * h / (abs(u) + abs(v) + 2a). Measured stability limits for smooth flow are 1.26-1.6 with SSPRK3 and 1.39-1.8 with RK4, depending on reconstruction and cell type (table): use at most 1.2 (SSPRK3) or 1.35 (RK4), and 1.0 with SSPRK3 as a robust default, shocks included (but 0.25 for the Noh problem's infinite-strength shock with bound_preserving); with [chemistry] the splitting error may call for less (detonations: about 0.35 with Strang splitting, 1.0 with coupling = "simpler"). Mallard 0.5 and earlier inputs give the same time step with half their cfl. Exactly one of cfl and dt is required, except that with [numerics] preset and neither of them the preset sets cfl. |
dt |
Fixed time step |
t_stop |
Stop at this simulation time (the last step is shortened to land on it) |
n_steps |
Stop after this many steps |
t_wall_stop |
Stop after this many seconds of wall time |
cuda_graphs |
CUDA builds: run each step (time-step reduction, halo exchanges, stages) as one CUDA graph, so the host launches one graph and waits once per step instead of launching each kernel (default true). Results are the same bit for bit. Steps run kernel by kernel where the host takes part in the step: gas mixtures, average-pressure outlets, characteristic boundaries, boundary or source expressions of t, and halos exchanged with MPI ([parallel] halo_exchange); the run log says which |
At least one stop condition is required.
[mesh]¶
| Key | Description |
|---|---|
type |
file (the default), cartesian (quads), cartesian_tri (each quad split into two triangles along its bottom-left to top-right diagonal), or wedge (quads over an 8 degree compression ramp starting at x = 0.5) |
filename |
(file) Mallard HDF5 mesh (.h5 or .hdf5, see below), ASCII Gmsh mesh (format 2.2 or 4.1), CGNS file (.cgns), ANSYS Fluent mesh or case file (.msh, .cas; ASCII or binary), or OpenFOAM polyMesh (a directory: the case, its constant/polyMesh, or anything between), of triangles and/or quadrilaterals (2D), or tetrahedra, pyramids, prisms and/or hexahedra (3D); see mesh files below |
Nx, Ny |
Number of quads in x and y (default 100) |
Lx, Ly |
Domain size; the domain is [0, Lx] x [0, Ly] (default 1) |
Generated meshes have boundary zones named left, right, bottom and top.
stretching = [beta_x, beta_y] ([beta_x, beta_y, beta_z] in 3D) clusters the
nodes of a generated mesh toward both ends of each direction with a nonzero
factor: node j of N lies at L/2 (1 + tanh(beta (2j/N - 1)) / tanh(beta));
0 (the default) keeps the spacing uniform. For a channel between walls at
y = 0 and y = Ly, stretching = [0, 1.7, 0] makes the cells next to the
walls about 8 times thinner than those at the center (with Ny = 96).
periodic = ["x", "y"] (and "z" in 3D) makes a generated mesh (except
wedge) periodic in those directions: left/right, bottom/top and
back/front are joined into interior faces and disappear as boundary zones.
Every scheme sees the seam as interior. Each periodic direction needs at least
3 cells. Zones of mesh files are paired with [[periodic]] (below).
In the 3D build (-DMallard_DIM=3), generated meshes are boxes
[0, Lx] x [0, Ly] x [0, Lz] of Nx x Ny x Nz blocks (Nz, Lz default to
100 and 1), with the extra boundary zones back (z = 0) and front (z = Lz):
type |
Cells |
|---|---|
cartesian |
One hexahedron per block |
cartesian_tet |
Six tetrahedra per block (Kuhn subdivision along the block diagonal) |
cartesian_prism |
Two triangular prisms per block (split along the xy diagonal) |
cartesian_pyramid |
Six pyramids per block, with apexes at the block center |
cartesian_mixed |
Hexahedra, pyramids and prisms in successive thirds of x |
3D cell geometry is exact for warped (non-planar) quadrilateral faces: face area vectors and centroids come from a triangle fan around the face's vertex average, and cell volumes and centroids from the tetrahedra joining those triangles to the cell's vertex average.
For Gmsh meshes, each physical curve (2D) or surface (3D) becomes a boundary
zone named after it (physical_<tag> if unnamed); boundary faces not in any
such group form the zone unassigned. Elements of other dimensions (points,
and curves in 3D) are ignored. Elements of order 2 and 3 are read by their
corners; high-order boundary elements (line3, line4 in 2D; triangle6,
triangle9, triangle10, quadrangle8, quadrangle9, quadrangle16 in 3D)
curve their faces (see curved boundaries below).
Every format and the transform below are illustrated in the user guide (meshes).
[mesh.transform] maps the nodes of a mesh file as it is read,
x -> R (S x) + t: scale first, then rotate about the origin, then translate.
Boundary zones, high-order nodes and cell types are unchanged; mirroring scales
(negative factors) are allowed. [[periodic]] translations, [[mesh.curved]]
shapes, probes and every other coordinate in the input refer to the
transformed mesh. mallard-mesh-convert input.toml mesh.h5 writes the
transformed mesh.
| Key | Description |
|---|---|
scale |
A factor for every axis (e.g. 0.001 for a mesh in mm), or one per axis [s_x, s_y] ([s_x, s_y, s_z] in 3D); nonzero |
rotate |
2D: angle in degrees, counterclockwise. 3D: {axis = [a_x, a_y, a_z], angle = degrees}, right-handed about the axis through the origin |
translate |
[t_x, t_y] ([t_x, t_y, t_z] in 3D) |
[mesh]
type = "file"
filename = "nozzle_mm.msh"
[mesh.transform]
scale = 0.001
rotate = {axis = [0, 0, 1], angle = 90}
translate = [0.0, 0.0, 0.05]
CGNS files (builds with -DMallard_ENABLE_CGNS=ON) are read from their one
base, whose cell dimension must match the build. Every zone must be
unstructured, with element sections of any of Mallard's cell types (MIXED
too, and higher orders by their corners); polyhedral NGON_n/NFACE_n
sections and structured zones are rejected. Several zones are joined into one
mesh where their Abutting1to1 connectivities (vertex PointList and
PointListDonor, as Gmsh writes for partitioned meshes) identify their nodes.
Each boundary condition (BC_t, by element range or list, or by vertices)
becomes a boundary zone named after its family, or the family's
FamilyName (Gmsh writes physical names there), or else the condition
itself; boundary elements in no condition take their section's family or
name. High-order boundary elements (BAR_3, BAR_4, TRI_6, TRI_9,
TRI_10, QUAD_8, QUAD_9, QUAD_16) curve their faces like Gmsh's.
Fluent meshes (.msh files starting with (, and .cas files) are read in
ASCII or binary (single- or double-precision nodes). Every face zone other
than interior ones becomes a boundary zone named as its zone section (39 or
45) names it (zone_<id> if none does); faces of such zones with cells on
both sides (internal walls, fans) are interior faces. Cells are rebuilt from
their faces and must be triangles or quadrilaterals (2D), or tetrahedra,
pyramids, prisms or hexahedra (3D); polygonal and polyhedral cells and
adapted meshes (cell and face trees) are rejected. Periodic face zones stay
boundary zones, to pair with [[periodic]].
OpenFOAM meshes are read from points, faces (faceList or
faceCompactList), owner, neighbour and boundary, ASCII or binary
(32- or 64-bit labels and scalars); compressed (.gz) and decomposed
(processor*) meshes must be decompressed or reconstructed first. Each patch
becomes a boundary zone of its name (cyclic patches too, to pair with
[[periodic]]). Cells are rebuilt from their faces as for Fluent. The 2D
build reads a mesh one cell thick in z between empty patches (as for 2D
OpenFOAM runs): each cell is its face at the lowest z, the other patches give
the boundary edges, and the empty patches disappear.
In a distributed run every rank reads a Gmsh, CGNS, Fluent or OpenFOAM mesh whole (keeping only its
share), so large meshes should be converted to Mallard's HDF5 mesh format
(builds with -DMallard_ENABLE_HDF5=ON), of which each rank reads only its
share; generated meshes are also produced per rank:
mallard-mesh-convert mesh.msh mesh.h5 # from Gmsh (or CGNS, Fluent, OpenFOAM)
mpirun -n 8 mallard-mesh-convert input.toml mesh.h5 # a generated mesh, written in parallel
The file holds global arrays, with global ids the row indices:
/nodes/coordinates (n_nodes x dim, float64), /cells/offsets and
/cells/nodes (CSR of node ids, uint64; the cell type follows from the node
count, Gmsh/VTK node order), /boundary/offsets, /boundary/nodes and
/boundary/zone (boundary faces and their zone index), the attribute
/boundary/zone_names, and the root attributes format = "mallard-mesh",
version = 1 and dimension. Meshes with high-order boundary faces also have
/boundary/high_order/offsets (per boundary face) and
/boundary/high_order/coordinates (all nodes of each high-order face, corners
first in Gmsh order; none for linear faces).
Curved boundaries¶
Boundary faces follow the true curved geometry where the mesh file has
high-order boundary elements, or where [[mesh.curved]] projects a zone onto
an analytic shape (any mesh: generated, linear Gmsh, HDF5). Curved faces get
quadrature points on the curve or surface with their own normals and
Jacobians, and the cells touching them their exact volumes, centroids and
TENO moments; in 3D the faces sharing an edge with a curved face (side faces
of prism layers, symmetry planes meeting the wall) are blended from their
edges. This brings orders 3 to 6 to their design accuracy at curved walls
(guide: curved boundaries).
| Key | Description |
|---|---|
curved_geometry |
([mesh]) false ignores high-order nodes and [[mesh.curved]]: straight-sided faces everywhere. Default true |
zone |
([[mesh.curved]]) Boundary zone to curve |
shape |
circle (2D), sphere or cylinder (3D) |
center |
A point of the shape's center (cylinders: of their axis) |
radius |
Radius |
axis |
(cylinder) Direction of the axis |
Points of a straight face are projected radially onto the shape, minus the
linear interpolant of its corners' own offsets, so faces still meet at the
mesh nodes; zone nodes farther than 5% of an edge length from the shape are
an error. Curved boundaries are not yet supported with physics.axisymmetric.
[[periodic]]¶
Pairs two boundary zones of any mesh (e.g. Gmsh physical curves or surfaces,
or zones of an HDF5 mesh) into a periodic seam, serially and in distributed
runs: zone B must be zone A translated, node by node (to 1e-6 of the zones'
shortest edge), as Gmsh's Periodic constraint produces. The faces of both
zones become interior faces and take no [[boundaries]] entry. A node with no
match is reported with its coordinates. Each zone joins at most one pair, and
as for generated meshes, each periodic direction needs at least 3 cells.
| Key | Description |
|---|---|
zones |
[A, B]: the zone names |
translation |
[t_x, t_y] ([t_x, t_y, t_z] in 3D) with B = A + translation |
[mesh]
type = "file"
filename = "box.msh"
[[periodic]]
zones = ["left", "right"]
translation = [1.0, 0.0]
[physics]¶
| Key | Description |
|---|---|
type |
euler (default) or navier_stokes |
gamma |
Ratio of specific heats |
p_ref, T_ref, rho_ref |
A reference state, which sets the gas constant R = p_ref / (rho_ref T_ref) |
mu |
(navier_stokes) Dynamic viscosity, or its value at T_mu_ref for Sutherland's law or the power law |
Pr |
(navier_stokes) Prandtl number, default 0.72 |
viscosity_model |
(navier_stokes) constant (default), sutherland or power_law (mu (T / T_mu_ref)^viscosity_exponent) |
T_mu_ref, sutherland_S |
(sutherland) Reference temperature (default 273.15) and Sutherland temperature (default 110.4) |
T_mu_ref, viscosity_exponent |
(power_law) Reference temperature and exponent, both required |
gas |
perfect (default): a calorically perfect gas set by the keys above; mixture: a thermally perfect mixture of the species of a mechanism (no gamma, p_ref, T_ref, rho_ref) |
mechanism |
(mixture) A Cantera YAML file, e.g. mechanisms/h2o2.yaml (see mechanisms/README.md); Chemkin files convert with Cantera's ck2yaml |
phase |
(mixture) Phase of the file to use; default the first |
transport |
(mixture, navier_stokes) mixture_averaged (default: Wilke viscosity, Mathur conductivity, mixture-averaged diffusion coefficients), unity_lewis (diffusion coefficients lambda / (rho cp)) or constant_lewis (lambda / (rho cp Le_k)), as Cantera's models, from the species' transport data in the file |
lewis |
(constant_lewis) Lewis numbers by species, e.g. lewis = { H2 = 0.3, H = 0.18 }; others 1 |
soret |
(mixture_averaged) true adds thermal diffusion (the Soret effect) with Cantera's mixture-averaged thermal diffusion coefficients, as Cantera's soret_enabled (default false); output DT_<species> |
axisymmetric |
(2D) true for flows symmetric about the x axis without swirl (default false); see below |
Gas mixtures (gas = "mixture") react when the input has a [chemistry]
table; every Riemann solver and face reconstruction works (RHLL for strong
shocks prone to the carbuncle, e.g. blunt-body detonations). With type = "navier_stokes" they are viscous, heat
conducting and diffusing: species diffuse along mole-fraction gradients with a
correction velocity (so the diffusive mass fluxes sum to zero) and carry their
enthalpy, and the time step includes the largest of 4/3 mu / rho,
lambda / (rho cv) and the species' diffusion coefficients. Walls are no-slip
and non-catalytic: no species crosses them, so their species, Soret and
enthalpy diffusion fluxes vanish. wall_adiabatic conducts no heat,
wall_heat_flux the given q, and wall_isothermal lambda dT/dn from the
boundary cell to the wall temperature T, with the mean of the cell's
conductivity and that at T (and the cell's composition). Species thermodynamics are NASA-7, NASA-9 or constant-cp
polynomials from the file, evaluated in double precision in every build. Each
species is transported (rho Y_k) with mass-flux upwinding, so mass fractions
stay in [0, 1] and sum to one; all mass fractions share one stencil and one
limiter per cell (MUSCL), or the stencils TENO chose for the contact field
(TENO, which reconstructs the flow in primitive variables for mixtures and
also flags cells by jumps of the molar mass). The scheme is conservative: at contacts between gases of different
cp / cv (e.g. cold hydrogen and hot air) the pressure is perturbed at the
percent level on coarse meshes; double_flux (in [numerics]) removes that.
Axisymmetric flows¶
With axisymmetric = true the 2D mesh is the meridian half-plane of a body
of revolution: x is the axial coordinate and y the radius, so every node needs
y >= 0. Boundary faces on the axis (y = 0) must be symmetry; nothing
crosses them. The solver integrates over each cell's solid of revolution:
cell values are r-weighted averages (analytical initial conditions are
averaged that way), and fluxes, sources, forces ([[forces]]), [integrals]
and conserved totals are per radian of the revolved domain (multiply forces by
2 pi for the force on the 3D body; only the axial component is meaningful).
u is [u_x, u_r]. Every reconstruction, Riemann solver, viscous and
mixture model, chemistry and MPI work as in planar runs; meshes cannot be
periodic in y. Guide: axisymmetric flows.
[les]¶
Large-eddy simulation with an explicit subgrid-scale (SGS) model
(navier_stokes only, single gases and mixtures, planar runs). The model's
eddy viscosity mu_t = rho nu_t is added to the molecular viscosity, with
cp mu_t / Pr_t added to the conductivity and mu_t / Sc_t to every
species' diffusivity (mixtures: in the mixture-averaged form, so the
diffusive fluxes still sum to zero). Wall faces keep the molecular fluxes. The
eddy viscosity of each cell comes from its least-squares velocity gradient
g_ij = du_i/dx_j, with the filter width Delta = V^(1/3) (3D) or A^(1/2)
(2D) of the cell; the time step includes it. Design, choices and validation:
the LES guide (design notes).
| Key | Description |
|---|---|
model |
sigma (default in 3D), wale (default in 2D), vreman or smagorinsky; see below |
C |
Model constant; defaults 1.35 (Sigma), 0.5 (WALE), 0.07 (Vreman's c), 0.17 (Smagorinsky) |
Pr_t |
Turbulent Prandtl number, default 0.9 |
Sc_t |
Turbulent Schmidt number, default 0.9 |
filter_width |
scotti (default in 3D): V^(1/3) f(a_1, a_2), Scotti, Meneveau & Lilly's correction for anisotropic cells, f = cosh(sqrt(4/27 ((ln a_1)^2 - ln a_1 ln a_2 + (ln a_2)^2))) of the ratios a_1 = h_1 / h_3, a_2 = h_2 / h_3 of the cell's extents (V over the eigenvalues of its projected-area tensor 1/2 sum_f A_f A_f^T / |A_f|; 1.2 for an aspect ratio of 5, 1.4 for 10; 1 on cubes and regular cells); volume (the 2D default): Delta = V^(1/d). For the eddy viscosity only ([les.combustion] keeps V^(1/3)). Channel at Re_tau = 395 and 590: Re_tau within 0.7% and 1.6% of MKM with scotti, 2.6% and 4.1% with volume |
dynamic |
true: the constant from the global dynamic procedure (Germano et al. 1991; Lilly 1992), once per step from the state: C^2 = <L^d : M> / <M : M> (Vreman's c without the square) summed over the domain, L = (rho u u)^ - (rho u)^ (rho u)^ / rho^, M = 2 ((rho Delta^2 D(g) S^d)^ - rho^ Delta_hat^2 D(g^) S^d(g^)), with ^ the volume-weighted average over a cell and its vertex neighbors, of width Delta_hat^2 = Delta^2 + 12 / d tr(cov) from the covariance of the neighbors' centroids (3 Delta on uniform hexahedra), and filtered gradients for the gradients of the filtered field. Clipped at zero; C is the value until the first step. The sums are exact (fixed point), so the constant is independent of the rank count. integrals.csv gets the column les_C. Default false |
model |
nu_t |
Zero for |
|---|---|---|
sigma (Nicoud et al. 2011) |
(C Delta)^2 s3 (s1 - s2)(s2 - s3) / s1^2, s1 >= s2 >= s3 the singular values of g |
pure shear, solid rotation, two-dimensional flows (so not allowed in 2D builds), isotropic and axisymmetric expansion; ~ y^3 at walls |
wale (Nicoud & Ducros 1999) |
(C Delta)^2 (Sd:Sd)^(3/2) / ((S:S)^(5/2) + (Sd:Sd)^(5/4)), Sd the traceless symmetric part of g^2 |
pure shear, isotropic expansion; ~ y^3 at walls |
vreman (Vreman 2004) |
c Delta^2 sqrt(B / (g:g)), B the second invariant of g g^T |
pure shear |
smagorinsky (Smagorinsky 1963) |
(C Delta)^2 sqrt(2 S:S) |
solid rotation (no wall damping: for comparisons only) |
MU_T (output variable) is the eddy viscosity. [integrals] budget = true
measures how much of the kinetic-energy dissipation comes from the model and
how much from the scheme.
[les.combustion]¶
Turbulence-chemistry interaction of reacting LES (a viscous mixture with
[chemistry]) by the dynamically thickened flame model (TFLES; Colin et al.
2000, Légier et al. 2002): where a flame is, its species diffusivities and
conductivity are multiplied by E F and its reaction rates by E / F, which
keeps the laminar flame speed and thickens the flame by F so that it spans
n_res cells; the efficiency E restores the flame-surface wrinkling of the
subgrid scales at the filter width F delta_L: by default E = F^beta
(Charlette, Meneveau & Veynante 2002) with beta from the dynamic procedure
of Wang, Boileau & Veynante (2011), which compares the resolved flame surface
|grad c| before and after a test filter (global, exact sums; written to the
integrals file as tf_beta). F = 1 + (max(1, n_res Delta /
delta_L) - 1) Omega with the flame sensor Omega = min(1, c (1 - c) /
0.0475) of the progress variable c = (T - T_unburnt) / (T_burnt -
T_unburnt), so Omega = 1 across the whole flame (0.05 <= c <= 0.95) and 0
in fresh and burnt gas, where the molecular and SGS transport are unchanged.
In the flame the SGS heat and species fluxes are multiplied by 1 - Omega.
The rates are scaled by integrating each cell's Strang reactor over E / F
times the half step (exact for the autonomous constant-volume reactor).
F, E and Omega are computed once per step from the state, and written as
TF_F, TF_E, TF_OMEGA. Guide: thickened flames.
| Key | Description |
|---|---|
model |
tfles |
delta_L |
Laminar thermal thickness (T_b - T_u) / max dT/dx of the flame (m), e.g. from Cantera |
s_L |
Laminar flame speed (m/s) |
T_unburnt, T_burnt |
Temperatures of the fresh and burnt gas (K) |
n_res |
Cells across the thickened flame, default 5 |
efficiency |
dynamic (default): E = F^beta, beta in [0, 1] from the dynamic procedure, no constant; turbulent flame speed within 8% of two DNS at Delta = 0.4-1.6 delta_L. charlette: Charlette's efficiency function of a subgrid velocity u' (the default until #294; doubles the flame speed at Delta = 1.6 delta_L). none: E = 1. Comparison in the design notes, section 8.3 |
beta |
charlette only: exponent of the efficiency, default 0.5 |
subgrid_velocity |
charlette only: the u' of the efficiency: colin (default), u' = 2 Delta^3 abs(lap(curl u)); or eddy_viscosity, u' = C_u nu_t / Delta from the SGS model. Colin's operator overpredicts u' 5-8 times on meshes with Delta >= 0.4 delta_L and the flame speed by 2x at Delta = 1.6 delta_L |
C_u |
charlette only: constant of subgrid_velocity = "eddy_viscosity", default 28 (a priori from a DNS at Delta = 0.8 delta_L; 22-39 over Delta = 0.4-1.6 delta_L) |
Experimental: model = "pasr", the partially stirred reactor (Sabelnikov &
Fureby 2013) for non-premixed and partially premixed flames: no thickening;
each cell's rates are those of its filtered state times the reacting fraction
kappa = tau_c / (tau_c + tau_mix), with the chemical time tau_c = rho cp T /
|q| of the cell's heat release rate q and the mixing time tau_mix = C_mix
Delta^2 / (nu + nu_t) of molecular and SGS diffusion across the cell, so
kappa -> 1 where the mesh resolves the mixing and the heat release tends to
rho cp T / tau_mix where the chemistry is fast. Applied as the per-cell
chemistry time scale of TFLES (exact for the Strang reactor), once per step.
Key C_mix (default 1); output PASR_KAPPA. Against a DNS of an H2/N2-air
diffusion flame in decaying turbulence (heat release over 0.2-0.4 ms): -11%
at Delta = 0.27 mm (quasi-laminar +17%), but -50% and a near-extinguished
flame at 0.53 mm (quasi-laminar +41%). It corrects the right way at moderate
filter widths and overcorrects on coarse meshes; not validated beyond this case.
[initialize]¶
| Key | Description |
|---|---|
type |
constant (default), analytical, restart, or remap (a restart file of another mesh) |
u |
constant: [u_x, u_y]; analytical: one expression in x, y, z per component |
rho, p, T |
constant: p and T; analytical: exactly two of the three, as expressions in x, y, z |
X or Y |
(mixtures) Mole or mass fractions by species, e.g. X = { H2 = 2.0, O2 = 1.0, AR = 7.0 }; normalized, unlisted species are zero. analytical: expressions (or numbers) per listed species |
balance |
(mixtures, analytical) Species taking 1 - sum of the listed fractions; without it the listed fractions are normalized |
n_subdivisions |
(analytical) Resolution of the cell averages. 2D: each cell's triangles are split into n_subdivisions² sub-triangles (default 4). 3D: each of the cell's tetrahedra is split into n_subdivisions³ sub-tetrahedra, each with a 14-point degree-5 rule (default 1) |
file |
(restart) Restart file to resume from. Restart files list their variables by name (format version 2, 3 when they also hold the weights of [statistics] averages, or 4 when they also hold the state of characteristic boundary faces, or 5 when compressed) and are read by name; files of version 1 (Mallard 0.3 and earlier) are still read |
Expressions use exprtk syntax, e.g. "x < 0.5 ? 1.0 : 0.125".
type = "remap"¶
Starts from a restart file of another mesh (resolution, cell type, partition or rank count), remapped conservatively and to high order: see Initialization: remap from another mesh and docs/design/remap.md.
| Key | Description |
|---|---|
file |
Restart file of the source run |
[initialize.mesh] |
The source run's [mesh] table (a generated mesh or a mesh file) |
[[initialize.periodic]] |
The source mesh's periodic zone pairs, as [[periodic]] (default: the run's [[periodic]]) |
degree |
Degree of the source cells' least-squares polynomials, 0 to 5 (default 2) |
limiter |
bounds (default): each polynomial stays within the averages of its cell and vertex neighbors (one factor for the density and the species); none keeps the full order, for smooth fields |
[[boundaries]]¶
Every boundary face must be assigned exactly once (a fully periodic mesh has
none, and needs no [[boundaries]]). Each entry has a name, the boundary
zone, and a type, below. A zone can be split
between several entries with where = "<expression in x, y, z>", which selects
the zone's faces whose centers satisfy the expression.
type |
Description | Keys |
|---|---|---|
extrapolation |
Transmissive: the exterior state is the solution translated from inside the domain | |
symmetry |
Slip wall / symmetry plane | |
wall_adiabatic |
Wall (no-slip for navier_stokes, slip for euler) with zero heat flux |
u (wall velocity, optional) |
wall_isothermal |
Wall at temperature T |
T, u (optional) |
wall_heat_flux |
Wall with heat flux q into the fluid |
q, u (optional) |
upt |
Inflow with fixed velocity, pressure and temperature | u, p, T (and X or Y for mixtures: numbers, or expressions in x, y, z evaluated at each face center for a composition that varies along the boundary, with an optional balance species as in [initialize]) |
farfield |
Characteristic far field for a free stream: the outgoing Riemann invariant comes from the interior, the incoming one from the free stream, so waves leave and the boundary works for inflow, outflow and tangential flow alike | u, p, T (free stream) |
dirichlet |
Exterior state from expressions in x, y, z, t, evaluated at face centers at every stage |
rho, u (one expression per component), p |
p_out |
Outlet: imposes p if the outflow is subsonic |
p |
p_out_average |
Outlet for mixed subsonic/supersonic flow: on subsonic faces, shifts the local pressure so that its area average over the boundary equals p, preserving the transverse profile |
p |
nscbc_outlet |
Partially non-reflecting characteristic outlet (Poinsot & Lele): outgoing waves leave, and each face's incoming acoustic wave relaxes its pressure toward p at the rate K = sigma c (1 - M^2) / L. Waves of frequency omega reflect by 1 / sqrt(1 + (2 omega / K)^2) |
p, L (a length of the domain), sigma (default 0.25; 0 is perfectly non-reflecting but lets the mean pressure drift, large values approach p_out), beta (the weight of the transverse terms in the incoming wave, 0 to 1: default the local Mach number, as Lodato et al.; 1 is Poinsot & Lele's original condition, 0 drops them. Faces next to walls and other boundaries, and faces with reversed flow, have none, which keeps eddies that reverse the flow at the outlet from driving it unstable) |
nscbc_inlet |
Partially non-reflecting characteristic inlet: the incoming acoustic wave relaxes the normal velocity toward u as nscbc_outlet relaxes the pressure; temperature and tangential velocity are imposed, or relaxed with sigma_T, sigma_t; the composition is imposed. Supersonic inflow imposes u, p, T |
u (numbers, or expressions in x, y, z evaluated at face centers), p (reference pressure, for supersonic inflow), T, L, sigma (default 0.25), sigma_T, sigma_t (optional), beta (default 0 with turbulence, whose own incoming wave carries the transverse terms), X or Y for mixtures (numbers or expressions, as upt), and an optional [boundaries.turbulence] table (below) |
Characteristic conditions change only the exterior state of the convective
flux; viscous terms treat them like extrapolation (image faces, or zero
normal derivatives: the outflow conditions of Poinsot & Lele). MUSCL boundary
cells leave out their ghosts across them, so that waves leave intact. Each face keeps its pressure and
normal velocity between steps, and restart files carry them, so a restarted
run reproduces an uninterrupted one bitwise, also on a different number of
ranks (restart files older than version 4 start them afresh from the
solution). Guide: characteristic boundaries.
Synthetic turbulence ([boundaries.turbulence])¶
An nscbc_inlet with a turbulence table adds synthetic turbulence to its
target velocity: the digital filter of Klein, Sadiki & Janicka (Gaussian
correlations of the given integral lengths across the inlet and, by Taylor's
hypothesis, in time), scaled to the given Reynolds stress by its Cholesky
factor (Lund, Wu & Squires). The tangential fluctuations are imposed, the
normal one enters through the face's incoming acoustic wave, which follows the
target's change without reflecting outgoing waves. The field depends only on
the time, the seed and the inlet, so runs are bitwise the same on any number
of ranks and across restarts. The inlet must be planar and normal to a
coordinate axis; a periodic direction across it makes the field periodic. See
the guide.
| Key | Description |
|---|---|
reynolds_stress |
[R_xx, R_yy, R_zz, R_xy, R_xz, R_yz] (2D: [R_xx, R_yy, R_xy]), numbers or expressions in x, y, z, positive semidefinite |
profile |
Instead of u and reynolds_stress: a CSV file of plane averages as tools/plane_average.py writes them (a first column x, y or z, then MEAN_U_X, MEAN_U_Y(, MEAN_U_Z) and COV_U_X_U_X, ...; missing off-diagonal covariances are zero), interpolated linearly along that coordinate: the statistics of a precursor run |
length_scale |
Integral length scales: a number, [L_x, L_y, L_z] (along each direction, for all components), or one such list per velocity component. The one along the inlet normal sets the integral time scale L / U_c |
convection_velocity |
U_c of Taylor's hypothesis (default the area-averaged mean inflow speed) |
seed |
Random seed, a non-negative integer (default 1); inlets also differ by their position in [[boundaries]] |
zero_net_flux |
true (default) removes the area mean of the normal fluctuation over the inlet at every instant, which would otherwise drive a plane acoustic wave; it also removes about 4 L_y L_z / A of the normal Reynolds stress for an inlet of area A |
points_per_length |
Resolution of the generator's grid on the inlet: points per smallest integral length (default 6, at least 2) |
[[boundaries]]
name = "inlet"
type = "nscbc_inlet"
u = [1.0, 0.0, 0.0]
p = 17.857
T = 1.0
L = 6.0
[boundaries.turbulence]
reynolds_stress = [0.01, 0.01, 0.01, 0.0, 0.0, 0.0]
length_scale = 0.25
[[sponges]]¶
Optional sponge layers, each adding -strength (U - U_ref) to the conservative variables (and species partial densities) per unit volume, with U_ref the conservatives of a reference state. Several sponges add up. The explicit source caps the time step at 1 / max strength.
| Key | Description |
|---|---|
strength |
Damping rate (1/s): a number or an expression in x, y, z, zero outside the layer, e.g. "x > 4 ? 20 * ((x - 4) / 1)^2 : 0" (a gradual ramp reflects less than a step) |
u, p, T |
Reference state: numbers or expressions in x, y, z (u has one per component) |
X or Y, balance |
(mixtures) Reference composition, numbers or expressions as in [initialize] |
Strength and reference are evaluated once at cell centroids.
[numerics]¶
| Key | Description |
|---|---|
preset |
robust, accurate, les or reacting: a validated combination of face_reconstruction (type and its order or limiter), riemann_solver, convective_flux, time_integrator and [run] cfl, each used only where the input does not set that key (a reconstruction option only when the reconstruction type is the preset's; cfl only when [run] sets neither cfl nor dt). What each chooses and why: Numerics: presets. Default: none (the defaults below) |
riemann_solver |
Rusanov, HLL, HLLC (default), Roe, or RHLL (rotated hybrid HLL-Roe, carbuncle-free except at shocks at rest on cell faces; see numerics) |
time_integrator |
FE, SSPRK3 (default) or RK4 |
check_nan |
Stop if the solution becomes non-finite (default false) |
double_flux |
(gas mixtures) true for the double-flux scheme: each cell's energy is updated with its own cp / cv and energy offset frozen over the time step on both sides of its faces, and reset to the true equation of state after the step, so pressure and velocity stay exactly uniform across contacts between different gases. Energy is then not exactly conserved (about 0.2% over a multicomponent shock tube). Default false |
low_mach_cutoff |
Low-Mach correction of the convective flux: the velocity jump across each interior face is scaled by z = min(1, max(M_L, M_R, low_mach_cutoff)) before the Riemann solver, so that upwind dissipation scales with the flow speed rather than the sound speed. Default 0.1; 1 disables it. See numerics/overview.md |
convective_flux |
riemann (default): the Riemann solver at every face; hybrid: the kinetic-energy-preserving central flux of Kuya, Totani & Kawai (2018) on the same reconstructed states, blended into the Riemann solver where a shock sensor fires, F = F_KEEP + phi (F_Riemann - F_KEEP). For large-eddy simulation: the central flux adds no dissipation, so the SGS model does the work (see [integrals] budget). phi is the larger of the face's two cells': 1 where the Ducros sensor restricted to compressions, (div u)^2 / ((div u)^2 + |omega|^2) with div u < 0, exceeds sensor_threshold, else upwind_floor. Boundary faces other than walls and symmetry planes use the Riemann solver. Species stay upwinded with the blended mass flux. Contacts and expansions are central: on Sod's problem the density error is about 1.8 times the Riemann solver's, with a 0.1% overshoot at the contact |
[numerics.hybrid]¶
| Key | Description |
|---|---|
sensor_threshold |
Ducros sensor above which a cell compressing the flow is a shock, default 0.65 (1 disables the Riemann solver) |
upwind_floor |
Upwind fraction of the other cells, default 0; a small value (e.g. 0.05) damps grid-scale noise on very irregular meshes, at the cost of numerical dissipation the budget then reports |
[numerics.face_reconstruction]¶
| Key | Description |
|---|---|
type |
FO (first order; the default, also without this table), MUSCL or TENO |
limiter |
(MUSCL) venkatakrishnan (default), barth_jespersen or none |
venkatakrishnan_K |
(MUSCL) Venkatakrishnan threshold constant, default 5 |
order |
(TENO) Order of accuracy, 3 to 6, default 5. In 3D, faces use Dunavant (triangles) or Gauss (quadrilaterals) rules exact to this order, capped at degree 5 on triangles |
stencil_factor |
(TENO) Minimum large-stencil size as a multiple of the number of polynomial coefficients, default 2; a stencil grows past it until its reconstruction's Lebesgue constant is at most 4 in 3D (10 in 2D; see docs/numerics/teno_e.md). Smaller values (e.g. 1.5) are markedly less dissipative for fine smooth structures (Shu-Osher entropy waves: 50% more amplitude at 200 cells) but less robust at discontinuities. |
small_stencil_size |
(TENO) Cells per sector stencil, default 10 (18 in 3D) |
troubled_threshold |
(TENO) Troubled-cell threshold on the density-jump variance, default 1e-3 |
troubled_upper |
(TENO) Variance at which the adaptive cutoff reaches its largest value (most dissipative), default 1e-2 |
C_T |
(TENO) Fixed TENO cutoff; adaptive (1e-10 to 1e-6) if omitted |
characteristic |
(TENO) Select stencils on characteristic variables, default true |
max_condition |
(TENO) Stencils grow until the least-squares system's condition estimate is below this, default 1e8 |
cache_file |
(TENO) Save the precomputed stencils and matrices here, and reuse them on later runs of the same mesh, boundary assignment and TENO options; anything else is detected and recomputed. Distributed runs write one file per rank, <cache_file>.r<rank>-of-<ranks>, for that rank count and partition, and record the halo depth the stencils need, so a cached run sets up its halo once. Partitions repeat for the same mesh and rank count. Size per cell: about 2.5 / 4 / 6 / 11 KB in 2D and 10 / 18 / 32 KB (hexahedra) or 9 / 13 / 29 / 63 KB (tetrahedra) in 3D for orders 3 / 4 / 5 / 6, e.g. 8.4 GB for 64^3 hexahedra at order 5; reading it takes seconds; the 3D setup takes about 5 s per million hexahedra and 20 s per million tetrahedra on an A100 (order 5), and minutes on CPUs. The cache records whether the device or the host computed it; both give the same tables |
cache_single_precision |
(TENO) Store the pseudo-inverses and smoothness-indicator matrices (3D: the cells' moments, from which the matrices are formed) of cache_file in single precision: about half the size (17 instead of 32 KB per cell for hexahedra at order 5). The run that writes the cache rounds them too, so it and the runs that read the cache agree with each other, but no longer with a run without it, whose results differ at single-precision round-off. Default false |
bound_preserving |
(TENO) Scale troubled-cell polynomials to keep density and pressure within the neighbors' range, default false |
single_precision_tables |
(TENO, 3D, not with gas mixtures) Keep the pseudo-inverses on the device in single precision: about 40% less device memory for 3D TENO5 (25 instead of 40 KB per hexahedron, 31 instead of 51 KB per tetrahedron on an A100, everything included), so about 1.6 times the cells per GPU, and a 3-8% faster step. Results change at single-precision round-off: below 1e-7 of each field's range for smooth flow, but up to 1e-3 (order 3: 7e-3) behind shocks, where the stencil selection of some cells goes the other way (3D blast on hexahedra, 60-80 steps; design notes); the cache, if any, holds the tables in single precision too. Default false |
troubled_capacity |
(TENO) Fraction of the reconstructed cells that the troubled-cell passes take at a time, which sizes their scratch; more troubled cells are done in further rounds, which recompute their central coefficients (same results). Default 0.5 in 3D (1 in 2D) |
curved_mirrors |
(TENO) Also take mirror images across curved wall and symmetry faces (across each face's plane) into the stencils, default false: stencils are one-sided at curved walls, where mirroring is only second-order consistent (curved far fields and inflows keep their mirror images) |
curved_wall_degree |
(TENO) Largest degree of the central polynomials of cells whose stencils reach a curved wall or symmetry face without mirror images, default 3: one-sided fits of degree 4 and 5 grow in time there, so orders 5 and 6 are fourth order at curved walls and of their order elsewhere |
[chemistry]¶
Finite-rate chemistry of gas mixtures (gas = "mixture" with a mechanism
that has reactions). By default each step is Strang split: every owned cell
that needs it is advanced as an adiabatic, constant-volume reactor over
dt / 2, then the flow takes its step, then the reactors take another
dt / 2 (with fuse_half_steps, the second half step is fused with the
next step's first). With coupling = "simpler" (SIMPLER balanced splitting,
Wu, Ma & Ihme 2019) each step
evaluates the flow's right-hand side T(U^n) once, advances every owned
cell over dt under its chemistry plus that constant source, then lets
the flow correct over the second half of the step with T(U) - T(U^n):
steady states of chemistry and transport stay exactly steady at any dt
(see the thermochemistry guide). The integrator
is RODAS, an adaptive Rosenbrock method with the analytical Jacobian, in
double precision in every build.
| Key | Description |
|---|---|
enabled |
false keeps the mixture non-reacting (default true) |
integrator |
rosenbrock (the default and only choice so far) |
coupling |
strang (default) or simpler; simpler does not combine with fuse_half_steps, numerics.double_flux or numerics.convective_flux = "hybrid" (SIMPLER's flow integrator amplifies non-dissipative operators such as the hybrid flux's central part; see the design notes) |
rtol |
Relative tolerance on the mass fractions and T (default 1e-6) |
atol |
Absolute tolerance on the mass fractions (default 1e-10) |
max_steps |
Sub-steps allowed per cell and half step (default 100000); more stop the run |
T_frozen |
No chemistry in cells below this temperature (default 0) |
fuse_half_steps |
true fuses the closing half step of a step with the next step's opening one, except where output, checks, probes, statistics or the end of the run read the state (default false). Faster where cells take few sub-steps, but results then depend on when output is written, and a restart reproduces an uninterrupted run only from a step at which that run also wrote output |
C_reg |
concentration [kmol/m^3] below which reaction orders 0 < n < 1 follow a regularized law (default 1e-12). Larger values (e.g. 1e-10) make trace fuel burning out in hot gas much cheaper to integrate (flame_3d: chemistry 20 to 11.5 ms per step) but change results: after 100 steps of flame_3d, T by up to 0.54 K, Y by up to 3e-5, the integrated heat release by 0.08% |
load_balance |
true moves the integration of cells from ranks with more chemistry work than the mean (sub-steps of their cells' last calls) to ranks with less, in every call where the most loaded rank exceeds the mean by 5%; only the cells' states travel, and results stay bitwise the same (default false). The summary reports the time ranks wait for the slowest rank's chemistry with or without it |
sparse |
true for the sparse LU (static pattern, with the Jacobian's dense rank-one part by Sherman-Morrison), false for the dense one; by default sparse from 30 species when its factors fill at most 60% of the dense matrix (GRI-3.0 and larger) |
lanes |
Vector lanes integrating one cell: 1 for one thread per cell (cells ordered by their last cost), a power of 2 up to 32 for a team per cell on GPUs; default 0, automatic: a warp per cell on GPUs from 16 species (8 warps, 16 from 512 species, for cells whose last call took 16 or more sub-steps), else one thread |
Cells whose mass fractions would change by less than atol / 100 over the
half step at their current rates are skipped. Reaction types: elementary,
three-body, falloff (Lindemann, Troe, SRI), pressure-dependent-Arrhenius
(PLOG) and Chebyshev, with non-integer reactant orders (global
mechanisms such as Westbrook–Dryer's). Orders between 0 and 1 follow the
power law down to a concentration of 1e-12 kmol/m^3 and a quadratic with a
bounded slope below it, so the Jacobian
stays finite where such a reactant runs out. Output variables: HRR (heat release rate,
W/m^3) and CHEM_COST (chemistry sub-steps of the cell in the last step);
restart files also hold CHEM_H, each cell's last sub-step, so restarted
runs repeat the uninterrupted one exactly. The progress rows add the share of
cells advanced in the last half step and the most sub-steps of a cell in the
last step, and the summary the chemistry's share of the wall time.
[radiation]¶
Radiative heat loss of gas mixtures in the optically thin limit (the TNF
workshop model): every cell loses
q = 4 sigma sum_i p_i a_i(T) (T^4 - T_ambient^4) [W/m^3], with p_i the
partial pressures [atm] of the radiating species and a_i their Planck-mean
absorption coefficients (the TNF workshop's fits to RADCAL, 300-2500 K:
H2O and CO2 polynomials in 1000/T, CH4 and CO in T). Each cell emits but
absorbs only the background at T_ambient, so the model holds where the gas
is optically thin (small flames, lean or diluted ones). The loss is a source of
the energy equation in the flow step; it needs no [chemistry].
| Key | Description |
|---|---|
model |
optically_thin (the default and only choice) |
T_ambient |
Background temperature [K] (default 300) |
species |
Radiating species, any of H2O, CO2, CO, CH4; default all four that the mechanism has (listing one it lacks is an error) |
Output variable: QRAD, the loss [W/m^3]. Cantera's flames with
radiation_enabled use the same model with H2O and CO2 only and no
background term: species = ["H2O", "CO2"] and T_ambient = 0 reproduce it.
[[forces]]¶
Write the force of the fluid on a boundary zone to a CSV file
(step, t, Fx_pressure, Fy_pressure, Fx_viscous, Fy_viscous, per unit depth, or per radian for
axisymmetric flows; in
3D step, t, Fx_pressure, Fy_pressure, Fz_pressure, Fx_viscous, Fy_viscous, Fz_viscous).
| Key | Description |
|---|---|
zone |
Boundary zone name |
interval |
Every this many steps, default 1 |
file |
Output file, default forces_<zone>.csv |
[integrals]¶
Write domain integrals to a CSV file (step, t, kinetic_energy, enstrophy,
dilatation_squared, pressure_dilatation, velocity_squared, vorticity_squared,
density_squared, temperature, temperature_squared): the integrals of
rho |u|^2 / 2, rho |omega|^2 / 2, (div u)^2, p div u, |u|^2,
|omega|^2, rho^2, T and T^2 (divided by the volume, the last ones give
the mean squared velocity and vorticity and the density and temperature
variances). With TENO the velocity
gradients are those of the reconstruction polynomials at the cell centroids
(order-consistent: on the Taylor-Green vortex at 64^3 per octant they match
spectral derivatives of the same field to about 1%); otherwise they are the
second-order least-squares gradients of the viscous fluxes, which
underestimate the enstrophy of under-resolved turbulence (by about 15% in
that case). For decaying
turbulence such as the Taylor-Green vortex, the kinetic energy dissipation
rate is -dE/dt and its viscous part 2 mu * enstrophy / rho0.
| Key | Description |
|---|---|
interval |
Every this many steps, default 1 |
file |
Output file, default integrals.csv |
budget |
true adds the kinetic-energy budget (planar runs): ke_rate_convective, ke_rate_viscous and ke_rate_sgs, the rates of change of the resolved kinetic energy sum V rho |u|^2 / 2 caused by the convective, molecular viscous and SGS fluxes of the current state (each sum V (u . R_m - |u|^2 / 2 R_rho) over that part R of the right-hand side), pressure_work, the rate a scheme without numerical dissipation would give (the two-point pressure flux mean(p) n of the cell values on interior faces, so sum over faces mean(p) (u_1 - u_0) . n A, plus the boundary faces' own fluxes), and eps_numerical = pressure_work - ke_rate_convective, the scheme's dissipation of kinetic energy on interior faces (the convective terms of the exact equations change the kinetic energy only by the pressure work and the boundary fluxes). pressure_work is the discrete counterpart of pressure_dilatation; unlike the latter it does not carry the gradients' discretization error, which matters where p div u is large (flames: thermal expansion at atmospheric pressure, several orders above the dissipation). -ke_rate_viscous and -ke_rate_sgs are the molecular and SGS dissipation. Costs one extra right-hand side per row and leaves the solution unchanged. Default false |
[statistics]¶
Running time averages, kept per cell on the device. Every interval steps
once t > t_start, the sample at time t enters with weight t - t_prev
(the time since the previous sample, or since t_start for the first), so the
averages approximate time integrals over (t_start, t] also when the time
step varies. Each cell's averages are its own (no communication), so they are
bitwise the same on any number of ranks, and sampling reads the state without
changing it.
| Key | Description |
|---|---|
fields |
Variables to average: RHO, U_X, U_Y, (3D) U_Z, P, T, H and, for mixtures, Y_<species> |
products |
Pairs "A*B" of those variables (e.g. "U_X*U_X", "U_X*U_Y", "T*T") whose covariance to keep; their means are kept too |
t_start |
Start time, default 0 |
interval |
Every this many steps, default 1 |
reset |
true starts the averages afresh on a restart instead of continuing those of the restart file (default false) |
The averages are output variables for [[write_data]]: MEAN_<A> and
COV_<A>_<B>, the covariance <A'B'> = <AB> - <A><B> (kept directly, by a
weighted Welford update, rather than as <AB>, which loses the fluctuations
to round-off when they are small), e.g. MEAN_U (a vector), COV_U_X_U_Y, or
MEAN_*, COV_*. Restart files carry them and their weights (format version
3), so a restarted run continues the averages bitwise, also on a different
number of ranks; a restart file without them starts them afresh, and one with
only some of them is an error unless reset = true. With
chemistry.fuse_half_steps, sampling steps read the state like output does.
tools/plane_average.py averages them further over homogeneous directions
(e.g. over x and z of a channel, as a function of y).
[[probes]]¶
Point and line probes: the values of the cells holding a set of points, every
interval steps, appended by rank 0 to a CSV file with rows
step, t, point, x, y(, z), <variables> (one per point and step; a restarted run
appends). Each point reads the cell average of the cell containing it (on a
face between cells, the one with the lowest global id, so any number of ranks
picks the same cell), or of the nearest cell centroid if no cell contains it.
Values are written to full precision.
| Key | Description |
|---|---|
name |
Probe name |
variables |
Any of the [statistics] fields |
point |
One point [x, y(, z)], or |
start, end, n_points |
n_points (at least 2) evenly spaced points from start to end |
interval |
Every this many steps, default 1 |
file |
Output file, default probe_<name>.csv |
[source]¶
Optional source terms, added per unit volume.
| Key | Description |
|---|---|
gravity |
[g_x, g_y] ([g_x, g_y, g_z] in 3D); adds rho g to the momentum and rho u . g to the energy equation |
rho, rhou, rhoE |
Expressions in x, y, z, t (rhou has one per component) for the mass, momentum and energy sources |
time_dependent |
Re-evaluate the expressions at every Runge-Kutta stage (host-side, so costly on large meshes); otherwise (the default) they are evaluated once |
mass_flow |
[m_x, m_y] ([m_x, m_y, m_z] in 3D): hold the volume average of rho u along this vector at its magnitude with a uniform body force f per unit volume along it (constant mass flow, e.g. a periodic channel). At every Runge-Kutta stage f cancels the rate of change of that average from all other terms (one global sum) and closes any remaining gap within the time step, so a flow started at the target stays there to rounding. The energy gains the force's work f . u. |
The scheme is not exactly well balanced: hydrostatic states carry small spurious velocities (about 1e-4 of the sound speed on a 32x32 mesh) that vanish at second order under refinement. Wall and symmetry ghost states continue the hydrostatic pressure gradient.
[parallel]¶
Used when Mallard runs on several MPI ranks (mpirun -n N Mallard -i input.toml).
| Key | Description |
|---|---|
partitioner |
multijagged (default: cells split into equal slabs along x, each slab along y, and in 3D along z, with the number of pieces per axis that leaves the least area between the blocks of the mesh's bounding box; a box of cuboid cells gets cuboid parts), hilbert (cells split along a Hilbert curve of their centroids) or graph (dKaMinPar on the cell connectivity, minimizing the faces between ranks; needs a build with Mallard_ENABLE_KAMINPAR). Results are the same bit for bit |
halo_exchange |
nccl (NCCL operations on the GPU's stream: no host synchronization per exchange; default when built with Mallard_ENABLE_NCCL) or mpi (nonblocking MPI; the default otherwise). Results are the same bit for bit |
[output]¶
| Key | Description |
|---|---|
check_interval |
Print a progress row every this many steps (default 1) |
async |
true (default) writes the [[write_data]] files on background threads while the run continues; false writes them before the run goes on. When a file is due, its values are copied out (on several ranks, regrouped where the file needs it) and the run goes on; a writer's next file first waits for its previous one. The files are the same as without async, byte for byte. HDF5 output on several ranks stays synchronous: parallel HDF5 calls MPI, which only the main thread does. The run waits for every file before it ends, also when it stops on an error |
io_threads |
Threads that copy out each snapshot and compress its files (default 1) |
The run's summary reports the size of the files written and the time spent writing them (in the background with async); output in its wall time is what the run waited for.
Each progress row shows the step, time t, time step dt, the fraction of the run done (by
whichever of n_steps, t_stop and t_wall_stop comes first), the time-stepping wall time
per step, the throughput in cell updates per second, the estimated time remaining, the minimum
density and pressure, the maximum Mach number and, with TENO, the percentage of troubled cells.
Files written appear as rows led by their step and time. The run ends with a summary of wall
time (setup, time stepping, diagnostics, output) and average throughput.
Only rank 0 prints, except for errors, which go to stderr from any rank and carry the rank in
parallel runs. Output on a terminal is colored unless NO_COLOR is set (CLICOLOR_FORCE=1
forces color, e.g. under mpirun); logs written to files are plain ASCII.
[[write_data]]¶
| Key | Description |
|---|---|
prefix |
Output path prefix; directories are created as needed |
format |
vtu (with a .pvd series next to it), hdf5 (with XDMF indexes; see below) or restart |
interval / time_interval |
Write every this many steps / this much simulation time (exactly one). With time_interval the time step is shortened to land on each output time. |
variables |
(vtu, hdf5) Any of RHO, RHOU_X, RHOU_Y, (3D) RHOU_Z, RHOE, U_X, U_Y, (3D) U_Z, P, T, H, CFL, the vectors RHOU and U (written with 3 components, zero z in 2D), Q (the Q-criterion: half the squared norm of the rotation rate minus that of the strain rate, with the hoop strain in axisymmetric runs) and VORTICITY (3D: the vector of VORTICITY_X, VORTICITY_Y, VORTICITY_Z; 2D: the scalar dv/dx - du/dy), with the velocity gradients of the [integrals] monitor (TENO reconstruction polynomials, else least squares), with TENO TENO_SIGMA (the troubled-cell indicator; stencil selection is active where it exceeds troubled_threshold), and for mixtures Y_<species>, X_<species> and RHOY_<species> (with navier_stokes also MU, LAMBDA and the diffusion coefficients D_<species>, and with soret the thermal diffusion coefficients DT_<species> [kg/(m s)]; with [chemistry] also HRR, CHEM_COST and the mass production rates OMEGA_<species> [kg/(m^3 s)]; with [radiation] also QRAD [W/m^3]), and P_MAX, the largest pressure of each cell at the end of any step so far (a numerical soot foil of detonation cells; restart files then carry it, so it continues across restarts), and the [statistics] averages MEAN_<A> and COV_<A>_<B>. A trailing * selects every variable with that prefix, e.g. Y_* |
geometry |
(vtu) all (default) for the volume, or a boundary zone name to write that zone's faces with the values of their adjacent cells (e.g. wall pressure) |
compression |
none (default) or zlib, lossless: VTU arrays are compressed as ParaView's vtkZLibDataCompressor reads them (needs Mallard_ENABLE_ZLIB); HDF5 datasets are chunked, byte-shuffled and deflated (HDF5's standard filters, which every HDF5 reader has); restart files become version 5, each variable in byte-shuffled, deflated chunks (Mallard_ENABLE_ZLIB to write and to read them), and restart bitwise like uncompressed ones. Not for boundary-zone output (geometry) |
relative_error |
(vtu, hdf5, with compression = "zlib") Error bound of lossy compression: each cell value is rounded to the fewest mantissa bits that keep it within this relative error of itself (|x' - x| <= relative_error |x|; zeros, subnormals, infinities and NaNs are kept), and the zeroed trailing bits compress well. The mesh stays exact. Restart files are always lossless |
chunk_cells |
(restart, with compression = "zlib") Cells per compressed chunk (default 65536); a rank reading some cells decompresses only the chunks that hold them |
format = "hdf5" (builds with -DMallard_ENABLE_HDF5=ON; several ranks need
parallel HDF5) scales to large runs: every rank writes its part of one file per
snapshot with collective I/O instead of a VTU piece of its own. It writes
PREFIX_mesh.h5, once:nodes/coordinates(n_nodes x dimension),cells/topology, an XDMFMixedtopology (each cell's XDMF type, then its nodes in VTK order: triangle 4, quadrilateral 5, tetrahedron 6, pyramid 7, wedge 8, hexahedron 9) andcells/offsets, where each cell's record starts (n_cells + 1 entries);PREFIX_NNNNNN.h5per snapshot: the attributesstep,timeandmesh(the mesh file's name), andfields/<name>for each variable (n_cells values, or n_cells x 3 for vectors);PREFIX_NNNNNN.xmfper snapshot andPREFIX.xmf, the time series, which ParaView opens (XDMF reader).
With compression = "zlib" the datasets are stored in chunks of 65536 rows.
Row i of every cell array is global cell i, the cell order of the mesh file and
of restart files, so the files do not depend on the number of ranks.
Snapshots are about half the size of VTU pieces (the mesh is not repeated) and
two files instead of one per rank. A shared file pays off on parallel file
systems; on one node's local disk, which serializes writes to a file, VTU
pieces write faster beyond a few ranks (2.1M hexahedra, 16 ranks: 115 ms per
HDF5 snapshot against 72 ms, 1 rank: 140 ms against 1.1 s). VTU output remains
the simpler choice for small runs. tools/mallard_h5.py reads the files.
MallardReactor¶
MallardReactor -i input.toml integrates one adiabatic, constant-volume
reactor with the solver's chemistry kernels (the RODAS Rosenbrock integrator
with the analytical Jacobian, in double precision) and writes its history as
CSV (t, T, p, Y_<species>). It reads [physics] (mechanism,
phase), the optional [chemistry] table and:
| Key | Description |
|---|---|
[reactor] type |
constant_volume (default; the only type so far) |
[reactor] T, p |
Initial temperature and pressure |
[reactor] X or Y |
Initial composition, as in [initialize] |
[reactor] end_time |
Integration time |
[reactor] output_interval |
Time between CSV rows (default end_time / 100); each interval ends like a splitting step: negative mass fractions clipped, mass fractions renormalized, T from the conserved energy |
[reactor] output |
CSV file (default reactor.csv) |
[chemistry] rtol |
Relative tolerance on Y and T (default 1e-6) |
[chemistry] atol |
Absolute tolerance on Y (default 1e-10) |
[chemistry] max_steps |
Sub-steps allowed per output interval (default 100000) |
[chemistry] sparse |
The linear solver, as in the solver's [chemistry] |
[benchmark] |
Instead of the run, a chemistry benchmark: states sampled along this reactor's trajectory, replicated over cells cells and advanced by the solver's chemistry kernels over each splitting step of dt, with results in output (default benchmark.csv); see benchmarks/README.md |
It prints the ignition delay, the time of the maximum of dT/dt, once
dT/dt has fallen below half that maximum by end_time (the runaway is over,
however small the temperature rise of a lean mixture), and otherwise none.
Example: examples/h2_ignition.