mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 06:05:58 -04:00
Merge pull request #953 from paulromano/test-data
Add unit tests for openmc.data Python package
This commit is contained in:
commit
3236f0de15
16 changed files with 799 additions and 124 deletions
66
.travis.yml
66
.travis.yml
|
|
@ -8,61 +8,39 @@ addons:
|
|||
apt:
|
||||
packages:
|
||||
- gfortran
|
||||
- g++
|
||||
- mpich
|
||||
- libmpich-dev
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/nndc_hdf5
|
||||
- $HOME/endf-b-vii.1
|
||||
env:
|
||||
- OPENMC_CONFIG="check_source"
|
||||
- OPENMC_CONFIG="^hdf5-debug$"
|
||||
- OPENMC_CONFIG="^omp-hdf5-debug$"
|
||||
- OPENMC_CONFIG="^mpi-hdf5-debug$"
|
||||
- OPENMC_CONFIG="^phdf5-debug$"
|
||||
|
||||
# We aren't testing the check_source script so just run it with Python 3.
|
||||
matrix:
|
||||
exclude:
|
||||
- python: "2.7"
|
||||
env: OPENMC_CONFIG="check_source"
|
||||
global:
|
||||
- FC=gfortran
|
||||
- MPI_DIR=/usr
|
||||
- PHDF5_DIR=/usr
|
||||
- HDF5_DIR=/usr
|
||||
- OMP_NUM_THREADS=2
|
||||
- OPENMC_CROSS_SECTIONS=$HOME/nndc_hdf5/cross_sections.xml
|
||||
- OPENMC_ENDF_DATA=$HOME/endf-b-vii.1
|
||||
- OPENMC_MULTIPOLE_LIBRARY=$HOME/multipole_lib
|
||||
- PATH=$PATH:$HOME/NJOY2016/build
|
||||
matrix:
|
||||
- OPENMC_CONFIG="^hdf5-debug$"
|
||||
- OPENMC_CONFIG="^omp-hdf5-debug$"
|
||||
- OPENMC_CONFIG="^mpi-hdf5-debug$"
|
||||
- OPENMC_CONFIG="^phdf5-debug$"
|
||||
|
||||
before_install:
|
||||
- if [[ $OPENMC_CONFIG != "check_source" ]]; then
|
||||
sudo add-apt-repository ppa:nschloe/hdf5-backports -y;
|
||||
sudo apt-get update -q;
|
||||
sudo apt-get install libhdf5-serial-dev libhdf5-mpich-dev -y;
|
||||
export FC=gfortran;
|
||||
export MPI_DIR=/usr;
|
||||
export PHDF5_DIR=/usr;
|
||||
export HDF5_DIR=/usr;
|
||||
fi
|
||||
- sudo add-apt-repository ppa:nschloe/hdf5-backports -y
|
||||
- sudo apt-get update -q
|
||||
- sudo apt-get install libhdf5-serial-dev libhdf5-mpich-dev -y
|
||||
|
||||
install:
|
||||
- if [[ $OPENMC_CONFIG != "check_source" ]]; then
|
||||
pip install numpy cython;
|
||||
pip install --upgrade pytest;
|
||||
pip install -e .[test];
|
||||
fi
|
||||
- ./tools/ci/travis-install.sh
|
||||
|
||||
before_script:
|
||||
- if [[ $OPENMC_CONFIG != "check_source" ]]; then
|
||||
if [[ ! -e $HOME/nndc_hdf5/cross_sections.xml ]]; then
|
||||
wget https://anl.box.com/shared/static/a6sw2cep34wlz6b9i9jwiotaqoayxcxt.xz -O - | tar -C $HOME -xvJ;
|
||||
fi;
|
||||
export OPENMC_CROSS_SECTIONS=$HOME/nndc_hdf5/cross_sections.xml;
|
||||
git clone --branch=master git://github.com/smharper/windowed_multipole_library.git wmp_lib;
|
||||
tar xzvf wmp_lib/multipole_lib.tar.gz;
|
||||
export OPENMC_MULTIPOLE_LIBRARY=$PWD/multipole_lib;
|
||||
fi
|
||||
- ./tools/ci/travis-before-script.sh
|
||||
|
||||
script:
|
||||
- cd tests
|
||||
- export OMP_NUM_THREADS=2
|
||||
- if [[ $OPENMC_CONFIG == "check_source" ]]; then
|
||||
./check_source.py;
|
||||
else
|
||||
./run_tests.py -C $OPENMC_CONFIG -j 2 &&
|
||||
pytest --cov=../openmc -v unit_tests/;
|
||||
fi
|
||||
- cd ..
|
||||
- ./tools/ci/travis-script.sh
|
||||
|
|
|
|||
|
|
@ -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 = []
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class LaboratoryAngleEnergy(AngleEnergy):
|
|||
"""
|
||||
|
||||
def __init__(self, breakpoints, interpolation, energy, mu, energy_out):
|
||||
super(LaboratoryAngleEnergy).__init__()
|
||||
super(LaboratoryAngleEnergy, self).__init__()
|
||||
self.breakpoints = breakpoints
|
||||
self.interpolation = interpolation
|
||||
self.energy = energy
|
||||
|
|
|
|||
|
|
@ -531,7 +531,8 @@ class WindowedMultipole(EqualityMixin):
|
|||
sqrtkT = sqrt(K_BOLTZMANN * T)
|
||||
sqrtE = sqrt(E)
|
||||
invE = 1.0 / E
|
||||
dopp = self.sqrtAWR / sqrtkT
|
||||
if sqrtkT > 0.0:
|
||||
dopp = self.sqrtAWR / sqrtkT
|
||||
|
||||
# Locate us. The i_window calc omits a + 1 present in F90 because of
|
||||
# the 1-based vs. 0-based indexing. Similarly startw needs to be
|
||||
|
|
|
|||
|
|
@ -465,6 +465,8 @@ class IncidentNeutron(EqualityMixin):
|
|||
return [mt]
|
||||
elif mt in SUM_RULES:
|
||||
mts = SUM_RULES[mt]
|
||||
else:
|
||||
return []
|
||||
complete = False
|
||||
while not complete:
|
||||
new_mts = []
|
||||
|
|
@ -527,12 +529,6 @@ class IncidentNeutron(EqualityMixin):
|
|||
rx_group = rxs_group.create_group('reaction_{:03}'.format(rx.mt))
|
||||
rx.to_hdf5(rx_group)
|
||||
|
||||
# Write 0K elastic scattering if needed
|
||||
if '0K' in rx.xs and '0K' not in rx_group:
|
||||
group = rx_group.create_group('0K')
|
||||
dset = group.create_dataset('xs', data=rx.xs['0K'].y)
|
||||
dset.attrs['threshold_idx'] = 1
|
||||
|
||||
# Write total nu data if available
|
||||
if len(rx.derived_products) > 0 and 'total_nu' not in g:
|
||||
tgroup = g.create_group('total_nu')
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from collections import namedtuple
|
|||
from io import StringIO
|
||||
import os
|
||||
import shutil
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
from subprocess import Popen, PIPE, STDOUT, CalledProcessError
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
|
|
@ -139,10 +139,10 @@ def run(commands, tapein, tapeout, input_filename=None, stdout=False,
|
|||
njoy_exec : str, optional
|
||||
Path to NJOY executable
|
||||
|
||||
Returns
|
||||
-------
|
||||
int
|
||||
Return code of NJOY process
|
||||
Raises
|
||||
------
|
||||
subprocess.CalledProcessError
|
||||
If the NJOY process returns with a non-zero status
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -165,16 +165,23 @@ def run(commands, tapein, tapeout, input_filename=None, stdout=False,
|
|||
|
||||
njoy.stdin.write(commands)
|
||||
njoy.stdin.flush()
|
||||
lines = []
|
||||
while True:
|
||||
# If process is finished, break loop
|
||||
line = njoy.stdout.readline()
|
||||
if not line and njoy.poll() is not None:
|
||||
break
|
||||
|
||||
lines.append(line)
|
||||
if stdout:
|
||||
# If user requested output, print to screen
|
||||
print(line, end='')
|
||||
|
||||
# Check for error
|
||||
if njoy.returncode != 0:
|
||||
raise CalledProcessError(njoy.returncode, njoy_exec,
|
||||
''.join(lines))
|
||||
|
||||
# Copy output files back to original directory
|
||||
for tape_num, filename in tapeout.items():
|
||||
tmpfilename = os.path.join(tmpdir, 'tape{}'.format(tape_num))
|
||||
|
|
@ -183,8 +190,6 @@ def run(commands, tapein, tapeout, input_filename=None, stdout=False,
|
|||
finally:
|
||||
shutil.rmtree(tmpdir)
|
||||
|
||||
return njoy.returncode
|
||||
|
||||
|
||||
def make_pendf(filename, pendf='pendf', error=0.001, stdout=False):
|
||||
"""Generate ACE file from an ENDF file
|
||||
|
|
@ -200,15 +205,15 @@ def make_pendf(filename, pendf='pendf', error=0.001, stdout=False):
|
|||
stdout : bool
|
||||
Whether to display NJOY standard output
|
||||
|
||||
Returns
|
||||
-------
|
||||
int
|
||||
Return code of NJOY process
|
||||
Raises
|
||||
------
|
||||
subprocess.CalledProcessError
|
||||
If the NJOY process returns with a non-zero status
|
||||
|
||||
"""
|
||||
|
||||
return make_ace(filename, pendf=pendf, error=error, broadr=False,
|
||||
heatr=False, purr=False, acer=False, stdout=stdout)
|
||||
make_ace(filename, pendf=pendf, error=error, broadr=False,
|
||||
heatr=False, purr=False, acer=False, stdout=stdout)
|
||||
|
||||
|
||||
def make_ace(filename, temperatures=None, ace='ace', xsdir='xsdir', pendf=None,
|
||||
|
|
@ -238,14 +243,14 @@ def make_ace(filename, temperatures=None, ace='ace', xsdir='xsdir', pendf=None,
|
|||
purr : bool, optional
|
||||
Indicating whether to add probability table when running NJOY
|
||||
acer : bool, optional
|
||||
Indicating whether to generate ACE file when running NJOY
|
||||
Indicating whether to generate ACE file when running NJOY
|
||||
**kwargs
|
||||
Keyword arguments passed to :func:`openmc.data.njoy.run`
|
||||
|
||||
Returns
|
||||
-------
|
||||
int
|
||||
Return code of NJOY process
|
||||
Raises
|
||||
------
|
||||
subprocess.CalledProcessError
|
||||
If the NJOY process returns with a non-zero status
|
||||
|
||||
"""
|
||||
ev = endf.Evaluation(filename)
|
||||
|
|
@ -285,7 +290,7 @@ def make_ace(filename, temperatures=None, ace='ace', xsdir='xsdir', pendf=None,
|
|||
nheatr = nheatr_in + 1
|
||||
commands += _TEMPLATE_HEATR
|
||||
nlast = nheatr
|
||||
|
||||
|
||||
# purr
|
||||
if purr:
|
||||
npurr_in = nlast
|
||||
|
|
@ -310,9 +315,9 @@ def make_ace(filename, temperatures=None, ace='ace', xsdir='xsdir', pendf=None,
|
|||
tapeout[nace] = fname.format(ace, temperature)
|
||||
tapeout[ndir] = fname.format(xsdir, temperature)
|
||||
commands += 'stop\n'
|
||||
retcode = run(commands, tapein, tapeout, **kwargs)
|
||||
run(commands, tapein, tapeout, **kwargs)
|
||||
|
||||
if acer and retcode == 0:
|
||||
if acer:
|
||||
with open(ace, 'w') as ace_file, open(xsdir, 'w') as xsdir_file:
|
||||
for temperature in temperatures:
|
||||
# Get contents of ACE file
|
||||
|
|
@ -337,10 +342,8 @@ def make_ace(filename, temperatures=None, ace='ace', xsdir='xsdir', pendf=None,
|
|||
os.remove(fname.format(ace, temperature))
|
||||
os.remove(fname.format(xsdir, temperature))
|
||||
|
||||
return retcode
|
||||
|
||||
|
||||
def make_ace_thermal(filename, filename_thermal, temperatures=None,
|
||||
def make_ace_thermal(filename, filename_thermal, temperatures=None,
|
||||
ace='ace', xsdir='xsdir', error=0.001, **kwargs):
|
||||
"""Generate thermal scattering ACE file from ENDF files
|
||||
|
||||
|
|
@ -362,10 +365,10 @@ def make_ace_thermal(filename, filename_thermal, temperatures=None,
|
|||
**kwargs
|
||||
Keyword arguments passed to :func:`openmc.data.njoy.run`
|
||||
|
||||
Returns
|
||||
-------
|
||||
int
|
||||
Return code of NJOY process
|
||||
Raises
|
||||
------
|
||||
subprocess.CalledProcessError
|
||||
If the NJOY process returns with a non-zero status
|
||||
|
||||
"""
|
||||
ev = endf.Evaluation(filename)
|
||||
|
|
@ -461,21 +464,18 @@ def make_ace_thermal(filename, filename_thermal, temperatures=None,
|
|||
tapeout[nace] = fname.format(ace, temperature)
|
||||
tapeout[ndir] = fname.format(xsdir, temperature)
|
||||
commands += 'stop\n'
|
||||
retcode = run(commands, tapein, tapeout, **kwargs)
|
||||
run(commands, tapein, tapeout, **kwargs)
|
||||
|
||||
if retcode == 0:
|
||||
with open(ace, 'w') as ace_file, open(xsdir, 'w') as xsdir_file:
|
||||
# Concatenate ACE and xsdir files together
|
||||
for temperature in temperatures:
|
||||
text = open(fname.format(ace, temperature), 'r').read()
|
||||
ace_file.write(text)
|
||||
|
||||
text = open(fname.format(xsdir, temperature), 'r').read()
|
||||
xsdir_file.write(text)
|
||||
|
||||
# Remove ACE/xsdir files for each temperature
|
||||
with open(ace, 'w') as ace_file, open(xsdir, 'w') as xsdir_file:
|
||||
# Concatenate ACE and xsdir files together
|
||||
for temperature in temperatures:
|
||||
os.remove(fname.format(ace, temperature))
|
||||
os.remove(fname.format(xsdir, temperature))
|
||||
text = open(fname.format(ace, temperature), 'r').read()
|
||||
ace_file.write(text)
|
||||
|
||||
return retcode
|
||||
text = open(fname.format(xsdir, temperature), 'r').read()
|
||||
xsdir_file.write(text)
|
||||
|
||||
# Remove ACE/xsdir files for each temperature
|
||||
for temperature in temperatures:
|
||||
os.remove(fname.format(ace, temperature))
|
||||
os.remove(fname.format(xsdir, temperature))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from collections import Iterable
|
||||
from difflib import get_close_matches
|
||||
from numbers import Real
|
||||
import itertools
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
|
|
@ -25,37 +26,37 @@ from openmc.stats import Discrete, Tabular
|
|||
_THERMAL_NAMES = {
|
||||
'c_Al27': ('al', 'al27'),
|
||||
'c_Be': ('be', 'be-metal'),
|
||||
'c_BeO': ('beo',),
|
||||
'c_BeO': ('beo'),
|
||||
'c_Be_in_BeO': ('bebeo', 'be-o', 'be/o'),
|
||||
'c_C6H6': ('benz', 'c6h6'),
|
||||
'c_C_in_SiC': ('csic',),
|
||||
'c_Ca_in_CaH2': ('cah',),
|
||||
'c_Ca_in_CaH2': ('cah'),
|
||||
'c_D_in_D2O': ('dd2o', 'hwtr', 'hw'),
|
||||
'c_Fe56': ('fe', 'fe56'),
|
||||
'c_Graphite': ('graph', 'grph', 'gr'),
|
||||
'c_H_in_CaH2': ('hcah2',),
|
||||
'c_H_in_CaH2': ('hcah2'),
|
||||
'c_H_in_CH2': ('hch2', 'poly', 'pol'),
|
||||
'c_H_in_CH4_liquid': ('lch4', 'lmeth'),
|
||||
'c_H_in_CH4_solid': ('sch4', 'smeth'),
|
||||
'c_H_in_H2O': ('hh2o', 'lwtr', 'lw'),
|
||||
'c_H_in_H2O_solid': ('hice',),
|
||||
'c_H_in_C5O2H8': ('lucite', 'c5o2h8'),
|
||||
'c_H_in_YH2': ('hyh2',),
|
||||
'c_H_in_YH2': ('hyh2'),
|
||||
'c_H_in_ZrH': ('hzrh', 'h-zr', 'h/zr', 'hzr'),
|
||||
'c_Mg24': ('mg', 'mg24'),
|
||||
'c_O_in_BeO': ('obeo', 'o-be', 'o/be'),
|
||||
'c_O_in_D2O': ('od2o',),
|
||||
'c_O_in_H2O_ice': ('oice',),
|
||||
'c_O_in_D2O': ('od2o'),
|
||||
'c_O_in_H2O_ice': ('oice'),
|
||||
'c_O_in_UO2': ('ouo2', 'o2-u', 'o2/u'),
|
||||
'c_ortho_D': ('orthod', 'dortho'),
|
||||
'c_ortho_H': ('orthoh', 'hortho'),
|
||||
'c_Si_in_SiC': ('sisic',),
|
||||
'c_Si_in_SiC': ('sisic'),
|
||||
'c_SiO2_alpha': ('sio2', 'sio2a'),
|
||||
'c_SiO2_beta': ('sio2b'),
|
||||
'c_para_D': ('parad', 'dpara'),
|
||||
'c_para_H': ('parah', 'hpara'),
|
||||
'c_U_in_UO2': ('uuo2', 'u-o2', 'u/o2'),
|
||||
'c_Y_in_YH2': ('yyh2',),
|
||||
'c_Y_in_YH2': ('yyh2'),
|
||||
'c_Zr_in_ZrH': ('zrzrh', 'zr-h', 'zr/h')
|
||||
}
|
||||
|
||||
|
|
@ -84,13 +85,25 @@ def get_thermal_name(name):
|
|||
# Make an educated guess?? This actually works well for
|
||||
# JEFF-3.2 which stupidly uses names like lw00.32t,
|
||||
# lw01.32t, etc. for different temperatures
|
||||
for proper_name, names in _THERMAL_NAMES.items():
|
||||
matches = get_close_matches(
|
||||
name.lower(), names, cutoff=0.5)
|
||||
if len(matches) > 0:
|
||||
warn('Thermal scattering material "{}" is not recognized. '
|
||||
'Assigning a name of {}.'.format(name, proper_name))
|
||||
return proper_name
|
||||
|
||||
# First, construct a list of all the values/keys in the names
|
||||
# dictionary
|
||||
all_names = itertools.chain(_THERMAL_NAMES.keys(),
|
||||
*_THERMAL_NAMES.values())
|
||||
|
||||
matches = get_close_matches(name, all_names, cutoff=0.5)
|
||||
if len(matches) > 0:
|
||||
# Figure out the key for the corresponding match
|
||||
match = matches[0]
|
||||
if match not in _THERMAL_NAMES:
|
||||
for key, value_list in _THERMAL_NAMES.items():
|
||||
if match in value_list:
|
||||
match = key
|
||||
break
|
||||
|
||||
warn('Thermal scattering material "{}" is not recognized. '
|
||||
'Assigning a name of {}.'.format(name, match))
|
||||
return match
|
||||
else:
|
||||
# OK, we give up. Just use the ACE name.
|
||||
warn('Thermal scattering material "{0}" is not recognized. '
|
||||
|
|
@ -408,30 +421,27 @@ class ThermalScattering(EqualityMixin):
|
|||
# Cross section
|
||||
elastic_xs_type = elastic_group['xs'].attrs['type'].decode()
|
||||
if elastic_xs_type == 'Tabulated1D':
|
||||
table.elastic_xs[T] = \
|
||||
Tabulated1D.from_hdf5(elastic_group['xs'])
|
||||
table.elastic_xs[T] = Tabulated1D.from_hdf5(
|
||||
elastic_group['xs'])
|
||||
elif elastic_xs_type == 'bragg':
|
||||
table.elastic_xs[T] = \
|
||||
CoherentElastic.from_hdf5(elastic_group['xs'])
|
||||
table.elastic_xs[T] = CoherentElastic.from_hdf5(
|
||||
elastic_group['xs'])
|
||||
|
||||
# Angular distribution
|
||||
if 'mu_out' in elastic_group:
|
||||
table.elastic_mu_out[T] = \
|
||||
elastic_group['mu_out'].value
|
||||
table.elastic_mu_out[T] = elastic_group['mu_out'].value
|
||||
|
||||
# Read thermal inelastic scattering
|
||||
if 'inelastic' in Tgroup:
|
||||
inelastic_group = Tgroup['inelastic']
|
||||
table.inelastic_xs[T] = \
|
||||
Tabulated1D.from_hdf5(inelastic_group['xs'])
|
||||
table.inelastic_xs[T] = Tabulated1D.from_hdf5(
|
||||
inelastic_group['xs'])
|
||||
if table.secondary_mode in ('equal', 'skewed'):
|
||||
table.inelastic_e_out[T] = \
|
||||
inelastic_group['energy_out']
|
||||
table.inelastic_mu_out[T] = \
|
||||
inelastic_group['mu_out']
|
||||
table.inelastic_e_out[T] = inelastic_group['energy_out'].value
|
||||
table.inelastic_mu_out[T] = inelastic_group['mu_out'].value
|
||||
elif table.secondary_mode == 'continuous':
|
||||
table.inelastic_dist[T] = \
|
||||
AngleEnergy.from_hdf5(inelastic_group)
|
||||
table.inelastic_dist[T] = AngleEnergy.from_hdf5(
|
||||
inelastic_group)
|
||||
|
||||
return table
|
||||
|
||||
|
|
|
|||
82
tests/unit_tests/test_data_decay.py
Normal file
82
tests/unit_tests/test_data_decay.py
Normal file
|
|
@ -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))
|
||||
50
tests/unit_tests/test_data_misc.py
Normal file
50
tests/unit_tests/test_data_misc.py
Normal file
|
|
@ -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)
|
||||
39
tests/unit_tests/test_data_multipole.py
Normal file
39
tests/unit_tests/test_data_multipole.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
import openmc.data
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def u235():
|
||||
directory = os.environ['OPENMC_MULTIPOLE_LIBRARY']
|
||||
filename = os.path.join(directory, '092235.h5')
|
||||
return openmc.data.WindowedMultipole.from_hdf5(filename)
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def fe56():
|
||||
directory = os.environ['OPENMC_MULTIPOLE_LIBRARY']
|
||||
filename = os.path.join(directory, '026056.h5')
|
||||
return openmc.data.WindowedMultipole.from_hdf5(filename)
|
||||
|
||||
|
||||
def test_evaluate(u235):
|
||||
"""Make sure multipole object can be called."""
|
||||
energies = [1e-3, 1.0, 10.0, 50.]
|
||||
total, absorption, fission = u235(energies, 0.0)
|
||||
assert total[1] == pytest.approx(90.64895383)
|
||||
total, absorption, fission = u235(energies, 300.0)
|
||||
assert total[1] == pytest.approx(91.12534964)
|
||||
|
||||
|
||||
def test_high_l(fe56):
|
||||
"""Test a nuclide (Fe56) with a high l-value (4)."""
|
||||
energies = [1e-3, 1.0, 10.0, 1e3, 1e5]
|
||||
total, absorption, fission = fe56(energies, 0.0)
|
||||
assert total[0] == pytest.approx(25.072619556789267)
|
||||
total, absorption, fission = fe56(energies, 300.0)
|
||||
assert total[0] == pytest.approx(27.85535792368082)
|
||||
364
tests/unit_tests/test_data_neutron.py
Normal file
364
tests/unit_tests/test_data_neutron.py
Normal file
|
|
@ -0,0 +1,364 @@
|
|||
#!/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(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'))
|
||||
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)
|
||||
101
tests/unit_tests/test_data_thermal.py
Normal file
101
tests/unit_tests/test_data_thermal.py
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from collections import Callable
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
import openmc.data
|
||||
|
||||
|
||||
_ENDF_DATA = os.environ['OPENMC_ENDF_DATA']
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def h2o():
|
||||
"""H in H2O thermal scattering data."""
|
||||
directory = os.path.dirname(os.environ['OPENMC_CROSS_SECTIONS'])
|
||||
filename = os.path.join(directory, 'c_H_in_H2O.h5')
|
||||
return openmc.data.ThermalScattering.from_hdf5(filename)
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def graphite():
|
||||
"""Graphite thermal scattering data."""
|
||||
directory = os.path.dirname(os.environ['OPENMC_CROSS_SECTIONS'])
|
||||
filename = os.path.join(directory, 'c_Graphite.h5')
|
||||
return openmc.data.ThermalScattering.from_hdf5(filename)
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def h2o_njoy():
|
||||
path_h1 = os.path.join(_ENDF_DATA, 'neutrons', 'n-001_H_001.endf')
|
||||
path_h2o = os.path.join(_ENDF_DATA, 'thermal_scatt', 'tsl-HinH2O.endf')
|
||||
return openmc.data.ThermalScattering.from_njoy(
|
||||
path_h1, path_h2o, temperatures=[293.6, 500.0])
|
||||
|
||||
|
||||
def test_h2o_attributes(h2o):
|
||||
assert h2o.name == 'c_H_in_H2O'
|
||||
assert h2o.nuclides == ['H1']
|
||||
assert h2o.secondary_mode == 'skewed'
|
||||
assert h2o.temperatures == ['294K']
|
||||
assert h2o.atomic_weight_ratio == pytest.approx(0.999167)
|
||||
|
||||
|
||||
def test_h2o_xs(h2o):
|
||||
assert not h2o.elastic_xs
|
||||
for temperature, func in h2o.inelastic_xs.items():
|
||||
assert temperature.endswith('K')
|
||||
assert isinstance(func, Callable)
|
||||
|
||||
|
||||
def test_graphite_attributes(graphite):
|
||||
assert graphite.name == 'c_Graphite'
|
||||
assert graphite.nuclides == ['C0', 'C12', 'C13']
|
||||
assert graphite.secondary_mode == 'skewed'
|
||||
assert graphite.temperatures == ['296K']
|
||||
assert graphite.atomic_weight_ratio == pytest.approx(11.898)
|
||||
|
||||
|
||||
def test_graphite_xs(graphite):
|
||||
for temperature, func in graphite.elastic_xs.items():
|
||||
assert temperature.endswith('K')
|
||||
assert isinstance(func, openmc.data.CoherentElastic)
|
||||
for temperature, func in graphite.inelastic_xs.items():
|
||||
assert temperature.endswith('K')
|
||||
assert isinstance(func, Callable)
|
||||
elastic = graphite.elastic_xs['296K']
|
||||
assert elastic([1e-3, 1.0]) == pytest.approx([13.47464936, 0.62590156])
|
||||
|
||||
|
||||
def test_export_to_hdf5(tmpdir, h2o_njoy, graphite):
|
||||
filename = str(tmpdir.join('water.h5'))
|
||||
h2o_njoy.export_to_hdf5(filename)
|
||||
assert os.path.exists(filename)
|
||||
|
||||
filename = str(tmpdir.join('graphite.h5'))
|
||||
graphite.export_to_hdf5(filename)
|
||||
assert os.path.exists(filename)
|
||||
|
||||
|
||||
def test_continuous_dist(h2o_njoy):
|
||||
for temperature, dist in h2o_njoy.inelastic_dist.items():
|
||||
assert temperature.endswith('K')
|
||||
assert isinstance(dist, openmc.data.CorrelatedAngleEnergy)
|
||||
|
||||
|
||||
def test_get_thermal_name():
|
||||
f = openmc.data.get_thermal_name
|
||||
# Names which are recognized
|
||||
assert f('lwtr') == 'c_H_in_H2O'
|
||||
assert f('hh2o') == 'c_H_in_H2O'
|
||||
|
||||
with pytest.warns(UserWarning, match='is not recognized'):
|
||||
# Names which can be guessed
|
||||
assert f('lw00') == 'c_H_in_H2O'
|
||||
assert f('graphite') == 'c_Graphite'
|
||||
assert f('D_in_D2O') == 'c_D_in_D2O'
|
||||
|
||||
# Names that don't remotely match anything
|
||||
assert f('boogie_monster') == 'c_boogie_monster'
|
||||
16
tools/ci/travis-before-script.sh
Executable file
16
tools/ci/travis-before-script.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
set -ex
|
||||
|
||||
# Download NNDC HDF5 data
|
||||
if [[ ! -e $HOME/nndc_hdf5/cross_sections.xml ]]; then
|
||||
wget https://anl.box.com/shared/static/a6sw2cep34wlz6b9i9jwiotaqoayxcxt.xz -O - | tar -C $HOME -xvJ
|
||||
fi
|
||||
|
||||
# Download ENDF/B-VII.1 distribution
|
||||
if [[ ! -d $HOME/endf-b-vii.1/neutrons ]]; then
|
||||
wget https://anl.box.com/shared/static/4kd2gxnf4gtk4w1c8eua5fsua22kvgjb.xz -O - | tar -C $HOME -xvJ
|
||||
fi
|
||||
|
||||
# Download multipole library
|
||||
git clone --branch=master git://github.com/smharper/windowed_multipole_library.git wmp_lib
|
||||
tar -C $HOME -xzvf wmp_lib/multipole_lib.tar.gz
|
||||
8
tools/ci/travis-install-njoy.sh
Executable file
8
tools/ci/travis-install-njoy.sh
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/bash
|
||||
set -ex
|
||||
cd $HOME
|
||||
git clone https://github.com/njoy/NJOY2016
|
||||
cd NJOY2016
|
||||
sed -i -e 's/5\.1/4.8/' CMakeLists.txt
|
||||
mkdir build && cd build
|
||||
cmake -Dstatic=on .. && make 2>/dev/null && sudo make install
|
||||
19
tools/ci/travis-install.sh
Executable file
19
tools/ci/travis-install.sh
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/bash
|
||||
set -ex
|
||||
|
||||
# Install NJOY 2016
|
||||
./tools/ci/travis-install-njoy.sh
|
||||
|
||||
# Running OpenMC's setup.py requires numpy/cython already
|
||||
pip install numpy cython
|
||||
|
||||
# pytest installed by default -- make sure we get latest
|
||||
pip install --upgrade pytest
|
||||
|
||||
# Pandas stopped supporting Python 3.4 with version 0.21
|
||||
if [[ "$TRAVIS_PYTHON_VERSION" == "3.4" ]]; then
|
||||
pip install pandas==0.20.3
|
||||
fi
|
||||
|
||||
# Install OpenMC in editable mode
|
||||
pip install -e .[test]
|
||||
8
tools/ci/travis-script.sh
Executable file
8
tools/ci/travis-script.sh
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/bash
|
||||
set -ex
|
||||
cd tests
|
||||
if [[ $TRAVIS_PYTHON_VERSION == "3.4" && $OPENMC_CONFIG == '^hdf5-debug$' ]]; then
|
||||
./check_source.py
|
||||
fi
|
||||
./run_tests.py -C $OPENMC_CONFIG -j 2
|
||||
pytest --cov=../openmc -v unit_tests/
|
||||
Loading…
Add table
Add a link
Reference in a new issue