From b0a300aedcd453b46f530547afbb6280c4b564f0 Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 13 Oct 2022 21:24:25 +0000 Subject: [PATCH] add to existing temp interp test, update doccs --- docs/source/io_formats/settings.rst | 8 +- tests/unit_tests/test_temp_interp.py | 121 ++++++++++++++++++++++++--- 2 files changed, 113 insertions(+), 16 deletions(-) diff --git a/docs/source/io_formats/settings.rst b/docs/source/io_formats/settings.rst index 7a794bf003..1a29e00ee7 100644 --- a/docs/source/io_formats/settings.rst +++ b/docs/source/io_formats/settings.rst @@ -875,10 +875,10 @@ cell temperature is 340 K and the tolerance is 15 K, then the closest temperature in the range of 325 K to 355 K will be used to evaluate cross sections. If the ```` is "interpolation", the tolerance specified applies to cell temperatures outside of the data bounds. For example, -If a cell is specified at 695K, a tolerance of 15K and data only available at -700K and 1000K, the cell's cross sections will be evaluated at 700K, since -desired temperature of 695K is within the tolerance of the actual data despite -not being bounded on both sides. +if a cell is specified at 695K, a tolerance of 15K and data is only available +at 700K and 1000K, the cell's cross sections will be evaluated at 700K, since +the desired temperature of 695K is within the tolerance of the actual data +despite not being bounded on both sides. *Default*: 10 K diff --git a/tests/unit_tests/test_temp_interp.py b/tests/unit_tests/test_temp_interp.py index f87d529619..c64ebe46ad 100644 --- a/tests/unit_tests/test_temp_interp.py +++ b/tests/unit_tests/test_temp_interp.py @@ -86,6 +86,70 @@ def make_fake_cross_section(): lib.export_to_xml('cross_sections_fake.xml') +def fake_thermal_scattering(): + """Create a fake thermal scattering library for U-235 at 294K and 600K + """ + fake_tsl = openmc.data.ThermalScattering("c_U_fake", 1.9968, 4.9, [0.0253]) + fake_tsl.nuclides = ['U235'] + + # Create elastic reaction + bragg_edges = [0.00370672, 0.00494229] + factors = [0.00375735, 0.01386287] + coherent_xs = openmc.data.CoherentElastic(bragg_edges, factors) + incoherent_xs_294 = openmc.data.Tabulated1D([0.00370672, 0.00370672], [0.00370672, 0.00370672]) + elastic_xs_base = openmc.data.Sum((coherent_xs, incoherent_xs_294)) + elastic_xs = {'294K': elastic_xs_base, '600K': elastic_xs_base} + coherent_dist = openmc.data.CoherentElasticAE(coherent_xs) + incoherent_dist_294 = openmc.data.IncoherentElasticAEDiscrete([ + [-0.6, -0.18, 0.18, 0.6], [-0.6, -0.18, 0.18, 0.6] + ]) + incoherent_dist_600 = openmc.data.IncoherentElasticAEDiscrete([ + [-0.1, -0.2, 0.2, 0.1], [-0.1, -0.2, 0.2, 0.1] + ]) + elastic_dist = { + '294K': openmc.data.MixedElasticAE(coherent_dist, incoherent_dist_294), + '600K': openmc.data.MixedElasticAE(coherent_dist, incoherent_dist_600) + } + fake_tsl.elastic = openmc.data.ThermalScatteringReaction(elastic_xs, elastic_dist) + + # Create inelastic reaction + inelastic_xs = { + '294K': openmc.data.Tabulated1D([1.0e-5, 4.9], [13.4, 3.35]), + '600K': openmc.data.Tabulated1D([1.0e-2, 10], [1.4, 5]) + } + breakpoints = [3] + interpolation = [2] + energy = [1.0e-5, 4.3e-2, 4.9] + energy_out = [ + openmc.data.Tabular([0.0002, 0.067, 0.146, 0.366], [0.25, 0.25, 0.25, 0.25]), + openmc.data.Tabular([0.0001, 0.009, 0.137, 0.277], [0.25, 0.25, 0.25, 0.25]), + openmc.data.Tabular([0.0579, 4.555, 4.803, 4.874], [0.25, 0.25, 0.25, 0.25]), + ] + for eout in energy_out: + eout.normalize() + eout.c = eout.cdf() + discrete = openmc.stats.Discrete([-0.9, -0.6, -0.3, -0.1, 0.1, 0.3, 0.6, 0.9], [1/8]*8) + discrete.c = discrete.cdf()[1:] + mu = [[discrete]*4]*3 + dist = openmc.data.IncoherentInelasticAE( + breakpoints, interpolation, energy, energy_out, mu) + inelastic_dist = {'294K': dist, '600K': dist} + inelastic = openmc.data.ThermalScatteringReaction(inelastic_xs, inelastic_dist) + fake_tsl.inelastic = inelastic + + return fake_tsl + + +def edit_fake_cross_sections(): + """Edit the test cross sections xml to include fake thermal scattering data + """ + lib = openmc.data.DataLibrary.from_xml("cross_sections_fake.xml") + c_U_fake = fake_thermal_scattering() + c_U_fake.export_to_hdf5("c_U_fake.h5") + lib.register_file("c_U_fake.h5") + lib.export_to_xml("cross_sections_fake.xml") + + @pytest.fixture(scope='module') def model(tmp_path_factory): tmp_path = tmp_path_factory.mktemp("temp_interp") @@ -119,21 +183,23 @@ def model(tmp_path_factory): @pytest.mark.parametrize( - ["method", "temperature", "fission_expected"], + ["method", "temperature", "fission_expected", "tolerance"], [ - ("nearest", 300.0, 0.5), - ("nearest", 600.0, 1.0), - ("nearest", 900.0, 0.5), - ("interpolation", 360.0, 0.6), - ("interpolation", 450.0, 0.75), - ("interpolation", 540.0, 0.9), - ("interpolation", 660.0, 0.9), - ("interpolation", 750.0, 0.75), - ("interpolation", 840.0, 0.6), + ("nearest", 300.0, 0.5, 10), + ("nearest", 600.0, 1.0, 10), + ("nearest", 900.0, 0.5, 10), + ("interpolation", 360.0, 0.6, 10), + ("interpolation", 450.0, 0.75, 10), + ("interpolation", 540.0, 0.9, 10), + ("interpolation", 660.0, 0.9, 10), + ("interpolation", 750.0, 0.75, 10), + ("interpolation", 840.0, 0.6, 10), + ("interpolation", 295.0, 0.5, 10), + ("interpolation", 990.0, 0.5, 100), ] ) -def test_interpolation(model, method, temperature, fission_expected): - model.settings.temperature = {'method': method, 'default': temperature} +def test_interpolation(model, method, temperature, fission_expected, tolerance): + model.settings.temperature = {'method': method, 'default': temperature, "tolerance": tolerance} sp_filename = model.run() with openmc.StatePoint(sp_filename) as sp: t = sp.tallies[model.tallies[0].id] @@ -152,3 +218,34 @@ def test_interpolation(model, method, temperature, fission_expected): assert k.n == pytest.approx(nu*fission_expected) else: assert abs(k.n - nu*fission_expected) <= 3*k.s + + +def test_temperature_interpolation_tolerance(model): + """Test applying global and cell temperatures with thermal scattering libraries + """ + edit_fake_cross_sections() + model.materials[0].add_s_alpha_beta("c_U_fake") + + # Default k-effective, using the thermal scattering data's minimum available temperature + model.settings.temperature = {'method': "nearest", 'default': 294, "tolerance": 50} + sp_filename = model.run() + with openmc.StatePoint(sp_filename) as sp: + default_k = sp.keff.n + + # Get k-effective with temperature below the minimum but in interpolation mode + model.settings.temperature = {'method': "interpolation", 'default': 255, "tolerance": 50} + sp_filename = model.run() + with openmc.StatePoint(sp_filename) as sp: + interpolated_k = sp.keff.n + + # Get the k-effective with the temperature applied to the cell, instead of globally + model.settings.temperature = {'method': "interpolation", 'default': 500, "tolerance": 50} + for cell in model.geometry.get_all_cells().values(): + cell.temperature = 275 + sp_filename = model.run() + with openmc.StatePoint(sp_filename) as sp: + cell_k = sp.keff.n + + # All calculated k-effectives should be equal + assert default_k == pytest.approx(interpolated_k) + assert interpolated_k == pytest.approx(cell_k)