mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-24 12:05:32 -04:00
365 lines
12 KiB
Python
365 lines
12 KiB
Python
#!/usr/bin/env python
|
|
|
|
from collections import Mapping, Callable
|
|
import os
|
|
|
|
import numpy as np
|
|
import pandas as pd
|
|
import pytest
|
|
import openmc.data
|
|
|
|
|
|
_TEMPERATURES = [300., 600., 900.]
|
|
_ENDF_DATA = os.environ['OPENMC_ENDF_DATA']
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def pu239():
|
|
"""Pu239 HDF5 data."""
|
|
directory = os.path.dirname(os.environ['OPENMC_CROSS_SECTIONS'])
|
|
filename = os.path.join(directory, 'Pu239.h5')
|
|
return openmc.data.IncidentNeutron.from_hdf5(filename)
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def xe135():
|
|
"""Xe135 ENDF data (contains SLBW resonance range)"""
|
|
filename = os.path.join(_ENDF_DATA, 'neutrons', 'n-054_Xe_135.endf')
|
|
return openmc.data.IncidentNeutron.from_endf(filename)
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def sm150():
|
|
"""Sm150 ENDF data (contains MLBW resonance range)"""
|
|
filename = os.path.join(_ENDF_DATA, 'neutrons', 'n-062_Sm_150.endf')
|
|
return openmc.data.IncidentNeutron.from_endf(filename)
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def gd154():
|
|
"""Gd154 ENDF data (contains Reich Moore resonance range)"""
|
|
filename = os.path.join(_ENDF_DATA, 'neutrons', 'n-064_Gd_154.endf')
|
|
return openmc.data.IncidentNeutron.from_endf(filename)
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def cl35():
|
|
"""Cl35 ENDF data (contains RML resonance range)"""
|
|
filename = os.path.join(_ENDF_DATA, 'neutrons', 'n-017_Cl_035.endf')
|
|
return openmc.data.IncidentNeutron.from_endf(filename)
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def am241():
|
|
"""Am241 ENDF data (contains Madland-Nix fission energy distribution)."""
|
|
filename = os.path.join(_ENDF_DATA, 'neutrons', 'n-095_Am_241.endf')
|
|
return openmc.data.IncidentNeutron.from_endf(filename)
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def u233():
|
|
"""U233 ENDF data (contains Watt fission energy distribution)."""
|
|
filename = os.path.join(_ENDF_DATA, 'neutrons', 'n-092_U_233.endf')
|
|
return openmc.data.IncidentNeutron.from_endf(filename)
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def u236():
|
|
"""U236 ENDF data (contains Watt fission energy distribution)."""
|
|
filename = os.path.join(_ENDF_DATA, 'neutrons', 'n-092_U_236.endf')
|
|
return openmc.data.IncidentNeutron.from_endf(filename)
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def na22():
|
|
"""Na22 ENDF data (contains evaporation spectrum)."""
|
|
filename = os.path.join(_ENDF_DATA, 'neutrons', 'n-011_Na_022.endf')
|
|
return openmc.data.IncidentNeutron.from_endf(filename)
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def be9():
|
|
"""Be9 ENDF data (contains laboratory angle-energy distribution)."""
|
|
filename = os.path.join(_ENDF_DATA, 'neutrons', 'n-004_Be_009.endf')
|
|
return openmc.data.IncidentNeutron.from_endf(filename)
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def h2():
|
|
endf_file = os.path.join(_ENDF_DATA, 'neutrons', 'n-001_H_002.endf')
|
|
return openmc.data.IncidentNeutron.from_njoy(
|
|
endf_file, temperatures=_TEMPERATURES)
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def am244():
|
|
endf_file = os.path.join(_ENDF_DATA, 'neutrons', 'n-095_Am_244.endf')
|
|
return openmc.data.IncidentNeutron.from_njoy(endf_file)
|
|
|
|
|
|
def test_attributes(pu239):
|
|
assert pu239.name == 'Pu239'
|
|
assert pu239.mass_number == 239
|
|
assert pu239.metastable == 0
|
|
assert pu239.atomic_symbol == 'Pu'
|
|
assert pu239.atomic_weight_ratio == pytest.approx(236.9986)
|
|
|
|
|
|
def test_fission_energy(pu239):
|
|
fer = pu239.fission_energy
|
|
assert isinstance(fer, openmc.data.FissionEnergyRelease)
|
|
components = ['betas', 'delayed_neutrons', 'delayed_photons', 'fragments',
|
|
'neutrinos', 'prompt_neutrons', 'prompt_photons', 'recoverable',
|
|
'total', 'q_prompt', 'q_recoverable', 'q_total']
|
|
for c in components:
|
|
assert isinstance(getattr(fer, c), Callable)
|
|
|
|
|
|
def test_compact_fission_energy(tmpdir):
|
|
files = [os.path.join(_ENDF_DATA, 'neutrons', 'n-090_Th_232.endf'),
|
|
os.path.join(_ENDF_DATA, 'neutrons', 'n-094_Pu_240.endf'),
|
|
os.path.join(_ENDF_DATA, 'neutrons', 'n-094_Pu_241.endf')]
|
|
output = str(tmpdir.join('compact_lib.h5'))
|
|
openmc.data.write_compact_458_library(files, output)
|
|
assert os.path.exists(output)
|
|
|
|
|
|
def test_energy_grid(pu239):
|
|
assert isinstance(pu239.energy, Mapping)
|
|
for temp, grid in pu239.energy.items():
|
|
assert temp.endswith('K')
|
|
assert np.all(np.diff(grid) >= 0.0)
|
|
|
|
|
|
def test_reactions(pu239):
|
|
assert 2 in pu239.reactions
|
|
assert isinstance(pu239.reactions[2], openmc.data.Reaction)
|
|
with pytest.raises(KeyError):
|
|
pu239.reactions[14]
|
|
|
|
|
|
def test_elastic(pu239):
|
|
elastic = pu239.reactions[2]
|
|
assert elastic.center_of_mass
|
|
assert elastic.q_value == 0.0
|
|
assert elastic.mt == 2
|
|
assert '0K' in elastic.xs
|
|
assert '294K' in elastic.xs
|
|
assert len(elastic.products) == 1
|
|
p = elastic.products[0]
|
|
assert isinstance(p, openmc.data.Product)
|
|
assert p.particle == 'neutron'
|
|
assert p.emission_mode == 'prompt'
|
|
assert len(p.distribution) == 1
|
|
d = p.distribution[0]
|
|
assert isinstance(d, openmc.data.UncorrelatedAngleEnergy)
|
|
assert isinstance(d.angle, openmc.data.AngleDistribution)
|
|
assert d.energy is None
|
|
assert p.yield_(0.0) == 1.0
|
|
|
|
|
|
def test_fission(pu239):
|
|
fission = pu239.reactions[18]
|
|
assert not fission.center_of_mass
|
|
assert fission.q_value == pytest.approx(198902000.0)
|
|
assert fission.mt == 18
|
|
assert '294K' in fission.xs
|
|
assert len(fission.products) == 8
|
|
prompt = fission.products[0]
|
|
assert prompt.particle == 'neutron'
|
|
assert prompt.yield_(1.0e-5) == pytest.approx(2.874262)
|
|
delayed = [p for p in fission.products if p.emission_mode == 'delayed']
|
|
assert len(delayed) == 6
|
|
assert all(d.particle == 'neutron' for d in delayed)
|
|
assert sum(d.decay_rate for d in delayed) == pytest.approx(4.037212)
|
|
assert sum(d.yield_(1.0) for d in delayed) == pytest.approx(0.00645)
|
|
photon = fission.products[-1]
|
|
assert photon.particle == 'photon'
|
|
|
|
|
|
def test_derived_products(am244):
|
|
fission = am244.reactions[18]
|
|
total_neutron = fission.derived_products[0]
|
|
assert total_neutron.emission_mode == 'total'
|
|
assert total_neutron.yield_(6e6) == pytest.approx(4.2558)
|
|
|
|
|
|
def test_urr(pu239):
|
|
for T, ptable in pu239.urr.items():
|
|
assert T.endswith('K')
|
|
assert isinstance(ptable, openmc.data.ProbabilityTables)
|
|
ptable = pu239.urr['294K']
|
|
assert ptable.absorption_flag == -1
|
|
assert ptable.energy[0] == pytest.approx(2500.001)
|
|
assert ptable.energy[-1] == pytest.approx(29999.99)
|
|
assert ptable.inelastic_flag == 51
|
|
assert ptable.interpolation == 2
|
|
assert not ptable.multiply_smooth
|
|
assert ptable.table.shape == (70, 6, 20)
|
|
assert ptable.table.shape[0] == ptable.energy.size
|
|
|
|
|
|
def test_get_reaction_components(h2):
|
|
assert h2.get_reaction_components(1) == [2, 16, 102]
|
|
assert h2.get_reaction_components(101) == [102]
|
|
assert h2.get_reaction_components(16) == [16]
|
|
assert h2.get_reaction_components(51) == []
|
|
|
|
|
|
def test_export_to_hdf5(tmpdir, pu239, gd154):
|
|
filename = str(tmpdir.join('pu239.h5'))
|
|
pu239.export_to_hdf5(filename)
|
|
assert os.path.exists(filename)
|
|
with pytest.raises(NotImplementedError):
|
|
gd154.export_to_hdf5('gd154.h5')
|
|
|
|
|
|
def test_slbw(xe135):
|
|
res = xe135.resonances
|
|
assert isinstance(res, openmc.data.Resonances)
|
|
assert len(res.ranges) == 2
|
|
resolved = res.resolved
|
|
assert isinstance(resolved, openmc.data.SingleLevelBreitWigner)
|
|
assert resolved.energy_min == pytest.approx(1e-5)
|
|
assert resolved.energy_max == pytest.approx(190.)
|
|
assert resolved.target_spin == pytest.approx(1.5)
|
|
assert isinstance(resolved.parameters, pd.DataFrame)
|
|
s = resolved.parameters.iloc[0]
|
|
assert s['energy'] == pytest.approx(0.084)
|
|
|
|
xs = resolved.reconstruct([10., 30., 100.])
|
|
assert sorted(xs.keys()) == [2, 18, 102]
|
|
assert np.all(xs[18] == 0.0)
|
|
|
|
|
|
def test_mlbw(sm150):
|
|
resolved = sm150.resonances.resolved
|
|
assert isinstance(resolved, openmc.data.MultiLevelBreitWigner)
|
|
assert resolved.energy_min == pytest.approx(1e-5)
|
|
assert resolved.energy_max == pytest.approx(1570.)
|
|
assert resolved.target_spin == 0.0
|
|
|
|
xs = resolved.reconstruct([10., 100., 1000.])
|
|
assert sorted(xs.keys()) == [2, 18, 102]
|
|
assert np.all(xs[18] == 0.0)
|
|
|
|
|
|
def test_reichmoore(gd154):
|
|
res = gd154.resonances
|
|
assert isinstance(res, openmc.data.Resonances)
|
|
assert len(res.ranges) == 2
|
|
resolved, unresolved = res.ranges
|
|
assert resolved is res.resolved
|
|
assert unresolved is res.unresolved
|
|
assert isinstance(resolved, openmc.data.ReichMoore)
|
|
assert isinstance(unresolved, openmc.data.Unresolved)
|
|
assert resolved.energy_min == pytest.approx(1e-5)
|
|
assert resolved.energy_max == pytest.approx(2760.)
|
|
assert resolved.target_spin == 0.0
|
|
assert resolved.channel_radius[0](1.0) == pytest.approx(0.74)
|
|
assert isinstance(resolved.parameters, pd.DataFrame)
|
|
assert (resolved.parameters['L'] == 0).all()
|
|
assert (resolved.parameters['J'] <= 0.5).all()
|
|
assert (resolved.parameters['fissionWidthA'] == 0.0).all()
|
|
|
|
elastic = gd154.reactions[2].xs['0K']
|
|
assert isinstance(elastic, openmc.data.ResonancesWithBackground)
|
|
assert elastic(0.0253) == pytest.approx(5.7228949796394524)
|
|
|
|
|
|
def test_rml(cl35):
|
|
resolved = cl35.resonances.resolved
|
|
assert isinstance(resolved, openmc.data.RMatrixLimited)
|
|
assert resolved.energy_min == pytest.approx(1e-5)
|
|
assert resolved.energy_max == pytest.approx(1.2e6)
|
|
assert resolved.target_spin == 0.0
|
|
for group in resolved.spin_groups:
|
|
assert isinstance(group, openmc.data.SpinGroup)
|
|
|
|
|
|
def test_madland_nix(am241):
|
|
fission = am241.reactions[18]
|
|
prompt_neutron = fission.products[0]
|
|
dist = prompt_neutron.distribution[0].energy
|
|
assert isinstance(dist, openmc.data.MadlandNix)
|
|
assert dist.efl == pytest.approx(1029979.0)
|
|
assert dist.efh == pytest.approx(546729.7)
|
|
assert isinstance(dist.tm, Callable)
|
|
|
|
|
|
def test_watt(u233):
|
|
fission = u233.reactions[18]
|
|
prompt_neutron = fission.products[0]
|
|
dist = prompt_neutron.distribution[0].energy
|
|
assert isinstance(dist, openmc.data.WattEnergy)
|
|
|
|
|
|
def test_maxwell(u236):
|
|
fission = u236.reactions[18]
|
|
prompt_neutron = fission.products[0]
|
|
dist = prompt_neutron.distribution[0].energy
|
|
assert isinstance(dist, openmc.data.MaxwellEnergy)
|
|
|
|
|
|
def test_evaporation(na22):
|
|
n2n = na22.reactions[16]
|
|
dist = n2n.products[0].distribution[0].energy
|
|
assert isinstance(dist, openmc.data.Evaporation)
|
|
|
|
|
|
def test_laboratory(be9):
|
|
n2n = be9.reactions[16]
|
|
dist = n2n.products[0].distribution[0]
|
|
assert isinstance(dist, openmc.data.LaboratoryAngleEnergy)
|
|
assert list(dist.breakpoints) == [18]
|
|
assert list(dist.interpolation) == [2]
|
|
assert dist.energy[0] == pytest.approx(1748830.)
|
|
assert dist.energy[-1] == pytest.approx(20.e6)
|
|
assert len(dist.energy) == len(dist.energy_out) == len(dist.mu)
|
|
for eout, mu in zip(dist.energy_out, dist.mu):
|
|
assert len(eout) == len(mu)
|
|
assert np.all((-1. <= mu.x) & (mu.x <= 1.))
|
|
|
|
|
|
def test_correlated(tmpdir):
|
|
endf_file = os.path.join(_ENDF_DATA, 'neutrons', 'n-014_Si_030.endf')
|
|
si30 = openmc.data.IncidentNeutron.from_njoy(endf_file, heatr=False)
|
|
|
|
# Convert to HDF5 and read back
|
|
filename = str(tmpdir.join('si30.h5'))
|
|
si30.export_to_hdf5(filename)
|
|
si30_copy = openmc.data.IncidentNeutron.from_hdf5(filename)
|
|
|
|
|
|
def test_nbody(tmpdir, h2):
|
|
# Convert to HDF5 and read back
|
|
filename = str(tmpdir.join('h2.h5'))
|
|
h2.export_to_hdf5(filename)
|
|
h2_copy = openmc.data.IncidentNeutron.from_hdf5(filename)
|
|
|
|
# Compare distributions
|
|
nbody1 = h2[16].products[0].distribution[0]
|
|
nbody2 = h2_copy[16].products[0].distribution[0]
|
|
assert nbody1.total_mass == nbody2.total_mass
|
|
assert nbody1.n_particles == nbody2.n_particles
|
|
assert nbody1.q_value == nbody2.q_value
|
|
|
|
|
|
def test_ace_convert(run_in_tmpdir):
|
|
filename = os.path.join(_ENDF_DATA, 'neutrons', 'n-001_H_001.endf')
|
|
ace_ascii = 'ace_ascii'
|
|
ace_binary = 'ace_binary'
|
|
openmc.data.njoy.make_ace(filename, ace=ace_ascii)
|
|
|
|
# Convert to binary
|
|
openmc.data.ace.ascii_to_binary(ace_ascii, ace_binary)
|
|
|
|
# Make sure conversion worked
|
|
lib_ascii = openmc.data.ace.Library(ace_ascii)
|
|
lib_binary = openmc.data.ace.Library(ace_binary)
|
|
for tab_a, tab_b in zip(lib_ascii.tables, lib_binary.tables):
|
|
assert tab_a.name == tab_b.name
|
|
assert tab_a.atomic_weight_ratio == pytest.approx(tab_b.atomic_weight_ratio)
|
|
assert tab_a.temperature == pytest.approx(tab_b.temperature)
|
|
assert np.all(tab_a.nxs == tab_b.nxs)
|
|
assert np.all(tab_a.jxs == tab_b.jxs)
|