diff --git a/openmc/data/grid.py b/openmc/data/grid.py index f08bac999..e63919ac2 100644 --- a/openmc/data/grid.py +++ b/openmc/data/grid.py @@ -21,6 +21,9 @@ def linearize(x, f, tolerance=0.001): Tabulated values of the dependent variable """ + # Make sure x is a numpy array + x = np.asarray(x) + # Initialize output arrays x_out = [] y_out = [] diff --git a/tests/unit_tests/test_data_decay.py b/tests/unit_tests/test_data_decay.py new file mode 100644 index 000000000..be8ad7d64 --- /dev/null +++ b/tests/unit_tests/test_data_decay.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python + +from collections import Mapping +import os +from math import log + +import numpy as np +import pytest +from uncertainties import ufloat +import openmc.data + + +_ENDF_DATA = os.environ['OPENMC_ENDF_DATA'] + + +def ufloat_close(a, b): + assert a.nominal_value == pytest.approx(b.nominal_value) + assert a.std_dev == pytest.approx(b.std_dev) + + +@pytest.fixture(scope='module') +def nb90(): + """Nb90 decay data.""" + filename = os.path.join(_ENDF_DATA, 'decay', 'dec-041_Nb_090.endf') + return openmc.data.Decay.from_endf(filename) + + +@pytest.fixture(scope='module') +def u235_yields(): + """U235 fission product yield data.""" + filename = os.path.join(_ENDF_DATA, 'nfy', 'nfy-092_U_235.endf') + return openmc.data.FissionProductYields.from_endf(filename) + + +def test_nb90_halflife(nb90): + ufloat_close(nb90.half_life, ufloat(52560.0, 180.0)) + ufloat_close(nb90.decay_constant, log(2.)/nb90.half_life) + + +def test_nb90_nuclide(nb90): + assert nb90.nuclide['atomic_number'] == 41 + assert nb90.nuclide['mass_number'] == 90 + assert nb90.nuclide['isomeric_state'] == 0 + assert nb90.nuclide['parity'] == 1.0 + assert nb90.nuclide['spin'] == 8.0 + assert not nb90.nuclide['stable'] + assert nb90.nuclide['mass'] == pytest.approx(89.13888) + + +def test_nb90_modes(nb90): + assert len(nb90.modes) == 2 + ec = nb90.modes[0] + assert ec.modes == ['ec/beta+'] + assert ec.parent == 'Nb90' + assert ec.daughter == 'Zr90' + assert 'Nb90 -> Zr90' in str(ec) + ufloat_close(ec.branching_ratio, ufloat(0.0147633, 0.0003386195)) + ufloat_close(ec.energy, ufloat(6111000., 4000.)) + + # Make sure branching ratios sum to 1 + total = sum(m.branching_ratio for m in nb90.modes) + assert total.nominal_value == pytest.approx(1.0) + + +def test_nb90_spectra(nb90): + assert sorted(nb90.spectra.keys()) == ['e-', 'ec/beta+', 'gamma', 'xray'] + + +def test_fpy(u235_yields): + assert u235_yields.nuclide['atomic_number'] == 92 + assert u235_yields.nuclide['mass_number'] == 235 + assert u235_yields.nuclide['isomeric_state'] == 0 + assert u235_yields.nuclide['name'] == 'U235' + assert u235_yields.energies == pytest.approx([0.0253, 500.e3, 1.4e7]) + + assert len(u235_yields.cumulative) == 3 + thermal = u235_yields.cumulative[0] + ufloat_close(thermal['I135'], ufloat(0.0628187, 0.000879461)) + + assert len(u235_yields.independent) == 3 + thermal = u235_yields.independent[0] + ufloat_close(thermal['I135'], ufloat(0.0292737, 0.000819663)) diff --git a/tests/unit_tests/test_data_misc.py b/tests/unit_tests/test_data_misc.py new file mode 100644 index 000000000..aeeb04c0f --- /dev/null +++ b/tests/unit_tests/test_data_misc.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python + +from collections import Mapping +import os + +import numpy as np +import pytest +import openmc.data + + +def test_data_library(tmpdir): + lib = openmc.data.DataLibrary.from_xml() + for f in lib.libraries: + assert sorted(f.keys()) == ['materials', 'path', 'type'] + + f = lib.get_by_material('U235') + assert f['type'] == 'neutron' + assert 'U235' in f['materials'] + + f = lib.get_by_material('c_H_in_H2O') + assert f['type'] == 'thermal' + assert 'c_H_in_H2O' in f['materials'] + + filename = str(tmpdir.join('test.xml')) + lib.export_to_xml(filename) + assert os.path.exists(filename) + + new_lib = openmc.data.DataLibrary() + directory = os.path.dirname(os.environ['OPENMC_CROSS_SECTIONS']) + new_lib.register_file(os.path.join(directory, 'H1.h5')) + assert new_lib.libraries[-1]['type'] == 'neutron' + new_lib.register_file(os.path.join(directory, 'c_Zr_in_ZrH.h5')) + assert new_lib.libraries[-1]['type'] == 'thermal' + + +def test_linearize(): + """Test linearization of a continuous function.""" + x, y = openmc.data.linearize([-1., 1.], lambda x: 1 - x*x) + f = openmc.data.Tabulated1D(x, y) + assert f(-0.5) == pytest.approx(1 - 0.5*0.5, 0.001) + assert f(0.32) == pytest.approx(1 - 0.32*0.32, 0.001) + + +def test_thin(): + """Test thinning of a tabulated function.""" + x = np.linspace(0., 2*np.pi, 1000) + y = np.sin(x) + x_thin, y_thin = openmc.data.thin(x, y) + f = openmc.data.Tabulated1D(x_thin, y_thin) + assert f(1.0) == pytest.approx(np.sin(1.0), 0.001) diff --git a/tests/unit_tests/test_data_neutron.py b/tests/unit_tests/test_data_neutron.py index 4809c5638..502442f5b 100644 --- a/tests/unit_tests/test_data_neutron.py +++ b/tests/unit_tests/test_data_neutron.py @@ -77,6 +77,13 @@ def na22(): 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') @@ -84,6 +91,12 @@ def h2(): 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 @@ -102,6 +115,15 @@ def test_fission_energy(pu239): 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(): @@ -155,6 +177,13 @@ def test_fission(pu239): 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') @@ -275,3 +304,62 @@ 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(tmpdir): + filename = os.path.join(_ENDF_DATA, 'neutrons', 'n-001_H_001.endf') + ace_ascii = str(tmpdir.join('ace_ascii')) + ace_binary = str(tmpdir.join('ace_binary')) + retcode = openmc.data.njoy.make_ace(filename, ace=ace_ascii) + assert retcode == 0 + + # 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)