Merge pull request #1023 from amandalund/photon-new

Photon Transport
This commit is contained in:
Paul Romano 2018-08-05 16:04:36 -05:00 committed by GitHub
commit 9fa0ca2b06
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
81 changed files with 33696 additions and 442 deletions

28521
openmc/data/BREMX.DAT Normal file

File diff suppressed because it is too large Load diff

View file

@ -9,12 +9,13 @@ WMP_VERSION = 'v0.2'
from .data import *
from .neutron import *
from .photon import *
from .decay import *
from .reaction import *
from .ace import *
from . import ace
from .angle_distribution import *
from .function import *
from .endf import *
from . import endf
from .energy_distribution import *
from .product import *
from .angle_energy import *

View file

@ -16,13 +16,82 @@ generates ACE-format cross sections.
"""
from os import SEEK_CUR
from pathlib import PurePath
import struct
import sys
import numpy as np
from openmc.mixin import EqualityMixin
from openmc.data.endf import _ENDF_FLOAT_RE
import openmc.checkvalue as cv
from .data import ATOMIC_SYMBOL, gnd_name
from .endf import ENDF_FLOAT_RE
def get_metadata(zaid, metastable_scheme='nndc'):
"""Return basic identifying data for a nuclide with a given ZAID.
Parameters
----------
zaid : int
ZAID (1000*Z + A) obtained from a library
metastable_scheme : {'nndc', 'mcnp'}
Determine how ZAID identifiers are to be interpreted in the case of
a metastable nuclide. Because the normal ZAID (=1000*Z + A) does not
encode metastable information, different conventions are used among
different libraries. In MCNP libraries, the convention is to add 400
for a metastable nuclide except for Am242m, for which 95242 is
metastable and 95642 (or 1095242 in newer libraries) is the ground
state. For NNDC libraries, ZAID is given as 1000*Z + A + 100*m.
Returns
-------
name : str
Name of the table
element : str
The atomic symbol of the isotope in the table; e.g., Zr.
Z : int
Number of protons in the nucleus
mass_number : int
Number of nucleons in the nucleus
metastable : int
Metastable state of the nucleus. A value of zero indicates ground state.
"""
cv.check_type('zaid', zaid, int)
cv.check_value('metastable_scheme', metastable_scheme, ['nndc', 'mcnp'])
Z = zaid // 1000
mass_number = zaid % 1000
if metastable_scheme == 'mcnp':
if zaid > 1000000:
# New SZA format
Z = Z % 1000
if zaid == 1095242:
metastable = 0
else:
metastable = zaid // 1000000
else:
if zaid == 95242:
metastable = 1
elif zaid == 95642:
metastable = 0
else:
metastable = 1 if mass_number > 300 else 0
elif metastable_scheme == 'nndc':
metastable = 1 if mass_number > 300 else 0
while mass_number > 3 * Z:
mass_number -= 100
# Determine name
element = ATOMIC_SYMBOL[Z]
name = gnd_name(Z, mass_number, metastable)
return (name, element, Z, mass_number, metastable)
def ascii_to_binary(ascii_file, binary_file):
"""Convert an ACE file in ASCII format (type 1) to binary format (type 2).
@ -160,7 +229,7 @@ class Library(EqualityMixin):
# Determine whether file is ASCII or binary
try:
fh = open(filename, 'rb')
fh = open(str(filename), 'rb')
# Grab 10 lines of the library
sb = b''.join([fh.readline() for i in range(10)])
@ -349,7 +418,7 @@ class Library(EqualityMixin):
# after it). If it's too short, then we apply the ENDF float regular
# expression. We don't do this by default because it's expensive!
if xss.size != nxs[1] + 1:
datastr = _ENDF_FLOAT_RE.sub(r'\1e\2', datastr)
datastr = ENDF_FLOAT_RE.sub(r'\1e\2', datastr)
xss = np.fromstring(datastr, sep=' ')
assert xss.size == nxs[1] + 1

Binary file not shown.

View file

