From b789f37fad14bddfe5d71ea801a953574104ebe5 Mon Sep 17 00:00:00 2001 From: "matteo.zammataro" Date: Thu, 9 Jan 2025 17:30:56 +0100 Subject: [PATCH] Add ambient dose coefficients (H*(10)) from ICRP74 --- openmc/data/__init__.py | 3 +- openmc/data/ambient_dose/__init__.py | 0 openmc/data/ambient_dose/dose.py | 73 +++++++++++++++++++ openmc/data/ambient_dose/icrp74/neutrons.txt | 50 +++++++++++++ openmc/data/ambient_dose/icrp74/photons.txt | 28 +++++++ openmc/data/effective_dose/dose.py | 2 +- pyproject.toml | 1 + tests/unit_tests/test_data_ambient_dose.py | 24 ++++++ ...ta_dose.py => test_data_effective_dose.py} | 18 ++--- 9 files changed, 188 insertions(+), 11 deletions(-) create mode 100644 openmc/data/ambient_dose/__init__.py create mode 100644 openmc/data/ambient_dose/dose.py create mode 100644 openmc/data/ambient_dose/icrp74/neutrons.txt create mode 100644 openmc/data/ambient_dose/icrp74/photons.txt create mode 100644 tests/unit_tests/test_data_ambient_dose.py rename tests/unit_tests/{test_data_dose.py => test_data_effective_dose.py} (64%) diff --git a/openmc/data/__init__.py b/openmc/data/__init__.py index c2d35565a8a..fec031da640 100644 --- a/openmc/data/__init__.py +++ b/openmc/data/__init__.py @@ -34,4 +34,5 @@ from .grid import * from .function import * -from .effective_dose.dose import dose_coefficients +from .effective_dose.dose import effective_dose_coefficients +from .ambient_dose.dose import ambient_dose_coefficients diff --git a/openmc/data/ambient_dose/__init__.py b/openmc/data/ambient_dose/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/openmc/data/ambient_dose/dose.py b/openmc/data/ambient_dose/dose.py new file mode 100644 index 00000000000..449d9227e12 --- /dev/null +++ b/openmc/data/ambient_dose/dose.py @@ -0,0 +1,73 @@ +from pathlib import Path + +import numpy as np + +import openmc.checkvalue as cv + +_FILES = { + ('icrp74', 'neutron'): Path('icrp74') / 'neutrons.txt', + ('icrp74', 'photon'): Path('icrp74') / 'photons.txt', +} + +_DOSE_TABLES = {} + + +def _load_dose_icrp(data_source: str, particle: str): + """Load effective dose tables from text files. + + Parameters + ---------- + data_source : {'icrp74'} + The dose conversion data source to use + particle : {'neutron', 'photon'} + Incident particle + + """ + path = Path(__file__).parent / _FILES[data_source, particle] + data = np.loadtxt(path, skiprows=3, encoding='utf-8') + data[:, 0] *= 1e6 # Change energies to eV + _DOSE_TABLES[data_source, particle] = data + + +def ambient_dose_coefficients(particle, data_source='icrp74'): + """Return effective dose conversion coefficients. + + This function provides fluence to ambient dose + (H*(10)) conversion coefficients for various types of external exposures + based on values in ICRP publications. Corrected values found in a + corrigendum are used rather than the values in the original report. + Available libraries include `ICRP Publication 74 + ` and `ICRP Publication 116 + `. + + Parameters + ---------- + particle : {'neutron', 'photon'} + Incident particle + data_source : {'icrp74'} + The data source for the effective dose conversion coefficients. + + Returns + ------- + energy : numpy.ndarray + Energies at which dose conversion coefficients are given + dose_coeffs : numpy.ndarray + Effective dose coefficients in [pSv cm^2] at provided energies. For + 'photon kerma', the coefficients are given in [Sv/Gy]. + + """ + + cv.check_value('data_source', data_source, {'icrp74'}) + + if (data_source, particle) not in _FILES: + raise ValueError(f"{particle} has no dose data in data source {data_source}.") + elif (data_source, particle) not in _DOSE_TABLES: + _load_dose_icrp(data_source, particle) + + # Get all data for selected particle + data = _DOSE_TABLES[data_source, particle] + + # Pull out energy and dose from table + energy = data[:, 0].copy() + dose_coeffs = data[:, 1].copy() + return energy, dose_coeffs diff --git a/openmc/data/ambient_dose/icrp74/neutrons.txt b/openmc/data/ambient_dose/icrp74/neutrons.txt new file mode 100644 index 00000000000..fe0036cbc9c --- /dev/null +++ b/openmc/data/ambient_dose/icrp74/neutrons.txt @@ -0,0 +1,50 @@ +Neutrons: Ambient per fluence, in units of pSv cm², for monoenergetic particles incident. + +Energy (MeV) Dose + 1.00E-09 6.60 + 1.00E-08 9.00 + 2.53E-08 10.6 + 1.00E-07 12.9 + 2.00E-07 13.5 + 5.00E-07 13.6 + 1.00E-06 13.3 + 2.00E-06 12.9 + 5.00E-06 12.0 + 1.00E-05 11.3 + 2.00E-05 10.6 + 5.00E-05 9.90 + 1.00E-04 9.40 + 2.00E-04 8.90 + 5.00E-04 8.30 + 1.00E-03 7.90 + 2.00E-03 7.70 + 5.00E-03 8.00 + 1.00E-02 10.5 + 2.00E-02 16.6 + 3.00E-02 23.7 + 5.00E-02 41.1 + 7.00E-02 60.0 + 1.00E-01 88.0 + 1.50E-01 132 + 2.00E-01 170 + 3.00E-01 233 + 5.00E-01 322 + 7.00E-01 375 + 9.00E-01 400 + 1 416 + 1.2 425 + 2 420 + 3 412 + 4 408 + 5 405 + 6 400 + 7 405 + 8 409 + 9 420 + 10 440 + 12 480 + 14 520 + 15 540 + 16 555 + 18 570 + 20 600 \ No newline at end of file diff --git a/openmc/data/ambient_dose/icrp74/photons.txt b/openmc/data/ambient_dose/icrp74/photons.txt new file mode 100644 index 00000000000..66031b2f0e9 --- /dev/null +++ b/openmc/data/ambient_dose/icrp74/photons.txt @@ -0,0 +1,28 @@ +Photons: Ambient dose (H*10) per fluence, in units of pSv cm² + +Energy (MeV) Dose +0.010 0.061 +0.015 0.83 +0.020 1.05 +0.030 0.81 +0.040 0.64 +0.050 0.55 +0.060 0.51 +0.080 0.53 +0.100 0.61 +0.150 0.89 +0.200 1.20 +0.300 1.80 +0.400 2.38 +0.500 2.93 +0.600 3.44 +0.800 4.38 +1 5.20 +1.5 6.90 +2 8.60 +3 11.1 +4 13.4 +5 15.5 +6 17.6 +8 21.6 +10 25.6 \ No newline at end of file diff --git a/openmc/data/effective_dose/dose.py b/openmc/data/effective_dose/dose.py index c7f458d1c6c..01c33b89039 100644 --- a/openmc/data/effective_dose/dose.py +++ b/openmc/data/effective_dose/dose.py @@ -40,7 +40,7 @@ def _load_dose_icrp(data_source: str, particle: str): _DOSE_TABLES[data_source, particle] = data -def dose_coefficients(particle, geometry='AP', data_source='icrp116'): +def effective_dose_coefficients(particle, geometry='AP', data_source='icrp116'): """Return effective dose conversion coefficients. This function provides fluence (and air kerma) to effective or ambient dose diff --git a/pyproject.toml b/pyproject.toml index e4e8472f1aa..e5b885d45bb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,6 +64,7 @@ exclude = ['tests*'] [tool.setuptools.package-data] "openmc.data.effective_dose" = ["**/*.txt"] +"openmc.data.ambient_dose" = ["**/*.txt"] "openmc.data" = ["*.txt", "*.DAT", "*.json", "*.h5"] "openmc.lib" = ["libopenmc.dylib", "libopenmc.so"] diff --git a/tests/unit_tests/test_data_ambient_dose.py b/tests/unit_tests/test_data_ambient_dose.py new file mode 100644 index 00000000000..7fc4ce1be9c --- /dev/null +++ b/tests/unit_tests/test_data_ambient_dose.py @@ -0,0 +1,24 @@ +from openmc.data import ambient_dose_coefficients +from pytest import approx, raises + + +def test_dose_coefficients(): + # Spot checks on values from ICRP tables + + energy, dose = ambient_dose_coefficients('photon', data_source='icrp74') + assert energy[0] == approx(0.01e6) + assert dose[0] == approx(0.061) + assert energy[-1] == approx(10.0e6) + assert dose[-1] == approx(25.6) + + energy, dose = ambient_dose_coefficients('neutron', data_source='icrp74') + assert energy[0] == approx(1e-3) + assert dose[0] == approx(6.60) + assert energy[-1] == approx(20.0e6) + assert dose[-1] == approx(600) + + # Invalid particle/data source should raise an exception + with raises(ValueError): + ambient_dose_coefficients('slime', 'icrp74') + with raises(ValueError): + ambient_dose_coefficients('neutron', data_source='icrp7000') diff --git a/tests/unit_tests/test_data_dose.py b/tests/unit_tests/test_data_effective_dose.py similarity index 64% rename from tests/unit_tests/test_data_dose.py rename to tests/unit_tests/test_data_effective_dose.py index 2d80cf8384f..8ed57ff63e3 100644 --- a/tests/unit_tests/test_data_dose.py +++ b/tests/unit_tests/test_data_effective_dose.py @@ -1,34 +1,34 @@ -from openmc.data import dose_coefficients +from openmc.data import effective_dose_coefficients from pytest import approx, raises def test_dose_coefficients(): # Spot checks on values from ICRP tables - energy, dose = dose_coefficients('photon', 'AP') + energy, dose = effective_dose_coefficients('photon', 'AP') assert energy[0] == approx(0.01e6) assert dose[0] == approx(0.0685) assert energy[-1] == approx(10e9) assert dose[-1] == approx(90.4) # updated in corrigendum - energy, dose = dose_coefficients('neutron', 'LLAT') + energy, dose = effective_dose_coefficients('neutron', 'LLAT') assert energy[0] == approx(1e-3) assert dose[0] == approx(1.04) assert energy[-1] == approx(10e9) assert dose[-1] == approx(1.23e3) - energy, dose = dose_coefficients('electron', 'ISO') + energy, dose = effective_dose_coefficients('electron', 'ISO') assert energy[0] == approx(0.01e6) assert dose[0] == approx(0.0188) assert energy[-1] == approx(10e9) assert dose[-1] == approx(699.0) - energy, dose = dose_coefficients('photon', data_source='icrp74') + energy, dose = effective_dose_coefficients('photon', data_source='icrp74') assert energy[0] == approx(0.01e6) assert dose[0] == approx(7.43*0.00653) assert energy[-1] == approx(10.0e6) assert dose[-1] == approx(24.0*0.990) - energy, dose = dose_coefficients('neutron', 'LLAT', data_source='icrp74') + energy, dose = effective_dose_coefficients('neutron', 'LLAT', data_source='icrp74') assert energy[0] == approx(1e-3) assert dose[0] == approx(1.68) assert energy[-1] == approx(20.0e6) @@ -36,8 +36,8 @@ def test_dose_coefficients(): # Invalid particle/geometry should raise an exception with raises(ValueError): - dose_coefficients('slime', 'LAT') + effective_dose_coefficients('slime', 'LAT') with raises(ValueError): - dose_coefficients('neutron', 'ZZ') + effective_dose_coefficients('neutron', 'ZZ') with raises(ValueError): - dose_coefficients('neutron', data_source='icrp7000') + effective_dose_coefficients('neutron', data_source='icrp7000')