Skip to content

UDF: surface reactions

Status: internal only. pipe.py_reaction_surface and py_reaction_multi are written by the mechanism closures, not by user code, and there is no TOML path to supply your own.

Read the chapter overview for the shared contract.

What exists today

The [pipe.catalyst] kind = "mechanism" closure builds these seams from a declarative mechanism file, and the reaction family carries the registered kinds (nh3_scr_kinetics, nh3_ads_des, arrhenius_scr_demo, …). That path is already user-extensible as data — you write a mechanism, not a function.

Why a code path here is the least urgent

Chemistry is where a hand-written callable is most likely to be wrong in a way that survives review, and where the existing declarative surface is richest:

  • the mechanism format covers Arrhenius forms, surface coverage, storage and multi-reaction sets;
  • the stiff integrators (lsoda, bs_jit, numbalsoda) need the rate expression to be differentiable and callable from compiled code — a Python callable per cell would drop the run onto the slowest path available, and py_reaction_surface is already inert under solver = "explicit";
  • rates that return garbage do not fail loudly, they shift a light-off curve by 20 K.

If you need chemistry the mechanism format cannot express, the productive route today is extending the mechanism surface — see closures reference for the reaction family and the kinds already registered.