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.
Thermochemistry¶
Gas mixtures carry one mass fraction per species of a mechanism, with thermally perfect thermodynamics, mixture-averaged (or simpler) transport, finite-rate chemistry and optically thin radiation. All of it is in double precision in every build, on CPUs and GPUs.
Gas mixtures¶
[physics]
type = "navier_stokes" # or "euler": no transport
gas = "mixture"
mechanism = "../../mechanisms/h2o2.yaml"
# phase = "ohmech" # default: the file's first phase
transport = "mixture_averaged" # navier_stokes only
[initialize]
type = "constant"
u = [0.0, 0.0]
p = 101325.0
T = 300.0
X = { H2 = 2.0, O2 = 1.0, N2 = 3.76 } # mole fractions, normalized
| Key | Default | Meaning |
|---|---|---|
gas |
"perfect" |
mixture for a thermally perfect mixture; then no gamma, p_ref, T_ref, rho_ref |
mechanism |
required | A Cantera YAML file |
phase |
first phase | Phase of the file to use |
transport |
"mixture_averaged" |
mixture_averaged, unity_lewis or constant_lewis (navier_stokes only) |
lewis |
1 for all | constant_lewis: Lewis numbers by species, e.g. { H2 = 0.3, H = 0.18 } |
soret |
false |
mixture_averaged: thermal diffusion (the Soret effect) |
Mechanisms. mechanisms/ holds H2/O2 (h2o2.yaml, 10 species), GRI-Mech
3.0 (gri30.yaml, 53), two-step propane and methane mechanisms for LES,
helium-air for shock-bubble runs, air to 20,000 K (NASA-9, thermo only) and a
100-species n-dodecane mechanism; its README lists them. Chemkin files convert
with Cantera's ck2yaml. Species thermodynamics may be NASA-7, NASA-9 or
constant-cp; reactions may be elementary, three-body, falloff (Lindemann,
Troe, SRI), pressure-dependent Arrhenius (PLOG) and Chebyshev, with
non-integer reactant orders.
Compositions. Everywhere a state is given ([initialize], upt and
nscbc_inlet boundaries, sponges, MallardReactor), give exactly one of X
(mole fractions) or Y (mass fractions), as a table by species; listed values
are normalized and unlisted species are zero. Analytical initial conditions
and inflows take expressions per species, and balance = "N2" gives one
species the rest (1 - sum) instead of normalizing:
[initialize]
type = "analytical"
Y = { H2 = "x < 0.5 ? 0.028 : 0.0", O2 = "x < 0.5 ? 0.226 : 0.233" }
balance = "N2"
Transport. With navier_stokes, species diffuse along mole-fraction
gradients with a correction velocity (the diffusive mass fluxes sum to zero)
and carry their enthalpy; viscosity and conductivity follow the mixture rules
(Wilke, Mathur), as Cantera's mixture-averaged model.
transport |
Diffusion coefficients | When |
|---|---|---|
mixture_averaged |
Mixture-averaged, from the species' transport data | Default; differential diffusion (lean hydrogen flames) |
unity_lewis |
lambda / (rho cp) for every species |
Comparisons with unity-Lewis theory or DNS |
constant_lewis |
lambda / (rho cp Le_k) |
Simplified chemistry with fitted Lewis numbers |
Walls are no-slip and non-catalytic: no species crosses them, so their
species, Soret and enthalpy diffusion fluxes vanish. wall_adiabatic,
wall_isothermal and wall_heat_flux set the heat flux (see
boundary conditions).
Contacts between different gases¶
The conservative scheme perturbs pressure at the percent level at contacts
between gases of different cp / cv (cold hydrogen in hot air) on coarse
meshes. [numerics] double_flux = true removes those oscillations: pressure
and velocity stay exactly uniform across such contacts, at the price of exact
energy conservation (about 0.2% over a multicomponent shock tube). Use it for
interfaces of very different gases (the shock_bubble_3d example), not for
flames.
Finite-rate chemistry¶
A mixture whose mechanism has reactions reacts when the input has a
[chemistry] table:
[chemistry]
rtol = 1.0e-6
atol = 1.0e-10
# coupling = "simpler" # balanced splitting, for large steps
# T_frozen = 400.0 # no chemistry below 400 K
Each owned cell is advanced as an adiabatic, constant-volume reactor by RODAS,
an adaptive Rosenbrock method with the analytical Jacobian; cells whose
composition would change by less than atol / 100 over the step are skipped.
Chemistry and flow are split:
- Strang (default): half a step of chemistry, a step of flow, another half
step of chemistry. Its splitting error binds before the CFL condition in
detonations: the 1D CJ detonation keeps its induction length within 5% up to
cfl = 0.35. - SIMPLER (
coupling = "simpler", Wu, Ma & Ihme 2019): the chemistry integrates over the whole step with the flow's right-hand side as a constant source, so steady flames stay exactly steady at any step; the detonation's induction length stays within 5% atcfl = 1.0(validation). Not withfuse_half_steps,double_fluxor thehybridflux.
| Key | Default | Meaning |
|---|---|---|
enabled |
true |
false keeps the mixture frozen |
coupling |
"strang" |
strang or simpler |
rtol, atol |
1e-6, 1e-10 | Integrator tolerances (relative on Y and T, absolute on Y) |
max_steps |
100000 | Sub-steps allowed per cell and call; more stop the run |
T_frozen |
0 | No chemistry in cells below this temperature |
fuse_half_steps |
false |
Strang: fuse the closing half step with the next opening one, except where output reads the state (faster; results then depend on output times) |
C_reg |
1e-12 | Concentration [kmol/m^3] below which orders between 0 and 1 are regularized; 1e-10 speeds up trace-fuel burnout at a small cost in accuracy |
load_balance |
false |
MPI: move chemistry work from loaded to idle ranks, bitwise the same results (performance) |
sparse |
automatic | Sparse LU (true) or dense (false); automatic picks sparse from 30 species when it pays (GRI-3.0 and larger) |
lanes |
0 (automatic) | GPU lanes per cell; automatic: a warp per cell from 16 species |
integrator |
"rosenbrock" |
The only choice so far |
Output variables: HRR (heat release rate, W/m^3), OMEGA_<species>
(production rates), CHEM_COST (sub-steps of each cell in the last step).
Restart files carry each cell's last sub-step, so restarts repeat an
uninterrupted run exactly. The progress rows show the share of cells advanced
and the most sub-steps of any cell.
Pitfalls:
- Time step. With Strang splitting, detonations need
cflof about 0.35; flames are insensitive (speed unchanged to 0.001% between 0.2 and 1.0). - Ignition from a cold start needs no special treatment, but
T_frozensaves the work of cold fresh gas in large runs. - Large mechanisms on GPUs are memory-bound: see Performance for cells per second up to 1268 species.
Radiation¶
Optically thin radiative heat loss (the TNF workshop model):
q = 4 sigma sum_i p_i a_i(T) (T^4 - T_ambient^4), with Planck-mean
absorption coefficients of H2O, CO2, CO and CH4. It holds for small, lean or
diluted flames, which emit but barely absorb. It needs no [chemistry] and
outputs QRAD [W/m^3].
| Key | Default | Meaning |
|---|---|---|
model |
"optically_thin" |
The only model |
T_ambient |
300 | Background temperature [K] |
species |
those of H2O, CO2, CO, CH4 in the mechanism | Radiating species |
Cantera's radiation_enabled flames are species = ["H2O", "CO2"] with
T_ambient = 0 (validation).
0D reactors: MallardReactor¶
MallardReactor integrates one adiabatic, constant-volume reactor with the
solver's own chemistry, and writes t, T, p and the mass fractions as
CSV. Use it to check a mechanism and tolerances before a run, or to get an
ignition delay:
# examples/h2_ignition/input.toml
[physics]
gas = "mixture"
mechanism = "../../mechanisms/h2o2.yaml"
[reactor]
T = 1200.0
p = 101325.0
X = { H2 = 2.0, O2 = 1.0, N2 = 3.76 }
end_time = 2.0e-4
output_interval = 1.0e-6
[chemistry]
rtol = 1.0e-6
atol = 1.0e-10
cd examples/h2_ignition
../../build/src/MallardReactor -i input.toml # writes reactor.csv, prints the ignition delay
examples/h2_ignition with MallardReactor: the ignition delay (maximum of
dT/dt) is 44.2 µs, as Cantera's
(validation).
[reactor] key |
Default | Meaning |
|---|---|---|
type |
"constant_volume" |
The only type |
T, p |
required | Initial temperature [K] and pressure [Pa] |
X or Y |
required | Initial composition |
end_time |
required | Integration time [s] |
output_interval |
end_time / 100 |
Time between CSV rows |
output |
"reactor.csv" |
CSV file |
A [benchmark] table turns the run into a chemistry benchmark: states sampled
along the reactor's trajectory, replicated over many cells and advanced by the
solver's chemistry kernels, which prints cells per second (see
benchmarks/README.md; keys cells, samples, dt, repeats,
igniting_fraction, lanes, threads, shared, bin_by_cost, output).
Examples¶
| Example | Shows |
|---|---|
h2_ignition |
MallardReactor |
reactive_shock_tube |
Ignition behind a reflected shock, Strang splitting |
detonation_1d, detonation_2d, detonation_3d |
CJ and cellular detonations, numerical soot foils (P_MAX) |
premixed_flame |
Freely propagating H2/air and CH4/air (GRI-3.0) flames against Cantera |
flame_2d, triple_flame, counterflow_diffusion |
Multidimensional laminar flames, differential diffusion |
flame_vortex, flame_vortex_quenching |
Flame-vortex interaction, with radiation |
autoignition_2d |
Stratified autoignition DNS |
shock_bubble_3d |
Non-reacting mixture, double_flux |
examples/flame_2d: a lean H2/air flame enters through upt (with its
composition) and leaves through p_out, periodic across the channel.
See also¶
- Input reference:
[chemistry],[radiation],MallardReactor - Validation: reacting flow
- Large-eddy simulation: thickened flames and PaSR
- Design notes: finite-rate chemistry