Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
5b4999a
Add heterogeneous reacting surface boundary conditions
Sep 4, 2026
ae12489
Merge branch 'master' into carbon-surface-v1
sbryngelson Sep 4, 2026
26769f1
Fix GPU device linkage for surface thermochemistry
Sep 5, 2026
b4942ca
Fix GPU access to surface molecular weights
Sep 6, 2026
92f0f19
Fix OpenACC surface molecular weights
Sep 7, 2026
e7d2c18
Merge branch 'master' into carbon-surface-v1
sbryngelson Sep 7, 2026
3250eeb
Fix surface chemistry OpenMP target and IBM species weights
Sep 7, 2026
466c95b
Fix OpenMP declare target syntax for surface thermochemistry
Sep 8, 2026
491df6b
Match surface thermochemistry OpenMP directives
Sep 8, 2026
d191a2d
Merge master into carbon-surface-v1
sbryngelson Sep 8, 2026
b5db145
Add 2D heterogeneous reacting surface example
Sep 10, 2026
0661de1
Merge remote-tracking branch 'upstream/master' into carbon-surface-v1
Sep 10, 2026
1b7a48d
Add golden data for reacting surface example
Sep 10, 2026
5ae3743
Merge branch 'master' into carbon-surface-v1
sbryngelson Sep 10, 2026
c135338
Merge branch 'master' into carbon-surface-v1
sbryngelson Sep 11, 2026
486bd70
Merge branch 'master' into carbon-surface-v1
sbryngelson Sep 11, 2026
6b2b60e
Key a chemistry build on its mechanism, not the Cantera phase name
sbryngelson Sep 11, 2026
94ac09d
Give the surface species arrays the same bound as the ones they are c…
sbryngelson Sep 11, 2026
c88f283
Merge branch 'master' into carbon-surface-v1
sbryngelson Sep 12, 2026
5c65e9c
Merge remote-tracking branch 'upstream/master' into HEAD
sbryngelson Sep 13, 2026
b857850
Merge branch 'master' into carbon-surface-v1
sbryngelson Sep 15, 2026
ad6893a
Fix review findings on reacting immersed-boundary surface chemistry (…
sbryngelson Sep 17, 2026
9e759de
Merge branch 'master' into carbon-surface-v1
sbryngelson Sep 17, 2026
3068dab
Merge branch 'master' into carbon-surface-v1
sbryngelson Sep 17, 2026
45c77c0
Shorten the cold-wall reacting-surface test to one step
sbryngelson Sep 18, 2026
722a8a5
Unit-test the surface-mechanism guards in the chemistry toolchain
sbryngelson Sep 18, 2026
78e030b
Move the IB surface constraints to the validator, and lint the AMD sp…
sbryngelson Sep 18, 2026
76cf339
Drop the cold-wall test: its golden is not portable across compilers
sbryngelson Sep 18, 2026
c23572f
Reduce the test suite to a single chemistry mechanism
sbryngelson Sep 19, 2026
f38a1c6
Derive the Chemistry --only label from the case, not from its trace
sbryngelson Sep 19, 2026
2ae44d6
Restore the reacting-surface golden; sandiego's slot pays for it
sbryngelson Sep 19, 2026
151119c
Merge branch 'master' into carbon-surface-v1
sbryngelson Sep 20, 2026
aca9445
Correct the --only test docstring: American spelling, and the example…
sbryngelson Sep 20, 2026
2c232bd
Merge branch 'master' into carbon-surface-v1
sbryngelson Sep 23, 2026
8d077d3
Generate surface chemistry with the MFC thermochem package
sbryngelson Sep 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/documentation/case.md
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,9 @@ This is enabled by adding ``'elliptic_smoothing': "T",`` and ``'elliptic_smoothi
| `airfoil_id` | Integer | Index into `ib_airfoil` array for NACA airfoil geometry patches. |
| `model_id` | Integer | Index into `stl_models` array for STL/OBJ geometry patches. |
| `slip` | Logical | Apply a slip boundary |
| `thermal_bc` | Integer | Thermal boundary-condition selector: 0 = zero-normal-gradient temperature, 1 = prescribed wall temperature, 2 = reacting surface energy balance. |
| `Twall` | Real | Prescribed wall temperature used when `thermal_bc = 1`. |
| `surface_reaction` | Integer | Heterogeneous surface-reaction flag: 0 = disabled, 1 = enabled. |
| `moving_ibm` | Integer | Sets the method used for IB movement. |
| `vel(i)` | Real | Initial velocity of the moving IB in the i-th direction. |
| `angular_vel(i)` | Real | Initial angular velocity of the moving IB in the i-th direction. |
Expand Down Expand Up @@ -413,6 +416,12 @@ Additional details on this specification can be found in [NACA airfoil](https://

- `slip` applies a slip boundary to the surface of the patch if true and a no-slip boundary condition to the surface if false.

- `thermal_bc` selects the thermal immersed-boundary condition. A value of 0 applies a zero-normal-gradient temperature condition, 1 prescribes the wall temperature using `Twall`, and 2 solves the reacting-surface energy balance for the surface temperature. The `thermal_bc = 2` option requires `surface_reaction = 1`. A non-zero `thermal_bc` requires `chemistry = T` and cannot be combined with `inj_species > 0`, since the thermal condition is applied by the chemistry ghost-state reconstruction, which an injecting surface bypasses.

- `Twall` specifies the prescribed surface temperature when `thermal_bc = 1` and must be positive in that case.

- `surface_reaction` enables heterogeneous surface chemistry when set to 1. Surface reactions require `chemistry = T` and cannot be combined with `inj_species > 0`.

- For STL/OBJ geometry (geometry 5 or 12), set `model_id` to index into the `stl_models` array and specify `model_filepath`, `model_scale`, `model_translate`, and `model_threshold` on that entry.

- `moving_ibm` sets the method by which movement will be applied to the immersed boundary. Using 0 will result in no movement. Using 1 will result 1-way coupling where the boundary moves at a constant rate and applied forces to the fluid based upon its own motion. In 1-way coupling, the fluid does not apply forces back onto the IB. Using 2 will result in 2-way coupling, where the boundary pushes on the fluid and the fluid pushes back on the boundary via pressure and viscous forces. If external forces are applied, the boundary will also experience those forces.
Expand Down Expand Up @@ -1246,13 +1255,17 @@ When ``cyl_coord = 'T'`` is set in 2D the following constraints must be met:
| `chem_params%%adap_substeps` | Logical | Per-rank adaptive sub-step count driven by local stiffness |
| `chem_params%%reaction_substeps_max` | Integer | Sub-step ceiling when `adap_substeps` is enabled |
| `cantera_file` | String | Cantera-format mechanism file (e.g., .yaml) |
| `surface_cantera_file` | String | Cantera-format mechanism file for heterogeneous surface chemistry |
| `surface_phase` | String | Cantera interface phase name for heterogeneous surface chemistry |

- `chem_params%%transport_model` specifies the methodology for calculating diffusion coefficients and other transport properties, `1` for mixture-average, `2` for Unity-Lewis
- `chem_params%%reaction_substeps` controls how the reaction source is integrated. With `0` (default) the net production rates are added to the flow right-hand side and advanced by the flow time stepper (fine for hydrogen). With a value `> 0`, the reaction is instead integrated by operator splitting after each flow update: every cell's constant-density, constant-internal-energy reactor is advanced over the timestep with that many sub-steps of an **α-QSS** (quasi-steady-state) integrator — a matrix-free, Jacobian-free predictor–corrector (Mott/CHEMEQ2) that splits the net rate into creation/destruction parts and applies a Padé α-weighting, so it stays stable on stiff mechanisms where an explicit source diverges. This decouples the (often much faster) chemical timescale from the flow timestep and is required for stiff mechanisms — e.g. hydrocarbons such as GRI-Mech methane, which otherwise diverge on the first step
- `chem_params%%adap_substeps` (default `F`) makes each rank choose its α-QSS sub-step count per flow step from the largest chemical stiffness among its own cells: the count sits at `reaction_substeps` (the floor) in inert or burned gas and rises toward `reaction_substeps_max` (the ceiling) only across the reaction front. It uses no MPI collectives. When enabled, `reaction_substeps >= 1` and `reaction_substeps_max >= reaction_substeps` are required

- `cantera_file` specifies the chemical mechanism file. If the file is part of the standard Cantera library, only the filename is required. Otherwise, the file must be located in the same directory as your `case.py` file

- `surface_cantera_file` and `surface_phase` specify the Cantera mechanism file and interface phase used for heterogeneous surface chemistry. These parameters must be specified together when a surface mechanism is used.

MFC generates and compiles the mechanism's Fortran routines itself. Supported mechanism features and the Cantera-only mixing-layer initialization are described in @ref thermochemistry "Thermochemistry implementation".

### 18. Chemistry-Specific Boundary Conditions
Expand Down
9 changes: 9 additions & 0 deletions docs/documentation/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,15 @@ Each of these fails quietly rather than loudly.
carrying both labels at once and also matches nothing. An empty selection then exits
**143**, which reads like an external kill rather than an empty filter. Pass UUIDs when
you want the union of several groups.
- **`Chemistry` is the one label not read off the trace.** Any case with ``chemistry='T'``
answers to it, because it selects a *build* and not just a test: Frontier AMD's GPU lane
compiles its chemistry binaries in a separate SLURM job invoked with `-o Chemistry`
(`.github/workflows/common/build.sh`) and then tests with `--no-build`, so a chemistry
case the filter misses is never compiled there and fails with a missing binary. Examples
are auto-registered as `<dim> -> Example -> <dirname>` and so can never carry the label
by hand. If you add a chemistry case, you get this for free; do not re-add the label to
a trace to compensate, since the UUID is a hash of the trace and renaming orphans the
golden directory.
- **Sibling `define_case_d` calls at the same stack level are never combined.** Two switches
that only matter together therefore get no effective coverage unless one is pushed onto
the stack and the other defined beneath it — `avg_state=1`, for instance, is only read
Expand Down
24 changes: 23 additions & 1 deletion docs/documentation/thermochemistry.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ renders the Fortran template. Neither is a runtime solver dependency.
| `thermochem/expressions.py` | NASA7, reaction-rate, equilibrium and transport expressions |
| `thermochem/fortran.py` | Supported-feature checks, expression formatting and module generation |
| `thermochem/module.f90.mako` | Fortran interface and numerical routines |
| `thermochem/surface.py`, `surface.f90.mako` | Heterogeneous surface-chemistry checks and module |
| `thermochem/fingerprint.py` | Mechanism and generator content identities for build reuse |
| `run/input.py` | Mechanism resolution and generation for each target |

Expand Down Expand Up @@ -47,6 +48,22 @@ can therefore differ in roundoff from the former double-literal expressions.
Troe falloff guards the logarithm at zero reduced pressure, including when a
compiler evaluates both arguments of a Fortran `merge` expression.

# Surface chemistry

Reacting immersed boundaries (`surface_cantera_file`, `surface_phase`) also use
`generate_surface_fortran`, which writes `m_surface_thermochem.f90` for the simulation
target. It shares the gas generator's rate-coefficient and NASA7 expressions, literal
kinds and offload annotations, and calls `m_thermochem` for concentrations and gas
enthalpies. The module provides the gas-species net production rates and the heat
released by the surface reactions; without a surface mechanism both return zero.

The supported model is a bulk solid reacting with gas species: irreversible
(interface-)Arrhenius reactions whose rates depend on gas concentrations, with
explicit orders allowed. Adjacent bulk phases, such as graphite, have unit activity
and enter the reaction enthalpy through their NASA7 thermodynamics at the reference
pressure. Sticking, Blowers-Masel and coverage-dependent rates, reversible surface
reactions, and surface-site species are rejected before emission.

# Mixing-layer initial conditions

The temporal 2D, spatial 2D and temporal 3D reacting mixing-layer examples share
Expand Down Expand Up @@ -81,7 +98,8 @@ After bootstrapping the toolchain, run:

```sh
PYTHONPATH=toolchain build/venv/bin/pytest -q \
toolchain/mfc/test_thermochem.py toolchain/mfc/test_flamelet.py
toolchain/mfc/test_thermochem.py toolchain/mfc/test_flamelet.py \
toolchain/mfc/test_surface_chemistry_codegen.py
./mfc.sh test --no-mpi -j 8 --only Chemistry
```

Expand All @@ -94,5 +112,9 @@ zero-concentration falloff with floating-point exception traps, and compilation
with OpenACC and OpenMP directives. The directive tests
execute on the host; they do not validate GPU offload on accelerator hardware.

The surface tests compile the example carbon mechanism's module and compare gas
production rates and reaction heat with Cantera's interface kinetics, check the
gasified carbon mass balance, and cover each rejected rate law.

Initialization tests check stream limits, normalization, elemental composition,
enthalpy, density and a burning hot profile for both mixing-layer mechanisms.
Loading
Loading