Skip to content

Creating a new HDF5 nuclear data library for UQ#3911

Draft
Grego01-biot wants to merge 31 commits intoopenmc-dev:developfrom
Grego01-biot:covariance_storage
Draft

Creating a new HDF5 nuclear data library for UQ#3911
Grego01-biot wants to merge 31 commits intoopenmc-dev:developfrom
Grego01-biot:covariance_storage

Conversation

@Grego01-biot
Copy link
Copy Markdown
Contributor

@Grego01-biot Grego01-biot commented Apr 1, 2026

Description

The goal of this PR is to create a new HDF5 nuclear data library with covariance data stored in that would live on the OpenMC nuclear data libraries page. This is only the HDF5 data storage part with no modifications to the C++ source code. The final goal would be to have the capability to perform on-the-fly cross section sampling using the stored data in HDF5 format. Another draft PR will be added shortly to openmc-dev/data repository in order to have the capability to generate the entire nuclear data library with MF=33 evaluations.

Python API addition

In order to do so, two new Python files are created and added to openmc/data:

  • mf33_njoy.py is a minimal driver that runs ERRORR module from NJOY to produce multigroup relative covariance matrices from an ENDF-6 evaluation. The user provides an explicit energy grid (group boundaries in eV) and optionally a weight spectrum used to produce multi-group cross sections. The output is the raw ERRORR tape33 text.

  • xs_covariance_njoy.py is where the data model, ENDF text parser, covariance factorization. The key class is NeutronXSCovariances, which holds parsed MF=33 covariance matrices and their lower-triangular factors. It provides the capability to read/write to HDF5 files and to write/read MF33 sub-tree inside an existing HDF5 group (used by IncidentNeutron).

  • neutron.py is modified to add an mg_covariance property on IncidentNeutron and write covariance data in export_to_hdf5() under /<nuclide>/covariance/mf33/. It also can read covariance data back in from_hdf5().

The idea is to start by generating multigroup covariance matrices for MF33 using ERRORR module from NJOY, parsing output tape33, storing the covariance data, the temperature, the type of covariance (relative or absolute), the energy grids and the reactions number.

HDF5 storage strategy

It is important to consider two types of covariance data:

  1. For self-covariance blocks (MT = MT), the matrices are symmetric positive semi-definite representing the uncertainty of a single reaction with itself. Due to these assumptions, it is possible to perform a factorization in order to store only a lower triangular matrix L rather than the full matrix. The goal is to reduce the storage size of covariance data in HDF5 files. The factorization can use Cholesky if the matrix is numerically positive definite, falling back to eigendecomposition with thresholding of small/negative eigenvalues followed by a QR pivot to obtain the desired lower-triangular form.
  2. For cross-covariance blocks, they are not symmetric and cannot be factorized easily. The current solution is to store them as raw G*G matrices. Following ENDF convention, only the upper-triangle pair is stored (the transpose gives the complementary block).

It is important to note that the assembly and joint eigendecomposition of the full joint covariance matrix are deferred to OpenMC's preprocessing step, where the user can decide which reactions to jointly sample. The idea is that before transport, the code will assemble the full joint covariance matrix for all requested reactions and store the eigendecomposition in memory for sampling purposes.

HDF5 layout

Covariance data is stored under /nuclide/covariance/mf33/. The group carries metadata as attributes: a format string, a flag indicating relative covariances, the MAT number, and the processing temperature. Two datasets sit at the top level: energy_grid_ev holding the G+1 group boundaries in eV, and mts listing the MT numbers that have covariance data. Below that, two sub-groups organize the actual matrices. The reactions/ sub-group stores raw covariance matrices as (G, G) datasets indexed by {mt}/{mt1} (includes all cross-correlations). The factors/ sub-group stores the lower-triangular factors L as (G, r) datasets, also indexed by {mt}/{mt1}, for self-correlations only.

This capability enables two UQ workflows within OpenMC: sensitivity analysis via the sandwich rule, and direct cross-section sampling via the Total Monte Carlo approach (similar to SANDY). It would also allow users to generate and store their own multigroup covariance data by providing a precomputed flux spectrum as input to NJOY and selecting the desired output energy grid (the lower energy bound cannot be 0 eV due to ERRORR and resolved resonance region treatment irespr = 1). For now, the strategy is to use the SCALE energy group structure with 252 energy groups. The data structure described here is a starting point — feedback on the schema and storage layout is more than welcome!

Here is an example of the code used to generate the new HDF5 file for Fe56.h5 using 1500 energy groups:

from openmc.data.xs_covariance_njoy import NeutronXSCovariances
import numpy as np

ek = np.logspace(np.log10(1e-5), np.log10(20e6), 1501)  # 1500 groups

cov = NeutronXSCovariances.from_endf(
    "n-026_Fe_056.endf",
    ek,
    njoy_exec="/path/to/njoy",
    temperature=293.6,
)

# Standalone file
cov.to_hdf5("Fe56_covariance.h5")

# Or embed in an existing OpenMC HDF5
import h5py
with h5py.File("Fe56.h5", "r+") as f:
    cov_root = f["Fe56"].require_group("covariance")
    cov.write_mf33_group(cov_root)

It is important to note that the code needs modularity to account for the tolerance used in NJOY, the dilution cross section used for the multigroup covariance generation and the combination or not of MF32 and MF33. For this PR, MF=31, MF=34 and MF=35 are not considered for storage in the HDF5.

Fixes # (issue)

Checklist

  • I have performed a self-review of my own code
  • I have run clang-format (version 18) on any C++ source files (if applicable)
  • I have followed the style guidelines for Python source files (if applicable)
  • I have made corresponding changes to the documentation (if applicable)
  • I have added tests that prove my fix is effective or that my feature works (if applicable)

Grego01 and others added 29 commits March 4, 2026 15:21
Grego01 added 2 commits April 15, 2026 18:31
…rrelations and addition of diagnostics before storing the matrices
…d adding tests to check the safeguards for self-covariance matrices
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.

1 participant