Skip to content

Store energy-dependent isomeric production data verbatim in depletion chains - #122

Open
jon-proximafusion wants to merge 4 commits into
developfrom
isomeric-chain-data
Open

Store energy-dependent isomeric production data verbatim in depletion chains#122
jon-proximafusion wants to merge 4 commits into
developfrom
isomeric-chain-data

Conversation

@jon-proximafusion

Copy link
Copy Markdown
Collaborator

Implements the chain-file side of #121: depletion chain files can now carry the evaluations' energy-dependent isomeric production data verbatim, so no side files are needed to know how a transmutation reaction splits between ground and metastable states.

What is stored

For each reaction target, an optional <isomeric_production> child element of <reaction> holding the ENDF MF=9 yield functions and MF=10 partial cross sections exactly as evaluated (original grids, values, and multi-region interpolation), together with the final-state level number, excitation energy, QM/QI, and the source library recorded in the evaluation header. No renormalization, thinning, or ratio pre-computation is performed; consumers fold the data with whatever spectrum they have. Old readers parse only the <reaction> attributes and ignore the child elements, and scalar branching ratios are unchanged by default (ground 1.0, metastables 0.0), so existing workflows including add_branching_ratios behave exactly as before.

Changes

  • openmc/deplete/nuclide.py: ProductionTable and IsomericProduction dataclasses, a Nuclide.isomeric_production mapping keyed by (reaction type, target), XML round trip, and validation of the stored data (physical ranges, orphan entries, pointwise MF=9 sum checks). Also fixes a latent NameError in Nuclide.validate for nuclides with no decay modes and inconsistent reaction sums.
  • openmc/deplete/_isomeric.py (new): MF=8/9/10 parsing from raw section text using the endf-python record readers, level-to-isomer assignment by excitation-energy matching against decay data (with positional pairing as fallback and fold-to-ground for unmappable levels, never naming targets from the LFS level index), scalar ratio collapse modes, and a mapping report.
  • openmc/deplete/chain.py: Chain.from_endf gains isomeric_branching, branching_files (extra ENDF evaluations consulted where the primary neutron file has no MF=8/9/10 data, e.g. TENDL), scalar_branching, elis_rtol, and isomer_mapping_log arguments; reduce carries the data for retained targets; set_branch_ratios preserves attached data through scalar rewrites (with a preserve_isomeric_data safeguard); new get_isomeric_production accessor.
  • Docs: chain XML format specification and Python API entries.

Verification

  • About 40 new unit tests, including round-trip fixtures built from the verbatim ENDF/B-VIII.1 Am241 and Nb93 section text.
  • Integration tests on the real ENDF/B-VIII.1 files reproduce the Am241 thermal capture split of 0.90 to ground and 0.10 to Am242_m1, with the metastable correctly mapped from level LFS=2 by excitation-energy matching (the issue that affected Adding isomeric branching to chain openmc-dev/openmc#3885).
  • A full ENDF-B/VIII.1 + TENDL-2025 chain was built and round-tripped with this branch (numbers posted on Store energy-dependent isomeric branching data (MF=8/9/10) verbatim in depletion chain files #121: 31.7 MB vs the 27.7 MB baseline, 3,193 reaction-target pairs with data on 408 parents, built in 13 s) and loads and validates in unmodified upstream OpenMC 0.15.3.
  • The branch was adversarially reviewed (four-dimension review with verification); confirmed findings, including a thermal-group dropping bug in the multigroup scalar collapse and a positional-mapping split of MF=9/MF=10 record pairs, were fixed in the final commit with regression tests.

shimwell added 4 commits July 6, 2026 11:33
Adds ProductionTable and IsomericProduction dataclasses to
openmc.deplete.nuclide, a Nuclide.isomeric_production mapping keyed by
(reaction type, target), XML round-trip via a new <isomeric_production>
child element of <reaction>, validation of the stored data, format
documentation, and unit tests. Also fixes a latent NameError in
Nuclide.validate where the reaction branch ratio message referenced the
decay branch ratio sum. See #121.
…edits

Chain.reduce deep-copies isomeric production data for retained targets
and warns when data is dropped with an excluded target.
Chain.set_branch_ratios keeps attached data for targets that survive a
rewrite and, controlled by a new preserve_isomeric_data argument,
raises or warns when a rewrite would remove a target carrying data.
Adds a Chain.get_isomeric_production accessor and tests. See #121.
Adds an openmc.deplete._isomeric module that parses ENDF MF=8/9/10
radioactive production sections from raw section text, keeping the
MF=9 yields and MF=10 partial cross sections verbatim, and maps final
state level numbers to metastable targets by matching excitation
energies against decay data (with positional pairing as fallback and
fold-to-ground for unmappable levels).

Chain.from_endf gains isomeric_branching, branching_files (extra
evaluations consulted where the primary neutron file has no data,
e.g. TENDL), scalar_branching ('none' default keeps historical
behavior; 'thermal' and multigroup flux collapse available),
elis_rtol, and isomer_mapping_log arguments. Metastable targets are
emitted as additional reaction entries and every mapping decision can
be written to a report file.

Tested against verbatim ENDF/B-VIII.1 Am241 and Nb93 section fixtures
and an integration test on real decay plus neutron files reproducing
the Am241 thermal capture split of 0.90 to ground and 0.10 to
Am242_m1 from level LFS=2. See #121.
Fixes from an adversarial review of the branch:
- Multigroup scalar collapse now clamps group midpoints into the MF=9
  grid instead of silently zeroing groups outside it, which discarded
  the entire thermal group for group structures starting at 0 eV.
- The positional level-to-isomer fallback now pairs whole levels, not
  individual records, so an MF=9 and MF=10 record of one state can no
  longer be split across two different metastable targets.
- Production data attached to a (type, target) pair appearing on more
  than one reaction element no longer multiplies on XML round trip.
- from_endf validates the scalar_branching tuple shape and flux sum,
  validates elis_rtol, and raises when branching_files,
  scalar_branching, or isomer_mapping_log are passed without
  isomeric_branching=True. Reactions with MF=9/10 data on more than
  one MT use the first (summary) MT and note the skipped ones in the
  mapping report.
- Deduplicated the ground-target inference in set_branch_ratios, added
  ProductionTable and IsomericProduction to the Python API docs, fixed
  source label examples to match evaluation headers, corrected type
  annotations, and added tests for all of the above plus the mapping
  report writer, the replace_missing folding path, and the validate
  message fix. See #121.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants