Repository navigation
Cantera mechanism I/O and reactor simulation (#65) - #73
Merged
Merged
Conversation
Refs #65. Fills in koopman_graph.datasets.reaction.cantera_io (lazy [cantera] boundary): - load_cantera_mechanism converts a Cantera gas mechanism (default the bundled h2o2.yaml) to a mass-action ReactionSystem at a reference (T, P, X). Reversible reactions split into forward/reverse rows with Cantera's rate constants. Elementary and mass-action three-body reactions are exact ([M] = sum eps_s c_s expanded into one reaction per collider). Falloff and other state-dependent rates are frozen, skipped, or rejected; non-mass-action orders are skipped or rejected. CanteraProvenance lists every frozen/skipped reaction and records the Cantera version, path, SHA-256, reference state, the illustration-only caveat, and the Cantera citation DOI. - simulate_cantera_reactor: const-pressure / const-volume ideal-gas ReactorNet, adiabatic or isothermal. - require_cantera, resolve_mechanism_path, mechanism_sha256. CI test jobs and the release verify job now install [reaction] and [cantera], so the cantera-marked tests run (and cover this module) there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Frozen state-dependent rates with a mass-action third body (e.g. three-body Blowers-Masel) now keep [M] via the per-collider expansion; Cantera's rate constants leave it out. Non-mass-action (+M) third bodies with Arrhenius rates convert exactly with no [M] factor. - Read rate constants with legacy rate-constant mode off (detected with a probe mechanism) and restore the process setting afterwards. - Orders equal to the reactant stoichiometry are mass action and are no longer skipped. - Duplicate reactions get unique reaction names (#index suffix). - Bare mechanism names prefer Cantera's bundled data directories over the working directory; Paths and names with a directory are explicit. - simulate_cantera_reactor rejects non-finite times and records state_dependent=None instead of the out-of-policy "exact". - Share solution loading in _open_solution; evaluate each collider efficiency once. - Tests for explicit/frozen/non-mass-action third bodies, legacy mode, matching orders, duplicate names, cwd shadowing, and infinite times. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lespie' into prop/cantera
Codecov Report❌ Patch coverage is
🚀 New features to boost your workflow:
|
tjkessler
added a commit
that referenced
this pull request
Oct 15, 2026
Carries the reviewed #69-#73 fixes up to #74. Conflict in datasets/reaction/oracles.py resolved by taking #71's hardened version (exact projector linear equilibrium, residual-checked Newton with line-search stall detection, OracleSpectrum.zero_tolerance, one SVD for rank / range / conservation laws) and re-applying #74's additions: - _require_stationary flux check on both Newton return paths, so a clamped one-way boundary stall is still refused; - eigenvalue_timescales as the single timescale implementation, now with an optional absolute zero_tolerance (OracleSpectrum.timescales passes its own; 0 compares exactly) and the round-off default otherwise. test_equilibrium_rejects_one_way_boundary_point accepts either guard's message, since both refuse the stalled point. Committed cards are unchanged (build_reaction_cards.py --check passes). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Base automatically changed from
feature/reaction-random-cstr-gillespie
to
main
October 15, 2026 21:04
tjkessler
added a commit
that referenced
this pull request
Oct 15, 2026
Ubuntu CI failed test_card_oracle_matches_recomputation (Michaelis-Menten, random network), test_cantera_card_oracle_and_provenance, and the card builder --check: oracle['conservation_laws'] drifted. With two or more conservation laws any rotation of an orthonormal basis is valid, and torch.linalg.svd returns a different one under Linux LAPACK than under macOS Accelerate, so the committed cards held a platform-specific basis. The single-law chain card was unaffected. _stoichiometric_basis now canonicalizes the conservation laws: Gram-Schmidt in species order on the columns of the projector P = W^T W, which is basis independent, so every platform gets the same rows (to rounding) with a fixed sign. Cards regenerated; apart from the rotated laws, oracle values move only at rounding level (<= 3e-14). Adds a test that a rotated, sign-flipped basis canonicalizes back to the same rows. Also merges main (#70-#73) into the branch, which GitHub reported as behind. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #65. Sixth PR for the reaction-network datasets. Stacked on #72 (→ #71 → #70 → #69). Merge in order #69 → #70 → #71 → #72 → this one. Each PR retargets to
mainwhen the one below it merges, and CI starts then.Changes
koopman_graph.datasets.reaction.cantera_iois the lazy[cantera]boundary. Importing it doesn't import Cantera.load_cantera_mechanism(name_or_path="h2o2.yaml", *, temperature_k, pressure_pa, mole_fractions, state_dependent="freeze")converts a gas mechanism into a mass-actionReactionSystemat a reference state(T, P, X):forward_rate_constants/reverse_rate_constantsatT. Reverse constants come from thermochemistry and aren't Arrhenius, soarrhenius=None.[M], and[M] = Σ ε_s c_s, so each+Mreaction expands into one reaction per colliders(A + B + s → … + s,k ε_s). Explicit colliders (+ O2) are just the case with a single collider.state_dependent="freeze"uses the effective constant at the reference state, which is exact there and approximate elsewhere."skip"drops them and"error"raises.ordersare always skipped (or raise under"error").CanteraProvenancelists every frozen and skipped equation, and records the Cantera version, resolved path, mechanism SHA-256, reference state, Cantera's "bundled inputs are for illustration only" caveat, and the Cantera 3.2.0 citation DOI. It also has a JSON-safeto_dict.Other functions:
simulate_cantera_reactor(...)runs anIdealGasConstPressureReactororIdealGasReactor, adiabatic or isothermal (energy="off"), and returns concentrations, T, and P at the output times plus provenance. It passesclone=Trueexplicitly, which becomes Cantera's default after 3.2.require_cantera()raises ImportError naming[cantera].resolve_mechanism_pathtakes an explicit path, which needs no Cantera, or searches Cantera's data directories.mechanism_sha256hashes the file.CI: the Ubuntu and macOS test jobs and the release verify job now install
--extra reaction --extra cantera. #66 deferred this untilcantera-marked tests existed. Without it,cantera_io.pywould be mostly uncovered in CI and fail the 90% Codecov patch target. Cantera 3.2.0 has wheels for the whole matrix (CPython 3.10–3.14, manylinux x86_64, macOS arm64), anduv sync --frozenwith the combined extras resolves from the existing lock.Tests
h2o2.yamlSHA-256 equals the value in [Feature]: Mass-action reaction-network datasets (koopman_graph.datasets.reaction) #65 (0efc6c52…c8d4).system.time_derivativeequals Cantera'snet_production_ratesto 1e-12 relative. The system is element-balanced, has 1 frozen reaction (the Troe falloff) and 0 skipped.skip/errorpolicies work. A custom mechanism withorders: {H2: 0.5}has that reaction skipped (or rejected undererror).integrate_stiffon the converted system to 1e-3 of the concentration scale. The adiabatic run heats past 1500 K at constant pressure.sys.modules, every entry point raises the[cantera]hint. Hashing and explicit-path resolution work without it.Verification (macOS arm64, Python 3.13, Cantera 3.2.0)
ruff checkandruff format --checkonsrc/ tests/pass.pytest -n auto -m "not slow and not distributed and not ray" --cov=koopman_graph --cov-fail-under=90: 3480 passed, 26 skipped, 97.27%.cantera_io.pyis at 98%.sphinx-build -W --keep-goingpasses.[cantera]. It will run for the first time when this PR retargets tomain.🤖 Generated with Claude Code