OpenMC Guide
StatePoint Files in OpenMC
What you'll learn
- Open a statepoint and pull out k-effective with its uncertainty.
- Retrieve a tally by name and convert it to a pandas dataframe.
- Judge whether a result has converged, using relative error and k by generation.
Before you start
Reading a statepoint back
A statepoint (statepoint.<batch>.h5) is the file model.run() writes, holding every tally's mean and standard deviation, k-effective for an eigenvalue run, and enough of the model to make sense of it. Open it and read out what you need — nothing here needs recomputing.
with openmc.StatePoint(statepoint_path) as sp:
keff = sp.keff
print(f"k-effective = {keff.nominal_value:.5f} ± {keff.std_dev:.5f}")
tally = sp.get_tally(name='fuel_flux') # the name must match a tally you defined
mean = tally.mean
rel_err = tally.std_dev / tally.mean
df = tally.get_pandas_dataframe() # full breakdown by filter bin, score, and nuclideTutorial snippet — no separate file in examples repo
get_pandas_dataframe() is the useful form once a tally carries more than one filter or score — it gives you one row per bin with columns for every filter, the score name, the mean, and the standard deviation, instead of the plain arrays that tally.mean returns.
Two independent checks decide whether a result is trustworthy. Relative error — std_dev / mean — falls as one over the square root of active histories, and should be comfortably under a percent or two for anything you plan to report. Separately, sp.k_generation gives k-effective batch by batch; plotted against batch number, it should look like noise scattered around a flat mean once the inactive batches have passed, not a value still drifting in one direction — a persistent trend past that point means the inactive count in Settings was too low.
The pin cell's statepoint
The pin cell's three named tallies — fuel_flux, clad_flux, and water_flux — come back out exactly as they were named going in. This is the same fragment that appears on Example: Pin Cell, which also works through the sanity checks — on k-effective, on the fuel's nu-fission-to-absorption ratio, and on relative error — that decide whether this particular run is one to trust.
with openmc.StatePoint(statepoint_path) as sp:
keff = sp.keff
fuel_flux = sp.get_tally(name='fuel_flux')
clad_flux = sp.get_tally(name='clad_flux')
water_flux = sp.get_tally(name='water_flux')
nu_fission_rate = fuel_flux.get_slice(scores=['nu-fission'])
absorption_rate = fuel_flux.get_slice(scores=['absorption'])Tutorial snippet — no separate file in examples repo
One thing to try
Plot sp.k_generation against batch number, with a vertical line marking the end of the 20 inactive batches. Predict what the two halves of the plot will look like before you run it — the segment before the line is the fission source still settling from its starting guess, and the segment after is what the relative-error check above is actually measuring the noise of.
import matplotlib.pyplot as plt
keff_by_gen = sp.k_generation
batches = range(1, len(keff_by_gen) + 1)
plt.figure()
plt.axvline(20, linestyle='--', color='gray', label='end of inactive batches')
plt.plot(batches, keff_by_gen, 'o-')
plt.xlabel('Batch')
plt.ylabel('k-effective')
plt.legend()
plt.show()Tutorial snippet — no separate file in examples repo
Check yourself
- Open a statepoint and pull out k-effective with its uncertainty?
- Retrieve a tally by name and convert it to a pandas dataframe?
- Judge whether a result has converged, using relative error and k by generation?