diff --git a/openmc/data/compton_profiles.h5 b/openmc/data/compton_profiles.h5 index e4fa2e56d..298ed0340 100644 Binary files a/openmc/data/compton_profiles.h5 and b/openmc/data/compton_profiles.h5 differ diff --git a/openmc/data/photon.py b/openmc/data/photon.py index a723b114f..4fdc60579 100644 --- a/openmc/data/photon.py +++ b/openmc/data/photon.py @@ -159,7 +159,6 @@ class AtomicRelaxation(EqualityMixin): self.binding_energy = binding_energy self.num_electrons = num_electrons self.transitions = transitions - self.compton_profile = OrderedDict() @property def binding_energy(self): diff --git a/openmc/data/stopping_powers.h5 b/openmc/data/stopping_powers.h5 index 7730925cf..4bc5b1388 100644 Binary files a/openmc/data/stopping_powers.h5 and b/openmc/data/stopping_powers.h5 differ diff --git a/src/output.F90 b/src/output.F90 index 6197cdc11..ee4847630 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -547,7 +547,7 @@ contains ! format for write statements 100 format (1X,A,T36,"= ",ES11.4," seconds") -101 format (1X,A,T36,"= ",A," neutrons/second") +101 format (1X,A,T36,"= ",A," particles/second") end subroutine print_runtime diff --git a/src/settings.F90 b/src/settings.F90 index c1bb09b41..1fbcb9209 100644 --- a/src/settings.F90 +++ b/src/settings.F90 @@ -27,7 +27,7 @@ module settings integer :: n_log_bins ! number of bins for logarithmic grid logical :: photon_transport = .false. - integer :: electron_treatment = ELECTRON_LED + integer :: electron_treatment = ELECTRON_TTB ! ============================================================================ ! MULTI-GROUP CROSS SECTION RELATED VARIABLES diff --git a/tests/regression_tests/photon_source/inputs_true.dat b/tests/regression_tests/photon_source/inputs_true.dat new file mode 100644 index 000000000..56ef025e7 --- /dev/null +++ b/tests/regression_tests/photon_source/inputs_true.dat @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + fixed source + 10000 + 1 + + + 0 0 0 + + + + 10000000.0 1.0 + + + ttb + true + + 1000.0 + + + + + + flux + + diff --git a/tests/regression_tests/photon_source/results_true.dat b/tests/regression_tests/photon_source/results_true.dat new file mode 100644 index 000000000..609f887bd --- /dev/null +++ b/tests/regression_tests/photon_source/results_true.dat @@ -0,0 +1,3 @@ +tally 1: +sum = 2.254985E+02 +sum_sq = 5.084955E+04 diff --git a/tests/regression_tests/photon_source/test.py b/tests/regression_tests/photon_source/test.py new file mode 100644 index 000000000..f278e0c27 --- /dev/null +++ b/tests/regression_tests/photon_source/test.py @@ -0,0 +1,61 @@ +from math import pi + +import numpy as np +import openmc + +from tests.testing_harness import PyAPITestHarness + + +class SourceTestHarness(PyAPITestHarness): + def _build_inputs(self): + mat = openmc.Material() + mat.set_density('g/cm3', 0.998207) + mat.add_element('H', 0.111894) + mat.add_element('O', 0.888106) + materials = openmc.Materials([mat]) + materials.export_to_xml() + + sphere = openmc.Sphere(R=1.0e9, boundary_type='reflective') + inside_sphere = openmc.Cell() + inside_sphere.region = -sphere + inside_sphere.fill = mat + root = openmc.Universe() + root.add_cell(inside_sphere) + geometry = openmc.Geometry(root) + geometry.export_to_xml() + + source = openmc.Source() + source.space = openmc.stats.Point((0, 0, 0)) + source.angle = openmc.stats.Isotropic() + source.energy = openmc.stats.Discrete([10.0e6], [1.0]) + source.particle = 'photon' + + settings = openmc.Settings() + settings.particles = 10000 + settings.batches = 1 + settings.photon_transport = True + settings.electron_treatment = 'ttb' + settings.cutoff = {'energy_photon' : 1000.0} + settings.run_mode = 'fixed source' + settings.source = source + settings.export_to_xml() + + tally = openmc.Tally() + tally.scores = ['flux'] + tallies = openmc.Tallies([tally]) + tallies.export_to_xml() + + def _get_results(self): + sp = openmc.StatePoint(self._sp_name) + outstr = '' + t = sp.get_tally() + outstr += 'tally {}:\n'.format(t.id) + outstr += 'sum = {:12.6E}\n'.format(t.sum[0, 0, 0]) + outstr += 'sum_sq = {:12.6E}\n'.format(t.sum_sq[0, 0, 0]) + + return outstr + + +def test_source(): + harness = SourceTestHarness('statepoint.1.h5') + harness.main() diff --git a/tests/unit_tests/test_data_photon.py b/tests/unit_tests/test_data_photon.py new file mode 100644 index 000000000..eecef73c4 --- /dev/null +++ b/tests/unit_tests/test_data_photon.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python + +from collections import Mapping, Callable +import os + +import numpy as np +import pandas as pd +import pytest +import openmc.data + + +_ENDF_DATA = os.environ['OPENMC_ENDF_DATA'] + + +@pytest.fixture(scope='module') +def elements_endf(): + """Dictionary of element ENDF data indexed by atomic symbol.""" + elements = {'H': 1, 'O': 8, 'Al': 13, 'Cu': 29, 'Ag': 47, 'U': 92, 'Pu': 94} + data = {} + for symbol, Z in elements.items(): + p_file = 'photoat-{:03}_{}_000.endf'.format(Z, symbol) + p_path = os.path.join(_ENDF_DATA, 'photoat', p_file) + a_file = 'atom-{:03}_{}_000.endf'.format(Z, symbol) + a_path = os.path.join(_ENDF_DATA, 'atomic_relax', a_file) + data[symbol] = openmc.data.IncidentPhoton.from_endf(p_path, a_path) + return data + + +@pytest.fixture() +def element(request, elements_endf): + """Element ENDF data""" + return elements_endf[request.param] + + +@pytest.mark.parametrize( + 'element, atomic_number', [ + ('Al', 13), + ('Cu', 29), + ('Pu', 94) + ], + indirect=['element'] +) +def test_attributes(element, atomic_number): + assert element.atomic_number == atomic_number + + +@pytest.mark.parametrize( + 'element, subshell, binding_energy, num_electrons', [ + ('H', 'K', 13.61, 1.0), + ('O', 'L3', 14.15, 2.67), + ('U', 'P2', 34.09, 2.0) + ], + indirect=['element'] +) +def test_atomic_relaxation(element, subshell, binding_energy, num_electrons): + atom_relax = element.atomic_relaxation + assert isinstance(atom_relax, openmc.data.photon.AtomicRelaxation) + assert subshell in atom_relax.subshells + assert atom_relax.binding_energy[subshell] == binding_energy + assert atom_relax.num_electrons[subshell] == num_electrons + + +@pytest.mark.parametrize('element', ['Al', 'Cu', 'Pu'], indirect=True) +def test_transitions(element): + transitions = element.atomic_relaxation.transitions + assert transitions + assert isinstance(transitions, Mapping) + for matrix in transitions.values(): + assert isinstance(matrix, pd.core.frame.DataFrame) + assert len(matrix.columns) == 4 + assert sum(matrix['probability']) == pytest.approx(1.0) + + +@pytest.mark.parametrize('element', ['H', 'Al', 'Ag'], indirect=True) +def test_bremsstrahlung(element): + brems = element.bremsstrahlung + assert isinstance(brems, Mapping) + assert np.all(np.diff(brems['electron_energy']) > 0.0) + assert np.all(np.diff(brems['photon_energy']) > 0.0) + assert brems['photon_energy'][0] == 0.0 + assert brems['photon_energy'][-1] == 1.0 + assert brems['dcs'].shape == (200, 30) + + +@pytest.mark.parametrize( + 'element, n_shell', [ + ('H', 1), + ('O', 3), + ('Al', 5) + ], + indirect=['element'] +) +def test_compton_profiles(element, n_shell): + profile = element.compton_profiles + assert profile + assert isinstance(profile, Mapping) + assert all(isinstance(x, Callable) for x in profile['J']) + assert all(len(x) == n_shell for x in profile.values()) + + +@pytest.mark.parametrize( + 'element, reaction', [ + ('Cu', 541), + ('Ag', 502), + ('Pu', 504) + ], + indirect=['element'] +) +def test_reactions(element, reaction): + reactions = element.reactions + assert all(isinstance(x, openmc.data.PhotonReaction) for x in reactions.values()) + assert reaction in reactions + with pytest.raises(KeyError): + reactions[18] + + +@pytest.mark.parametrize( + 'element, I', [ + ('H', 19.2), + ('O', 95.0), + ('U', 890.0) + ], + indirect=['element'] +) +def test_stopping_powers(element, I): + stopping_powers = element.stopping_powers + assert isinstance(stopping_powers, Mapping) + assert stopping_powers['I'] == I + assert np.all(np.diff(stopping_powers['energy']) > 0.0) + assert len(stopping_powers['s_collision']) == 200 + assert len(stopping_powers['s_radiative']) == 200 + + +@pytest.mark.parametrize('element', ['Pu'], indirect=True) +def test_export_to_hdf5(tmpdir, element): + filename = str(tmpdir.join('tmp.h5')) + element.export_to_hdf5(filename) + assert os.path.exists(filename) diff --git a/tools/ci/travis-before-script.sh b/tools/ci/travis-before-script.sh index d0df06f2f..bbb34358b 100755 --- a/tools/ci/travis-before-script.sh +++ b/tools/ci/travis-before-script.sh @@ -7,11 +7,12 @@ sh -e /etc/init.d/xvfb start # 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 + wget https://anl.box.com/shared/static/na85do11dfh0lb9utye2il5o6yaxx8hi.xz -O - | tar -C $HOME -xvJ fi # Download ENDF/B-VII.1 distribution -if [[ ! -d $HOME/endf-b-vii.1/neutrons ]]; then +ENDF=$HOME/endf-b-vii.1/ +if [[ ! -d $ENDF/neutrons || ! -d $ENDF/photoat || ! -d $ENDF/atomic_relax ]]; then wget https://anl.box.com/shared/static/4kd2gxnf4gtk4w1c8eua5fsua22kvgjb.xz -O - | tar -C $HOME -xvJ fi