@ -22,10 +22,31 @@ from .function import Tabulated1D, INTERPOLATION_SCHEME
from openmc.stats.univariate import Uniform, Tabular, Legendre
LIBRARIES = {0: 'ENDF/B', 1: 'ENDF/A', 2: 'JEFF', 3: 'EFF',
4: 'ENDF/B High Energy', 5: 'CENDL', 6: 'JENDL',
31: 'INDL/V', 32: 'INDL/A', 33: 'FENDL', 34: 'IRDF',
35: 'BROND', 36: 'INGDB-90', 37: 'FENDL/A', 41: 'BROND'}
_LIBRARY = {0: 'ENDF/B', 1: 'ENDF/A', 2: 'JEFF', 3: 'EFF',
4: 'ENDF/B High Energy', 5: 'CENDL', 6: 'JENDL',
17: 'TENDL', 18: 'ROSFOND', 21: 'SG-21', 31: 'INDL/V',
32: 'INDL/A', 33: 'FENDL', 34: 'IRDF', 35: 'BROND',
36: 'INGDB-90', 37: 'FENDL/A', 41: 'BROND'}
_SUBLIBRARY = {
0: 'Photo-nuclear data',
1: 'Photo-induced fission product yields',
3: 'Photo-atomic data',
4: 'Radioactive decay data',
5: 'Spontaneous fission product yields',
6: 'Atomic relaxation data',
10: 'Incident-neutron data',
11: 'Neutron-induced fission product yields',
12: 'Thermal neutron scattering data',
19: 'Neutron standards',
113: 'Electro-atomic data',
10010: 'Incident-proton data',
10011: 'Proton-induced fission product yields',
10020: 'Incident-deuteron data',
10030: 'Incident-triton data',
20030: 'Incident-helion (3He) data',
20040: 'Incident-alpha data'
}
SUM_RULES = {1: [2, 3],
3: [4, 5, 11, 16, 17, 22, 23, 24, 25, 27, 28, 29, 30, 32, 33, 34, 35,
@ -45,7 +66,7 @@ SUM_RULES = {1: [2, 3],
106: list(range(750, 800)),
107: list(range(800, 850))}
_ENDF_FLOAT_RE = re.compile(r'([\s\-\+]?\d*\.\d+)([\+\-]\d+)')
ENDF_FLOAT_RE = re.compile(r'([\s\-\+]?\d*\.\d+)([\+\-]\d+)')
def float_endf(s):
@ -68,7 +89,7 @@ def float_endf(s):
The number
"""
return float(_ENDF_FLOAT_RE.sub(r'\1e\2', s))
return float(ENDF_FLOAT_RE.sub(r'\1e\2', s))
def _int_endf(s):
@ -410,6 +431,14 @@ class Evaluation(object):
self._read_header()
def __repr__(self):
if 'zsymam' in self.target:
name = self.target['zsymam'].replace(' ', '')
else:
name = 'Unknown'
return '<{} for {} {}>'.format(self.info['sublibrary'], name,
self.info['library'])
def _read_header(self):
file_obj = io.StringIO(self.section[1, 451])
@ -422,8 +451,7 @@ class Evaluation(object):
self._LRP = items[2]
self.target['fissionable'] = (items[3] == 1)
try:
global LIBRARIES
library = LIBRARIES[items[4]]
library = _LIBRARY[items[4]]
except KeyError:
library = 'Unknown'
self.info['modification'] = items[5]
@ -446,7 +474,7 @@ class Evaluation(object):
self.projectile['mass'] = items[0]
self.info['energy_max'] = items[1]
library_release = items[2]
self.info['sublibrary'] = items[4]
self.info['sublibrary'] = _SUBLIBRARY[items[4]]
library_version = items[5]
self.info['library'] = (library, library_version, library_release)

View file

@ -52,14 +52,17 @@ class DataLibrary(EqualityMixin):
Path to the file to be registered.
"""
h5file = h5py.File(filename, 'r')
with h5py.File(filename, 'r') as h5file:
materials = []
filetype = 'neutron'
for name in h5file:
if name.startswith('c_'):
filetype = 'thermal'
materials.append(name)
materials = []
if 'filetype' in h5file.attrs:
filetype = h5file.attrs['filetype'].decode().lstrip('data_')
else:
filetype = 'neutron'
for name in h5file:
if name.startswith('c_'):
filetype = 'thermal'
materials.append(name)
library = {'path': filename, 'type': filetype, 'materials': materials}
self.libraries.append(library)
@ -81,10 +84,9 @@ class DataLibrary(EqualityMixin):
if common_dir == '':
common_dir = '.'
directory = os.path.relpath(common_dir, os.path.dirname(path))
if directory != '.':
if os.path.relpath(common_dir, os.path.dirname(path)) != '.':
dir_element = ET.SubElement(root, "directory")
dir_element.text = directory
dir_element.text = os.path.realpath(common_dir)
for library in self.libraries:
lib_element = ET.SubElement(root, "library")

View file

@ -14,8 +14,8 @@ import numpy as np
import h5py
from . import HDF5_VERSION, HDF5_VERSION_MAJOR
from .ace import Library, Table, get_table
from .data import ATOMIC_SYMBOL, K_BOLTZMANN, EV_PER_MEV, gnd_name
from .ace import Library, Table, get_table, get_metadata
from .data import ATOMIC_SYMBOL, K_BOLTZMANN, EV_PER_MEV
from .endf import Evaluation, SUM_RULES, get_head_record, get_tab1_record
from .fission_energy import FissionEnergyRelease
from .function import Tabulated1D, Sum, ResonancesWithBackground
@ -34,88 +34,26 @@ from openmc.mixin import EqualityMixin
_RESONANCE_ENERGY_GRID = np.logspace(-3, 3, 61)
def _get_metadata(zaid, metastable_scheme='nndc'):
"""Return basic identifying data for a nuclide with a given ZAID.
Parameters
----------
zaid : int
ZAID (1000*Z + A) obtained from a library
metastable_scheme : {'nndc', 'mcnp'}
Determine how ZAID identifiers are to be interpreted in the case of
a metastable nuclide. Because the normal ZAID (=1000*Z + A) does not
encode metastable information, different conventions are used among
different libraries. In MCNP libraries, the convention is to add 400
for a metastable nuclide except for Am242m, for which 95242 is
metastable and 95642 (or 1095242 in newer libraries) is the ground
state. For NNDC libraries, ZAID is given as 1000*Z + A + 100*m.
Returns
-------
name : str
Name of the table
element : str
The atomic symbol of the isotope in the table; e.g., Zr.
Z : int
Number of protons in the nucleus
mass_number : int
Number of nucleons in the nucleus
metastable : int
Metastable state of the nucleus. A value of zero indicates ground state.
"""
cv.check_type('zaid', zaid, int)
cv.check_value('metastable_scheme', metastable_scheme, ['nndc', 'mcnp'])
Z = zaid // 1000
mass_number = zaid % 1000
if metastable_scheme == 'mcnp':
if zaid > 1000000:
# New SZA format
Z = Z % 1000
if zaid == 1095242:
metastable = 0
else:
metastable = zaid // 1000000
else:
if zaid == 95242:
metastable = 1
elif zaid == 95642:
metastable = 0
else:
metastable = 1 if mass_number > 300 else 0
elif metastable_scheme == 'nndc':
metastable = 1 if mass_number > 300 else 0
while mass_number > 3 * Z:
mass_number -= 100
# Determine name
element = ATOMIC_SYMBOL[Z]
name = gnd_name(Z, mass_number, metastable)
return (name, element, Z, mass_number, metastable)
class IncidentNeutron(EqualityMixin):
"""Continuous-energy neutron interaction data.
Instances of this class are not normally instantiated by the user but rather
created using the factory methods :meth:`IncidentNeutron.from_hdf5` and
:meth:`IncidentNeutron.from_ace`.
This class stores data derived from an ENDF-6 format neutron interaction
sublibrary. Instances of this class are not normally instantiated by the
user but rather created using the factory methods
:meth:`IncidentNeutron.from_hdf5`, :meth:`IncidentNeutron.from_ace`, and
:meth:`IncidentNeutron.from_endf`.
Parameters
----------
name : str
Name of the nuclide using the GND naming convention
atomic_number : int
Number of protons in the nucleus
Number of protons in the target nucleus
mass_number : int
Number of nucleons in the nucleus
Number of nucleons in the target nucleus
metastable : int
Metastable state of the nucleus. A value of zero indicates ground state.
Metastable state of the target nucleus. A value of zero indicates ground
state.
atomic_weight_ratio : float
Atomic mass ratio of the target nuclide.
kTs : Iterable of float
@ -125,22 +63,19 @@ class IncidentNeutron(EqualityMixin):
Attributes
----------
atomic_number : int
Number of protons in the nucleus
Number of protons in the target nucleus
atomic_symbol : str
Atomic symbol of the nuclide, e.g., 'Zr'
atomic_weight_ratio : float
Atomic weight ratio of the target nuclide.
energy : dict of numpy.ndarray
The energy values (eV) at which reaction cross-sections are tabulated.
They keys of the dict are the temperature string ('294K') for each
set of energies
fission_energy : None or openmc.data.FissionEnergyRelease
The energy released by fission, tabulated by component (e.g. prompt
neutrons or beta particles) and dependent on incident neutron energy
mass_number : int
Number of nucleons in the nucleus
Number of nucleons in the target nucleus
metastable : int
Metastable state of the nucleus. A value of zero indicates ground state.
Metastable state of the target nucleus. A value of zero indicates ground
state.
name : str
Name of the nuclide using the GND naming convention
reactions : collections.OrderedDict
@ -512,6 +447,7 @@ class IncidentNeutron(EqualityMixin):
# Open file and write version
f = h5py.File(path, mode, libver=libver)
f.attrs['filetype'] = np.string_('data_neutron')
f.attrs['version'] = np.array(HDF5_VERSION)
# Write basic data
@ -686,7 +622,7 @@ class IncidentNeutron(EqualityMixin):
# If mass number hasn't been specified, make an educated guess
zaid, xs = ace.name.split('.')
name, element, Z, mass_number, metastable = \
_get_metadata(int(zaid), metastable_scheme)
get_metadata(int(zaid), metastable_scheme)
# Assign temperature to the running list
kTs = [ace.temperature*EV_PER_MEV]

1005
openmc/data/photon.py Normal file

File diff suppressed because it is too large Load diff

View file

@ -1093,7 +1093,7 @@ class Reaction(EqualityMixin):
ev : openmc.data.endf.Evaluation
ENDF evaluation
mt : int
The MT value of the reaction to get angular distributions for
The MT value of the reaction to get data for
Returns
-------

Binary file not shown.

View file

@ -279,6 +279,7 @@ class ThermalScattering(EqualityMixin):
"""
# Open file and write version
f = h5py.File(path, mode, libver=libver)
f.attrs['filetype'] = np.string_('data_thermal')
f.attrs['version'] = np.array(HDF5_VERSION)
# Write basic data