This guide explains how to configure LowMachReact-Hex simulations using the case.nml Fortran namelist file and native mesh input files.
It updates the earlier draft for the current energy/species/Cantera stage. The companion file case_nml_reference.md is the concise option reference. This file is the longer operating guide with recommended modes, examples, validation steps, and common mistakes.
The current solver should be understood as a constant-density low-Mach/incompressible projection solver with optional species and enthalpy transport.
Important current rules:
rho.rho_thermo is diagnostic/future-use only.enable_variable_density = .true. is not supported yet.h as the transported state.h, composition Y, and thermodynamic pressure p0.p0 is currently the uniform operating pressure background_press.qrad exists as the future volumetric source interface.case.nmlThe solver reads named Fortran namelist blocks from the case file. Recommended block order is:
&mesh_input
/
&time_input
/
&fluid_input
/
&solver_input
/
&boundary_input
/
&species_input
/
&energy_input
/
&output_input
/
&profiling_input
/
The order is chosen to match the logical setup sequence: mesh, time, fluid properties, solver controls, boundary conditions, species, energy, output, and profiling.
General Fortran namelist rules:
.true. and .false..!.Example indexed species boundary input:
patch_Y(1,1) = 0.0 ! O2 on patch 1
patch_Y(2,1) = 0.0 ! N2 on patch 1
patch_Y(3,1) = 1.0 ! CO2 on patch 1
mesh_dir points to a directory containing the solver native mesh files.
points.datnpoints
id x y z
...
cells.datncells
id node1 node2 node3 node4 node5 node6 node7 node8 cx cy cz volume
...
faces.datnfaces
id owner neighbor patch nx ny nz area cx cy cz
...
Meaning:
owner: owner cell id.neighbor: neighboring cell id. Boundary faces usually use a boundary/empty neighbor indicator.patch: boundary patch id for boundary faces.nx ny nz: face normal components.area: face area.cx cy cz: face centroid.patches.datnpatches
id name nfaces
face_id_1 face_id_2 ...
...
Patch names in this file must match patch_name in case.nml.
periodic.datOptional file used only for periodic connectivity.
nlinks
face_id pair_face_id neighbor_cell_id
...
The &fluid_input block controls the flow density, flow viscosity, thermodynamic operating pressure, and Cantera transport refresh interval.
&fluid_input
rho = 1.0
nu = 1.0e-2
enable_cantera = .false.
enable_variable_density = .false.
enable_variable_nu = .false.
cantera_mech_file = "gri30.yaml"
background_temp = 300.0
background_press = 101325.0
transport_update_interval = 10
/
rho: constant flow densityrho is the density used by the flow/projection solver and by the constant-density energy equation.
Current behavior:
flow density = params%rho
This is not replaced by Cantera density. The Cantera density field is diagnostic only.
nu: constant kinematic viscositynu is the constant kinematic viscosity used when variable Cantera viscosity is not active.
For fixed-Reynolds-number validation, keep:
enable_variable_nu = .false.
Then the Reynolds number is controlled by:
Re = U_ref L_ref / nu
enable_cantera in fluid_inputThis switch controls the Cantera fluid transport path, mainly viscosity. It is independent of species_input enable_cantera.
Recommended current validation setting:
enable_cantera = .false.
enable_variable_nu = .false.
Turn it on only for a dedicated variable-viscosity validation.
enable_variable_densityThis is a future variable-density low-Mach flag. Current supported value:
enable_variable_density = .false.
Do not enable it yet. Cantera rho_thermo is available for diagnostics, but the pressure projection still uses constant rho.
enable_variable_nuThis controls whether Cantera viscosity may affect the flow viscosity. If .true., it requires:
enable_cantera = .true.
For current non-reacting scalar validation, the most useful setting is often:
&fluid_input
enable_cantera = .false.
enable_variable_nu = .false.
/
&species_input
enable_cantera = .true. ! Cantera D_k only
/
This keeps the flow Reynolds number fixed while allowing species diffusivity to vary with T, Y, and p0.
background_tempFallback temperature for Cantera transport when energy is disabled.
Current behavior:
if energy is enabled: Cantera transport uses energy%T
if energy is disabled: Cantera transport uses background_temp
background_pressUniform thermodynamic pressure used by Cantera.
Current behavior:
p0 = background_press
Cantera uses this pressure for:
h(T,Y,p0)T(h,Y,p0)cp(T,Y,p0)thermal_conductivity(T,Y,p0)rho_thermo(T,Y,p0)D_k(T,Y,p0)Do not confuse this with the hydrodynamic/projection pressure field.
transport_update_intervalControls how often Cantera transport properties are refreshed.
It controls:
mu, if variable viscosity is enabled.D_k, if species Cantera is enabled.It does not control:
h <-> T recovery.cp refresh.thermal_conductivity refresh.Recommended values:
1 debugging and validation
5-20 faster non-reacting development runs
The &energy_input block controls enthalpy/temperature storage, energy transport, constant-property fallback values, and Cantera thermodynamics.
&energy_input
enable_energy = .true.
enable_cantera_thermo = .true.
thermo_update_interval = 1
thermo_default_species = "N2"
initial_T = 300.0
energy_reference_T = 300.0
energy_reference_h = 0.0
energy_cp = 1005.0
energy_lambda = 0.026
/
enable_energyMaster switch for energy transport.
When enabled, the solver stores and advances:
T: temperature [K]h: transported sensible enthalpy [J/kg]qrad: volumetric energy source [W/m^3]cp: heat capacity [J/kg/K]lambda: thermal conductivity [W/m/K]rho_thermo: Cantera diagnostic density [kg/m^3]Current energy discretization:
energy advection: upwind
energy diffusion: central/two-point gradient of T
source: qrad / rho
integration: explicit
Important: even though h is transported, conduction is driven by grad(T).
enable_cantera_thermoWhen .false., the solver uses the constant-cp fallback:
h = h_ref + cp * (T - T_ref)
T = T_ref + (h - h_ref) / cp
lambda = energy_lambda
cp = energy_cp
When .true., the solver uses Cantera thermodynamics:
h_sensible = h_abs(T,Y,p0) - h_abs(T_ref,Y,p0)
T = Cantera_HP_inverse(h_sensible + h_abs(T_ref,Y,p0), Y, p0)
cp = cp(T,Y,p0)
lambda = thermal_conductivity(T,Y,p0)
rho_thermo = rho(T,Y,p0)
Why sensible enthalpy matters:
Cantera absolute enthalpy includes formation/reference contributions. In non-reacting mixing, raw absolute enthalpy can create artificial heat release when composition changes. Using sensible enthalpy relative to the same composition at T_ref removes that artifact.
During the energy step, the solver may use a combined thermo-sync call:
(T, cp, lambda, rho_thermo) = sync(h, Y, p0)
This is logically equivalent to recovering T from h,Y,p0 and then refreshing cp, lambda, and rho_thermo, but avoids a redundant second Cantera pass.
For species-enabled runs, a pre-flux sync is used after species transport because Y may have changed. For species-disabled runs, the pre-flux sync can be skipped after initialization because the previous post-flux sync remains valid.
This is now the accepted convention.
When species transport changes the composition from Y_old to Y_new, preserve transported enthalpy and recover temperature:
h_after_species = h_before_species
T_after_species = T(h_after_species, Y_new, p0)
Do not recompute enthalpy from the old temperature and new composition before energy transport:
Do not use: h = h(T_old, Y_new, p0)
That would preserve temperature instead of the transported energy state and can numerically add or remove sensible enthalpy during passive species mixing.
thermo_update_intervalReserved for future optimization. Current supported value:
thermo_update_interval = 1
Cantera energy thermodynamics must remain logically synchronized every energy step. The implementation may optimize internally with a combined thermo-sync call and conservative cache, but do not set this above 1 until a stale-thermo strategy is explicitly implemented and validated.
thermo_default_speciesDefault species for Cantera thermodynamics when species transport is off.
Example:
thermo_default_species = "N2"
Used when:
enable_cantera_thermo = .true.
enable_species = .false.
Ignored when:
enable_species = .true.
In that case, Cantera thermodynamics use transported species%Y.
Useful examples:
thermo_default_species = "N2"
thermo_default_species = "CO2"
thermo_default_species = "H2O"
Use "H2O" with the letter O, not "H20" with zero.
initial_TInitial gas temperature in Kelvin. Must be positive.
energy_reference_TReference temperature used for sensible enthalpy. Must be positive.
Recommended for simple validation:
initial_T = 300.0
energy_reference_T = 300.0
This makes the initial sensible enthalpy close to zero for the initial composition.
energy_reference_hReference enthalpy for constant-cp mode. Usually:
energy_reference_h = 0.0
energy_cpConstant heat capacity for non-Cantera energy mode. Must be positive.
energy_lambdaConstant thermal conductivity for non-Cantera energy mode. Must be non-negative.
For visible diffusion debugging, you may temporarily use a larger value than air's physical value.
The &species_input block controls passive species transport, fallback diffusivity, Cantera species diffusivity, and future reactions.
&species_input
enable_species = .true.
enable_reactions = .false.
enable_cantera = .true.
nspecies = 3
species_name = "O2", "N2", "CO2"
initial_Y = 0.0, 1.0, 0.0
species_diffusivity = 2.0e-5, 2.0e-5, 2.0e-5
/
enable_speciesMaster switch for species transport.
enable_reactionsFuture reaction chemistry switch. Current validation setting:
enable_reactions = .false.
Do not turn reactions on until passive species, passive energy, and Cantera thermo have been validated.
enable_cantera in species_inputThis controls Cantera species diffusivity D_k.
When .false.:
D_k = species_diffusivity(k)
When .true.:
D_k = Cantera mixture-averaged diffusivity D_k(T,Y,p0)
The temperature source is:
energy enabled: energy%T
energy disabled: background_temp
nspeciesNumber of transported species. Must be non-negative and within the compiled max_species limit.
species_nameTransported species names. These must match species in the Cantera mechanism whenever Cantera species transport or Cantera thermodynamics with transported species is enabled.
Example:
species_name = "O2", "N2", "CO2"
initial_YInitial domain mass fractions.
Examples:
initial_Y = 0.0, 1.0, 0.0 ! pure N2 for O2,N2,CO2 list
initial_Y = 0.0, 0.0, 1.0 ! pure CO2 for O2,N2,CO2 list
species_diffusivityFallback constant diffusivity values [m^2/s]. Used when species_input enable_cantera = .false..
Boundary configuration links the physical boundary names in patches.dat to flow, pressure, species, and temperature conditions.
Example:
&boundary_input
n_patches = 5
patch_name = "inlet", "outlet", "wall", "zmin", "zmax"
patch_type = "dirichlet", "neumann", "wall", "symmetric", "symmetric"
patch_velocity_type = "fixed_value", "zero_gradient", "no_slip", "symmetric", "symmetric"
patch_pressure_type = "zero_gradient", "zero_gradient", "zero_gradient", "zero_gradient", "zero_gradient"
patch_temperature_type = "fixed_value", "zero_gradient", "zero_gradient", "zero_gradient", "zero_gradient"
patch_species_type = "fixed_value", "zero_gradient", "zero_gradient", "zero_gradient", "zero_gradient"
patch_u = 1.0, 0.0, 0.0, 0.0, 0.0
patch_v = 0.0, 0.0, 0.0, 0.0, 0.0
patch_w = 0.0, 0.0, 0.0, 0.0, 0.0
patch_p = 0.0, 0.0, 0.0, 0.0, 0.0
patch_dpdn = 0.0, 0.0, 0.0, 0.0, 0.0
patch_T = 400.0, 300.0, 300.0, 300.0, 300.0
patch_Y(1,1) = 0.0
patch_Y(2,1) = 0.0
patch_Y(3,1) = 1.0
/
The parser recognizes these aliases:
| Physical meaning | Accepted names |
|---|---|
| Wall | "wall", "no_slip", "moving_wall" |
| Symmetry/slip | "symmetry", "symmetric", "slip" |
| Periodic | "periodic" |
| Fixed value | "dirichlet", "fixed_value" |
| Zero gradient | "neumann", "zero_gradient" |
Use fixed pressure only where needed to anchor the pressure field. Otherwise use zero-gradient for typical outlets/walls, depending on the case design.
Use:
patch_temperature_type = "fixed_value"
patch_T = ...
for fixed-temperature inlets or hot/cold walls.
If a patch has:
patch_temperature_type = "zero_gradient"
then patch_T is not used as a fixed value on that patch.
Use:
patch_species_type = "fixed_value"
patch_Y(k,patch) = ...
for species inlets.
Mass fractions should sum to about 1 on fixed-value species patches.
For Cantera thermo plus transported species, a fixed-temperature species inlet should be interpreted as:
T_b = patch_T(patch)
Y_b = patch_Y(:,patch)
h_b = h(T_b,Y_b,p0)
This is important for hot/cold fuel/oxidizer inlets. It avoids evaluating boundary enthalpy with interior composition or a default bath gas.
&output_input
output_dir = "cases/rectangle_2D/output"
write_vtu = .true.
write_diagnostics = .true.
/
output_dirDirectory for generated output files.
Before rerunning after changing output arrays, remove old output:
rm -rf cases/rectangle_2D/output
write_vtuControls VTU/PVTU/PVD visualization output.
write_diagnosticsControls CSV diagnostics. Current diagnostic files may include:
diagnostics.csvenergy_diagnostics.csv&profiling_input
enable_profiling = .true.
nested_profiling = .true.
/
enable_profilingEnable MPI-aware profiling.
nested_profilingShow a nested call tree in the terminal profiling report.
Current profiling region names include:
Transport_Update
Projection_Step
Species_Transport
Energy_Transport
Diagnostics_Write_Flow
Diagnostics_Write_Energy
Output_Write_VTU
For Cantera thermo energy runs, nested energy children may include:
Energy_Cantera_PreSync
Energy_PreFlux_Exchange
Energy_Flux_Update
Energy_Cantera_PostSync
Energy_Final_Exchange
The profiler reports inclusive wall time. Flat rows are not additive when nested timers are enabled.
Use this to verify that energy/species additions did not change old flow behavior.
&fluid_input
rho = 1.0
nu = 1.0e-2
enable_cantera = .false.
enable_variable_density = .false.
enable_variable_nu = .false.
cantera_mech_file = "gri30.yaml"
background_temp = 300.0
background_press = 101325.0
transport_update_interval = 10
/
&species_input
enable_species = .false.
enable_reactions = .false.
enable_cantera = .false.
nspecies = 0
/
&energy_input
enable_energy = .false.
enable_cantera_thermo = .false.
thermo_update_interval = 1
thermo_default_species = "N2"
initial_T = 300.0
energy_reference_T = 300.0
energy_reference_h = 0.0
energy_cp = 1005.0
energy_lambda = 0.026
/
Expected result:
Use this to validate energy numerics without Cantera complexity.
&energy_input
enable_energy = .true.
enable_cantera_thermo = .false.
thermo_update_interval = 1
thermo_default_species = "N2"
initial_T = 300.0
energy_reference_T = 300.0
energy_reference_h = 0.0
energy_cp = 1005.0
energy_lambda = 0.026
/
Expected result:
qrad remains zero unless a source is prescribed later.Use this for Stage 2A thermo smoke tests.
&species_input
enable_species = .false.
enable_reactions = .false.
enable_cantera = .false.
nspecies = 0
/
&energy_input
enable_energy = .true.
enable_cantera_thermo = .true.
thermo_update_interval = 1
thermo_default_species = "N2"
initial_T = 300.0
energy_reference_T = 300.0
energy_reference_h = 0.0
energy_cp = 1005.0
energy_lambda = 0.026
/
Change thermo_default_species from "N2" to "CO2" to verify that cp, thermal_conductivity, rho_thermo, and thermal diffusivity respond to the selected gas.
Use this for Stage 2B non-reacting species/energy coupling.
&species_input
enable_species = .true.
enable_reactions = .false.
enable_cantera = .false.
nspecies = 3
species_name = "O2", "N2", "CO2"
initial_Y = 0.0, 1.0, 0.0
species_diffusivity = 2.0e-5, 2.0e-5, 2.0e-5
/
&energy_input
enable_energy = .true.
enable_cantera_thermo = .true.
thermo_update_interval = 1
thermo_default_species = "N2"
initial_T = 300.0
energy_reference_T = 300.0
energy_reference_h = 0.0
energy_cp = 1005.0
energy_lambda = 0.026
/
In this mode:
thermo_default_species is ignored
Cantera thermo uses transported species%Y
h is preserved through species changes
T is recovered from h,Y,p0
Use this to test variable D_k while keeping the flow Reynolds number fixed.
&fluid_input
rho = 1.0
nu = 1.0e-2
enable_cantera = .false.
enable_variable_density = .false.
enable_variable_nu = .false.
cantera_mech_file = "gri30.yaml"
background_temp = 300.0
background_press = 101325.0
transport_update_interval = 10
/
&species_input
enable_species = .true.
enable_reactions = .false.
enable_cantera = .true.
nspecies = 3
species_name = "O2", "N2", "CO2"
initial_Y = 0.0, 1.0, 0.0
species_diffusivity = 2.0e-5, 2.0e-5, 2.0e-5
/
Expected result:
D_k = Cantera D_k(T,Y,p0)
nu = constant
rho = constant
Re = fixed
Use this only after simpler tests pass.
Recommended rules:
enable_species = .true.enable_reactions = .false.enable_energy = .true.enable_cantera_thermo = .true.enable_variable_density = .false.enable_variable_nu = .false. initiallypatch_T and patch_YExpected result:
sum_Y remains close to 1.Depending on enabled physics, ParaView may show the following arrays.
velocitypressurepressure is hydrodynamic/projection pressure, not thermodynamic pressure.
temperatureenthalpyqradcpthermal_conductivityrho_thermothermal_diffusivitythermo_pressureMeanings:
| Field | Meaning |
|---|---|
temperature |
Active gas temperature [K]. |
enthalpy |
Transported sensible enthalpy [J/kg]. |
qrad |
Volumetric radiation/source term [W/m^3]. Positive adds energy to gas. |
cp |
Constant or Cantera heat capacity [J/kg/K]. |
thermal_conductivity |
Constant or Cantera conductivity [W/m/K]. |
rho_thermo |
Cantera diagnostic density [kg/m^3]. Not used in projection. |
thermal_diffusivity |
thermal_conductivity / (rho_flow * cp). |
thermo_pressure |
Uniform background_press. |
Examples:
Y_O2Y_N2Y_CO2sum_YD_O2D_N2D_CO2D_<species> is the diffusivity used by species transport.
If arrays are missing in ParaView after adding new output fields, remove old output and rerun:
rm -rf cases/rectangle_2D/output
make rectangle_2D-release NP=8
Then inspect the output metadata:
grep -R "thermal_diffusivity|thermo_pressure\|D_" cases/rectangle_2D/output
The solver should print a mode summary similar to:
Flow density mode: constant rho = ... kg/m^3
Flow viscosity mode: constant nu = ... m^2/s
Cantera rho_thermo: diagnostic only, not used by projection
Cantera transport update interval: N step(s) [mu/D_k only]
Cantera transport temperature source: energy%T
Cantera thermo update interval: every energy step
Cantera thermo sync: combined T/cp/lambda/rho_thermo from h,Y,p0
Cantera thermodynamic pressure p0: ... Pa
Use this block to verify that the active runtime mode matches the intended validation mode.
Run an existing flow-only or flow/species case with:
enable_energy = .false.
Expected:
Use:
enable_energy = .true.
enable_cantera_thermo = .false.
Expected:
temperature is initialized to initial_T.enthalpy follows constant-cp formula.qrad = 0.Use zero velocity and fixed hot/cold temperature boundaries.
Expected:
Use:
enable_cantera_thermo = .true.
enable_species = .false.
Expected:
h(T) followed by T(h) recovers the original temperature.thermo_default_species changes thermodynamic properties.Use:
enable_species = .true.
enable_reactions = .false.
enable_cantera_thermo = .true.
Expected:
Use species Cantera only:
&fluid_input
enable_cantera = .false.
enable_variable_nu = .false.
/
&species_input
enable_cantera = .true.
/
Expected:
D_k varies with T, Y, and p0.Use opposed inlets, species boundary compositions, fixed inlet temperatures, and reactions off.
Compare:
Expected:
qrad tests, futureBefore external radiation physics, test prescribed qrad patterns:
Expected:
qrad heats the gas.qrad cools the gas.qrad.Do not use:
enable_variable_density = .true.
Current solver does not implement variable-density projection. Use rho_thermo only as a diagnostic field.
Avoid starting with:
fluid_input enable_cantera = .true.
species_input enable_cantera = .true.
enable_cantera_thermo = .true.
enable_variable_nu = .true.
Instead, validate one feature at a time.
enable_cantera switchesThere are two separate blocks:
&fluid_input
enable_cantera = ... ! flow viscosity path
/
&species_input
enable_cantera = ... ! species diffusivity path
/
Use the species switch for Cantera D_k. Use the fluid switch only when testing Cantera viscosity.
Current thermodynamic pressure is:
background_press = 101325.0
The pressure field written to output is projection pressure, not Cantera thermodynamic pressure.
Setting patch_T alone is not enough. You also need:
patch_temperature_type = "fixed_value"
for that patch.
For fixed species inlets, check:
sum_k patch_Y(k,patch) ~= 1
This is especially important for Cantera thermo and species diffusivity.
For fixed-temperature species inlets, the intended rule is:
h_b = h(T_b,Y_b,p0)
not:
h_b = h(T_b,Y_interior,p0)
The accepted Option A convention is:
preserve h
recover T from h,Y_new,p0
Do not preserve old temperature by recomputing h(T_old,Y_new,p0).
The current flow solver remains constant-density. Exact agreement with variable-density 1D Cantera counterflow is not expected yet.
Remove output when array structure changes:
rm -rf cases/<case>/output
Then rerun the case.
Recommended files:
docs/case_nml_reference.md
docs/input_configuration_guide.md
docs/energy_thermo_conventions.md
docs/enthalpy_species_coupling_convention.md
docs/validation_ladder.md
This file can serve as docs/input_configuration_guide.md. The compact companion file can serve as docs/case_nml_reference.md.