mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 05:35:49 -04:00
Merge pull request #1205 from liangjg/refactor-photon
Add from_hdf5() in `openmc.data.IncidentPhoton`
This commit is contained in:
commit
8e7bf4b186
26 changed files with 488 additions and 294 deletions
|
|
@ -115,7 +115,7 @@ class AngleDistribution(EqualityMixin):
|
|||
Angular distribution
|
||||
|
||||
"""
|
||||
energy = group['energy'].value
|
||||
energy = group['energy'][()]
|
||||
data = group['mu']
|
||||
offsets = data.attrs['offsets']
|
||||
interpolation = data.attrs['interpolation']
|
||||
|
|
|
|||
|
|
@ -210,15 +210,15 @@ class CorrelatedAngleEnergy(AngleEnergy):
|
|||
interp_data = group['energy'].attrs['interpolation']
|
||||
energy_breakpoints = interp_data[0, :]
|
||||
energy_interpolation = interp_data[1, :]
|
||||
energy = group['energy'].value
|
||||
energy = group['energy'][()]
|
||||
|
||||
offsets = group['energy_out'].attrs['offsets']
|
||||
interpolation = group['energy_out'].attrs['interpolation']
|
||||
n_discrete_lines = group['energy_out'].attrs['n_discrete_lines']
|
||||
dset_eout = group['energy_out'].value
|
||||
dset_eout = group['energy_out'][()]
|
||||
energy_out = []
|
||||
|
||||
dset_mu = group['mu'].value
|
||||
dset_mu = group['mu'][()]
|
||||
mu = []
|
||||
|
||||
n_energy = len(energy)
|
||||
|
|
|
|||
|
|
@ -1144,7 +1144,7 @@ class ContinuousTabular(EnergyDistribution):
|
|||
interp_data = group['energy'].attrs['interpolation']
|
||||
energy_breakpoints = interp_data[0, :]
|
||||
energy_interpolation = interp_data[1, :]
|
||||
energy = group['energy'].value
|
||||
energy = group['energy'][()]
|
||||
|
||||
data = group['distribution']
|
||||
offsets = data.attrs['offsets']
|
||||
|
|
|
|||
|
|
@ -349,8 +349,8 @@ class Tabulated1D(Function1D):
|
|||
raise ValueError("Expected an HDF5 attribute 'type' equal to '"
|
||||
+ cls.__name__ + "'")
|
||||
|
||||
x = dataset.value[0, :]
|
||||
y = dataset.value[1, :]
|
||||
x = dataset[0, :]
|
||||
y = dataset[1, :]
|
||||
breakpoints = dataset.attrs['breakpoints']
|
||||
interpolation = dataset.attrs['interpolation']
|
||||
return cls(x, y, breakpoints, interpolation)
|
||||
|
|
@ -434,7 +434,7 @@ class Polynomial(np.polynomial.Polynomial, Function1D):
|
|||
if dataset.attrs['type'].decode() != cls.__name__:
|
||||
raise ValueError("Expected an HDF5 attribute 'type' equal to '"
|
||||
+ cls.__name__ + "'")
|
||||
return cls(dataset.value)
|
||||
return cls(dataset[()])
|
||||
|
||||
|
||||
class Combination(EqualityMixin):
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ class KalbachMann(AngleEnergy):
|
|||
interp_data = group['energy'].attrs['interpolation']
|
||||
energy_breakpoints = interp_data[0, :]
|
||||
energy_interpolation = interp_data[1, :]
|
||||
energy = group['energy'].value
|
||||
energy = group['energy'][()]
|
||||
|
||||
data = group['distribution']
|
||||
offsets = data.attrs['offsets']
|
||||
|
|
|
|||
|
|
@ -356,24 +356,24 @@ class WindowedMultipole(EqualityMixin):
|
|||
|
||||
# Read scalars.
|
||||
|
||||
out.spacing = group['spacing'].value
|
||||
out.sqrtAWR = group['sqrtAWR'].value
|
||||
out.E_min = group['E_min'].value
|
||||
out.E_max = group['E_max'].value
|
||||
out.spacing = group['spacing'][()]
|
||||
out.sqrtAWR = group['sqrtAWR'][()]
|
||||
out.E_min = group['E_min'][()]
|
||||
out.E_max = group['E_max'][()]
|
||||
|
||||
# Read arrays.
|
||||
|
||||
err = "WMP '{}' array shape is not consistent with the '{}' array shape"
|
||||
|
||||
out.data = group['data'].value
|
||||
out.data = group['data'][()]
|
||||
|
||||
out.windows = group['windows'].value
|
||||
out.windows = group['windows'][()]
|
||||
|
||||
out.broaden_poly = group['broaden_poly'].value.astype(np.bool)
|
||||
out.broaden_poly = group['broaden_poly'][...].astype(np.bool)
|
||||
if out.broaden_poly.shape[0] != out.windows.shape[0]:
|
||||
raise ValueError(err.format('broaden_poly', 'windows'))
|
||||
|
||||
out.curvefit = group['curvefit'].value
|
||||
out.curvefit = group['curvefit'][()]
|
||||
if out.curvefit.shape[0] != out.windows.shape[0]:
|
||||
raise ValueError(err.format('curvefit', 'windows'))
|
||||
|
||||
|
|
|
|||
|
|
@ -521,7 +521,7 @@ class IncidentNeutron(EqualityMixin):
|
|||
kTg = group['kTs']
|
||||
kTs = []
|
||||
for temp in kTg:
|
||||
kTs.append(kTg[temp].value)
|
||||
kTs.append(kTg[temp][()])
|
||||
|
||||
data = cls(name, atomic_number, mass_number, metastable,
|
||||
atomic_weight_ratio, kTs)
|
||||
|
|
|
|||
|
|
@ -19,71 +19,62 @@ from .endf import Evaluation, get_head_record, get_tab1_record, get_list_record
|
|||
from .function import Tabulated1D
|
||||
|
||||
|
||||
_SUBSHELLS = ['K', 'L1', 'L2', 'L3', 'M1', 'M2', 'M3', 'M4', 'M5',
|
||||
'N1', 'N2', 'N3', 'N4', 'N5', 'N6', 'N7', 'O1', 'O2',
|
||||
'O3', 'O4', 'O5', 'O6', 'O7', 'O8', 'O9', 'P1', 'P2',
|
||||
'P3', 'P4', 'P5', 'P6', 'P7', 'P8', 'P9', 'P10', 'P11',
|
||||
'Q1', 'Q2', 'Q3']
|
||||
|
||||
|
||||
# Helper function to map designator to subshell string or None
|
||||
def _subshell(i):
|
||||
if i == 0:
|
||||
return None
|
||||
else:
|
||||
return _SUBSHELLS[i - 1]
|
||||
|
||||
# Electron subshell labels
|
||||
_SUBSHELLS = [None, 'K', 'L1', 'L2', 'L3', 'M1', 'M2', 'M3', 'M4', 'M5',
|
||||
'N1', 'N2', 'N3', 'N4', 'N5', 'N6', 'N7', 'O1', 'O2', 'O3',
|
||||
'O4', 'O5', 'O6', 'O7', 'O8', 'O9', 'P1', 'P2', 'P3', 'P4',
|
||||
'P5', 'P6', 'P7', 'P8', 'P9', 'P10', 'P11','Q1', 'Q2', 'Q3']
|
||||
|
||||
_REACTION_NAME = {
|
||||
501: 'Total photon interaction',
|
||||
502: 'Photon coherent scattering',
|
||||
504: 'Photon incoherent scattering',
|
||||
515: 'Pair production, electron field',
|
||||
516: 'Total pair production',
|
||||
517: 'Pair production, nuclear field',
|
||||
522: 'Photoelectric absorption',
|
||||
526: 'Electro-atomic scattering',
|
||||
527: 'Electro-atomic bremsstrahlung',
|
||||
528: 'Electro-atomic excitation',
|
||||
534: 'K (1s1/2) subshell photoelectric',
|
||||
535: 'L1 (2s1/2) subshell photoelectric',
|
||||
536: 'L2 (2p1/2) subshell photoelectric',
|
||||
537: 'L3 (2p3/2) subshell photoelectric',
|
||||
538: 'M1 (3s1/2) subshell photoelectric',
|
||||
539: 'M2 (3p1/2) subshell photoelectric',
|
||||
540: 'M3 (3p3/2) subshell photoelectric',
|
||||
541: 'M4 (3d3/2) subshell photoelectric',
|
||||
542: 'M5 (3d5/2) subshell photoelectric',
|
||||
543: 'N1 (4s1/2) subshell photoelectric',
|
||||
544: 'N2 (4p1/2) subshell photoelectric',
|
||||
545: 'N3 (4p3/2) subshell photoelectric',
|
||||
546: 'N4 (4d3/2) subshell photoelectric',
|
||||
547: 'N5 (4d5/2) subshell photoelectric',
|
||||
548: 'N6 (4f5/2) subshell photoelectric',
|
||||
549: 'N7 (4f7/2) subshell photoelectric',
|
||||
550: 'O1 (5s1/2) subshell photoelectric',
|
||||
551: 'O2 (5p1/2) subshell photoelectric',
|
||||
552: 'O3 (5p3/2) subshell photoelectric',
|
||||
553: 'O4 (5d3/2) subshell photoelectric',
|
||||
554: 'O5 (5d5/2) subshell photoelectric',
|
||||
555: 'O6 (5f5/2) subshell photoelectric',
|
||||
556: 'O7 (5f7/2) subshell photoelectric',
|
||||
557: 'O8 (5g7/2) subshell photoelectric',
|
||||
558: 'O9 (5g9/2) subshell photoelectric',
|
||||
559: 'P1 (6s1/2) subshell photoelectric',
|
||||
560: 'P2 (6p1/2) subshell photoelectric',
|
||||
561: 'P3 (6p3/2) subshell photoelectric',
|
||||
562: 'P4 (6d3/2) subshell photoelectric',
|
||||
563: 'P5 (6d5/2) subshell photoelectric',
|
||||
564: 'P6 (6f5/2) subshell photoelectric',
|
||||
565: 'P7 (6f7/2) subshell photoelectric',
|
||||
566: 'P8 (6g7/2) subshell photoelectric',
|
||||
567: 'P9 (6g9/2) subshell photoelectric',
|
||||
568: 'P10 (6h9/2) subshell photoelectric',
|
||||
569: 'P11 (6h11/2) subshell photoelectric',
|
||||
570: 'Q1 (7s1/2) subshell photoelectric',
|
||||
571: 'Q2 (7p1/2) subshell photoelectric',
|
||||
572: 'Q3 (7p3/2) subshell photoelectric'
|
||||
501: ('Total photon interaction', 'total'),
|
||||
502: ('Photon coherent scattering', 'coherent'),
|
||||
504: ('Photon incoherent scattering', 'incoherent'),
|
||||
515: ('Pair production, electron field', 'pair_production_electron'),
|
||||
516: ('Total pair production', 'pair_production_total'),
|
||||
517: ('Pair production, nuclear field', 'pair_production_nuclear'),
|
||||
522: ('Photoelectric absorption', 'photoelectric'),
|
||||
526: ('Electro-atomic scattering', 'electro_atomic_scat'),
|
||||
527: ('Electro-atomic bremsstrahlung', 'electro_atomic_brem'),
|
||||
528: ('Electro-atomic excitation', 'electro_atomic_excit'),
|
||||
534: ('K (1s1/2) subshell photoelectric', 'K'),
|
||||
535: ('L1 (2s1/2) subshell photoelectric', 'L1'),
|
||||
536: ('L2 (2p1/2) subshell photoelectric', 'L2'),
|
||||
537: ('L3 (2p3/2) subshell photoelectric', 'L3'),
|
||||
538: ('M1 (3s1/2) subshell photoelectric', 'M1'),
|
||||
539: ('M2 (3p1/2) subshell photoelectric', 'M2'),
|
||||
540: ('M3 (3p3/2) subshell photoelectric', 'M3'),
|
||||
541: ('M4 (3d3/2) subshell photoelectric', 'M4'),
|
||||
542: ('M5 (3d5/2) subshell photoelectric', 'M5'),
|
||||
543: ('N1 (4s1/2) subshell photoelectric', 'N1'),
|
||||
544: ('N2 (4p1/2) subshell photoelectric', 'N2'),
|
||||
545: ('N3 (4p3/2) subshell photoelectric', 'N3'),
|
||||
546: ('N4 (4d3/2) subshell photoelectric', 'N4'),
|
||||
547: ('N5 (4d5/2) subshell photoelectric', 'N5'),
|
||||
548: ('N6 (4f5/2) subshell photoelectric', 'N6'),
|
||||
549: ('N7 (4f7/2) subshell photoelectric', 'N7'),
|
||||
550: ('O1 (5s1/2) subshell photoelectric', 'O1'),
|
||||
551: ('O2 (5p1/2) subshell photoelectric', 'O2'),
|
||||
552: ('O3 (5p3/2) subshell photoelectric', 'O3'),
|
||||
553: ('O4 (5d3/2) subshell photoelectric', 'O4'),
|
||||
554: ('O5 (5d5/2) subshell photoelectric', 'O5'),
|
||||
555: ('O6 (5f5/2) subshell photoelectric', 'O6'),
|
||||
556: ('O7 (5f7/2) subshell photoelectric', 'O7'),
|
||||
557: ('O8 (5g7/2) subshell photoelectric', 'O8'),
|
||||
558: ('O9 (5g9/2) subshell photoelectric', 'O9'),
|
||||
559: ('P1 (6s1/2) subshell photoelectric', 'P1'),
|
||||
560: ('P2 (6p1/2) subshell photoelectric', 'P2'),
|
||||
561: ('P3 (6p3/2) subshell photoelectric', 'P3'),
|
||||
562: ('P4 (6d3/2) subshell photoelectric', 'P4'),
|
||||
563: ('P5 (6d5/2) subshell photoelectric', 'P5'),
|
||||
564: ('P6 (6f5/2) subshell photoelectric', 'P6'),
|
||||
565: ('P7 (6f7/2) subshell photoelectric', 'P7'),
|
||||
566: ('P8 (6g7/2) subshell photoelectric', 'P8'),
|
||||
567: ('P9 (6g9/2) subshell photoelectric', 'P9'),
|
||||
568: ('P10 (6h9/2) subshell photoelectric', 'P10'),
|
||||
569: ('P11 (6h11/2) subshell photoelectric', 'P11'),
|
||||
570: ('Q1 (7s1/2) subshell photoelectric', 'Q1'),
|
||||
571: ('Q2 (7p1/2) subshell photoelectric', 'Q2'),
|
||||
572: ('Q3 (7p3/2) subshell photoelectric', 'Q3')
|
||||
}
|
||||
|
||||
# Compton profiles are read from a pre-generated HDF5 file when they are first
|
||||
|
|
@ -225,7 +216,7 @@ class AtomicRelaxation(EqualityMixin):
|
|||
# Get shell designators
|
||||
n = ace.nxs[7]
|
||||
idx = ace.jxs[11]
|
||||
shells = [_subshell(int(i)) for i in ace.xss[idx : idx+n]]
|
||||
shells = [_SUBSHELLS[int(i)] for i in ace.xss[idx : idx+n]]
|
||||
|
||||
# Get number of electrons for each shell
|
||||
idx = ace.jxs[12]
|
||||
|
|
@ -245,8 +236,8 @@ class AtomicRelaxation(EqualityMixin):
|
|||
if n_transitions > 0:
|
||||
records = []
|
||||
for j in range(n_transitions):
|
||||
subj = _subshell(int(ace.xss[idx]))
|
||||
subk = _subshell(int(ace.xss[idx + 1]))
|
||||
subj = _SUBSHELLS[int(ace.xss[idx])]
|
||||
subk = _SUBSHELLS[int(ace.xss[idx + 1])]
|
||||
etr = ace.xss[idx + 2]*EV_PER_MEV
|
||||
if j == 0:
|
||||
ftr = ace.xss[idx + 3]
|
||||
|
|
@ -301,7 +292,7 @@ class AtomicRelaxation(EqualityMixin):
|
|||
# Read data for each subshell
|
||||
for i in range(n_subshells):
|
||||
params, list_items = get_list_record(file_obj)
|
||||
subi = _subshell(int(params[0]))
|
||||
subi = _SUBSHELLS[int(params[0])]
|
||||
n_transitions = int(params[5])
|
||||
binding_energy[subi] = list_items[0]
|
||||
num_electrons[subi] = list_items[1]
|
||||
|
|
@ -310,8 +301,8 @@ class AtomicRelaxation(EqualityMixin):
|
|||
# Read transition data
|
||||
records = []
|
||||
for j in range(n_transitions):
|
||||
subj = _subshell(int(list_items[6*(j+1)]))
|
||||
subk = _subshell(int(list_items[6*(j+1) + 1]))
|
||||
subj = _SUBSHELLS[int(list_items[6*(j+1)])]
|
||||
subk = _SUBSHELLS[int(list_items[6*(j+1) + 1])]
|
||||
etr = list_items[6*(j+1) + 2]
|
||||
ftr = list_items[6*(j+1) + 3]
|
||||
records.append((subj, subk, etr, ftr))
|
||||
|
|
@ -323,8 +314,70 @@ class AtomicRelaxation(EqualityMixin):
|
|||
# Return instance of class
|
||||
return cls(binding_energy, num_electrons, transitions)
|
||||
|
||||
def to_hdf5(self, group):
|
||||
raise NotImplementedError
|
||||
@classmethod
|
||||
def from_hdf5(cls, group):
|
||||
"""Generate atomic relaxation data from an HDF5 group
|
||||
|
||||
Parameters
|
||||
----------
|
||||
group : h5py.Group
|
||||
HDF5 group to read from
|
||||
|
||||
Returns
|
||||
-------
|
||||
openmc.data.AtomicRelaxation
|
||||
Atomic relaxation data
|
||||
|
||||
"""
|
||||
# Create data dictionaries
|
||||
binding_energy = {}
|
||||
num_electrons = {}
|
||||
transitions = {}
|
||||
|
||||
designators = [s.decode() for s in group.attrs['designators']]
|
||||
columns = ['secondary', 'tertiary', 'energy (eV)', 'probability']
|
||||
for shell in designators:
|
||||
# Shell group
|
||||
sub_group = group[shell]
|
||||
|
||||
# Read subshell binding energy and number of electrons
|
||||
if 'binding_energy' in sub_group.attrs:
|
||||
binding_energy[shell] = sub_group.attrs['binding_energy']
|
||||
if 'num_electrons' in sub_group.attrs:
|
||||
num_electrons[shell] = sub_group.attrs['num_electrons']
|
||||
|
||||
# Read transition data
|
||||
if 'transitions' in sub_group:
|
||||
df = pd.DataFrame(sub_group['transitions'][()],
|
||||
columns=columns)
|
||||
# Replace float indexes back to subshell strings
|
||||
df[columns[:2]] = df[columns[:2]].replace(
|
||||
np.arange(float(len(_SUBSHELLS))), _SUBSHELLS)
|
||||
transitions[shell] = df
|
||||
|
||||
return cls(binding_energy, num_electrons, transitions)
|
||||
|
||||
def to_hdf5(self, group, shell):
|
||||
"""Write atomic relaxation data to an HDF5 group
|
||||
|
||||
Parameters
|
||||
----------
|
||||
group : h5py.Group
|
||||
HDF5 group to write to
|
||||
shell : str
|
||||
The subshell to write data for
|
||||
|
||||
"""
|
||||
|
||||
# Write subshell binding energy and number of electrons
|
||||
group.attrs['binding_energy'] = self.binding_energy[shell]
|
||||
group.attrs['num_electrons'] = self.num_electrons[shell]
|
||||
|
||||
# Write transition data with replacements
|
||||
if shell in self.transitions:
|
||||
df = self.transitions[shell].replace(
|
||||
_SUBSHELLS, range(len(_SUBSHELLS)))
|
||||
group.create_dataset('transitions', data=df.values.astype(float))
|
||||
|
||||
|
||||
class IncidentPhoton(EqualityMixin):
|
||||
|
|
@ -509,7 +562,7 @@ class IncidentPhoton(EqualityMixin):
|
|||
idx += n_energy
|
||||
|
||||
# Copy binding energy
|
||||
shell = _subshell(d)
|
||||
shell = _SUBSHELLS[d]
|
||||
e = data.atomic_relaxation.binding_energy[shell]
|
||||
rx.subshell_binding_energy = e
|
||||
|
||||
|
|
@ -558,12 +611,12 @@ class IncidentPhoton(EqualityMixin):
|
|||
if not _COMPTON_PROFILES:
|
||||
filename = os.path.join(os.path.dirname(__file__), 'compton_profiles.h5')
|
||||
with h5py.File(filename, 'r') as f:
|
||||
_COMPTON_PROFILES['pz'] = f['pz'].value
|
||||
_COMPTON_PROFILES['pz'] = f['pz'][()]
|
||||
for i in range(1, 101):
|
||||
group = f['{:03}'.format(i)]
|
||||
num_electrons = group['num_electrons'].value
|
||||
binding_energy = group['binding_energy'].value*EV_PER_MEV
|
||||
J = group['J'].value
|
||||
num_electrons = group['num_electrons'][()]
|
||||
binding_energy = group['binding_energy'][()]*EV_PER_MEV
|
||||
J = group['J'][()]
|
||||
_COMPTON_PROFILES[i] = {'num_electrons': num_electrons,
|
||||
'binding_energy': binding_energy,
|
||||
'J': J}
|
||||
|
|
@ -580,6 +633,89 @@ class IncidentPhoton(EqualityMixin):
|
|||
|
||||
return data
|
||||
|
||||
@classmethod
|
||||
def from_hdf5(cls, group_or_filename):
|
||||
"""Generate photon reaction from an HDF5 group
|
||||
|
||||
Parameters
|
||||
----------
|
||||
group_or_filename : h5py.Group or str
|
||||
HDF5 group containing interaction data. If given as a string, it is
|
||||
assumed to be the filename for the HDF5 file, and the first group is
|
||||
used to read from.
|
||||
|
||||
Returns
|
||||
-------
|
||||
openmc.data.IncidentPhoton
|
||||
Photon interaction data
|
||||
|
||||
"""
|
||||
if isinstance(group_or_filename, h5py.Group):
|
||||
group = group_or_filename
|
||||
else:
|
||||
h5file = h5py.File(str(group_or_filename), 'r')
|
||||
|
||||
# Make sure version matches
|
||||
if 'version' in h5file.attrs:
|
||||
major, minor = h5file.attrs['version']
|
||||
# For now all versions of HDF5 data can be read
|
||||
else:
|
||||
raise IOError(
|
||||
'HDF5 data does not indicate a version. Your installation '
|
||||
'of the OpenMC Python API expects version {}.x data.'
|
||||
.format(HDF5_VERSION_MAJOR))
|
||||
|
||||
group = list(h5file.values())[0]
|
||||
|
||||
Z = group.attrs['Z']
|
||||
data = cls(Z)
|
||||
|
||||
# Read energy grid
|
||||
energy = group['energy'][()]
|
||||
|
||||
# Read cross section data
|
||||
for mt, (name, key) in _REACTION_NAME.items():
|
||||
if key in group:
|
||||
rgroup = group[key]
|
||||
elif key in group['subshells']:
|
||||
rgroup = group['subshells'][key]
|
||||
else:
|
||||
continue
|
||||
|
||||
data.reactions[mt] = PhotonReaction.from_hdf5(rgroup, mt, energy)
|
||||
|
||||
# Check for necessary reactions
|
||||
for mt in (502, 504, 522):
|
||||
assert mt in data, "Reaction {} not found".format(mt)
|
||||
|
||||
# Read atomic relaxation
|
||||
data.atomic_relaxation = AtomicRelaxation.from_hdf5(group['subshells'])
|
||||
|
||||
# Read Compton profiles
|
||||
if 'compton_profiles' in group:
|
||||
rgroup = group['compton_profiles']
|
||||
profile = data.compton_profiles
|
||||
profile['num_electrons'] = rgroup['num_electrons'][()]
|
||||
profile['binding_energy'] = rgroup['binding_energy'][()]
|
||||
|
||||
# Get electron momentum values
|
||||
pz = rgroup['pz'][()]
|
||||
J = rgroup['J'][()]
|
||||
if pz.size != J.shape[1]:
|
||||
raise ValueError("'J' array shape is not consistent with the "
|
||||
"'pz' array shape")
|
||||
profile['J'] = [Tabulated1D(pz, Jk) for Jk in J]
|
||||
|
||||
# Read bremsstrahlung
|
||||
if 'bremsstrahlung' in group:
|
||||
rgroup = group['bremsstrahlung']
|
||||
data.bremsstrahlung['I'] = rgroup.attrs['I']
|
||||
for key in ('dcs', 'electron_energy', 'ionization_energy',
|
||||
'num_electrons', 'photon_energy'):
|
||||
data.bremsstrahlung[key] = rgroup[key][()]
|
||||
|
||||
return data
|
||||
|
||||
def export_to_hdf5(self, path, mode='a', libver='earliest'):
|
||||
"""Export incident photon data to an HDF5 file.
|
||||
|
||||
|
|
@ -590,6 +726,9 @@ class IncidentPhoton(EqualityMixin):
|
|||
mode : {'r', r+', 'w', 'x', 'a'}
|
||||
Mode that is used to open the HDF5 file. This is the second argument
|
||||
to the :class:`h5py.File` constructor.
|
||||
libver : {'earliest', 'latest'}
|
||||
Compatibility mode for the HDF5 file. 'latest' will produce files
|
||||
that are less backwards compatible but have performance benefits.
|
||||
|
||||
"""
|
||||
# Open file and write version
|
||||
|
|
@ -607,77 +746,25 @@ class IncidentPhoton(EqualityMixin):
|
|||
union_grid = np.union1d(union_grid, rx.xs.x)
|
||||
group.create_dataset('energy', data=union_grid)
|
||||
|
||||
# Write coherent scattering cross section
|
||||
rx = self.reactions[502]
|
||||
coh_group = group.create_group('coherent')
|
||||
coh_group.create_dataset('xs', data=rx.xs(union_grid))
|
||||
if rx.scattering_factor is not None:
|
||||
# Create integrated form factor
|
||||
ff = deepcopy(rx.scattering_factor)
|
||||
ff.x *= ff.x
|
||||
ff.y *= ff.y/Z**2
|
||||
int_ff = Tabulated1D(ff.x, ff.integral())
|
||||
int_ff.to_hdf5(coh_group, 'integrated_scattering_factor')
|
||||
if rx.anomalous_real is not None:
|
||||
rx.anomalous_real.to_hdf5(coh_group, 'anomalous_real')
|
||||
if rx.anomalous_imag is not None:
|
||||
rx.anomalous_imag.to_hdf5(coh_group, 'anomalous_imag')
|
||||
|
||||
# Write incoherent scattering cross section
|
||||
rx = self[504]
|
||||
incoh_group = group.create_group('incoherent')
|
||||
incoh_group.create_dataset('xs', data=rx.xs(union_grid))
|
||||
if rx.scattering_factor is not None:
|
||||
rx.scattering_factor.to_hdf5(incoh_group, 'scattering_factor')
|
||||
|
||||
# Write electron-field pair production cross section
|
||||
if 515 in self:
|
||||
pair_group = group.create_group('pair_production_electron')
|
||||
pair_group.create_dataset('xs', data=self[515].xs(union_grid))
|
||||
|
||||
# Write nuclear-field pair production cross section
|
||||
if 517 in self:
|
||||
pair_group = group.create_group('pair_production_nuclear')
|
||||
pair_group.create_dataset('xs', data=self[517].xs(union_grid))
|
||||
|
||||
# Write photoelectric cross section
|
||||
photoelec_group = group.create_group('photoelectric')
|
||||
photoelec_group.create_dataset('xs', data=self[522].xs(union_grid))
|
||||
|
||||
# Write photoionization cross sections
|
||||
# Write cross sections
|
||||
shell_group = group.create_group('subshells')
|
||||
designators = []
|
||||
for mt, rx in self.reactions.items():
|
||||
if mt >= 534 and mt <= 572:
|
||||
# Get name of subshell
|
||||
shell = _SUBSHELLS[mt - 534]
|
||||
designators.append(shell)
|
||||
sub_group = shell_group.create_group(shell)
|
||||
name, key = _REACTION_NAME[mt]
|
||||
if mt in [502, 504, 515, 517, 522]:
|
||||
sub_group = group.create_group(key)
|
||||
elif mt >= 534 and mt <= 572:
|
||||
# Subshell
|
||||
designators.append(key)
|
||||
sub_group = shell_group.create_group(key)
|
||||
|
||||
if self.atomic_relaxation is not None:
|
||||
relax = self.atomic_relaxation
|
||||
# Write subshell binding energy and number of electrons
|
||||
sub_group.attrs['binding_energy'] = relax.binding_energy[shell]
|
||||
sub_group.attrs['num_electrons'] = relax.num_electrons[shell]
|
||||
# Write atomic relaxation
|
||||
if key in self.atomic_relaxation.subshells:
|
||||
self.atomic_relaxation.to_hdf5(sub_group, key)
|
||||
else:
|
||||
continue
|
||||
|
||||
# Write transition data with replacements
|
||||
if shell in relax.transitions:
|
||||
shell_values = _SUBSHELLS.copy()
|
||||
shell_values.insert(0, None)
|
||||
df = relax.transitions[shell].replace(
|
||||
shell_values, range(len(shell_values)))
|
||||
sub_group.create_dataset(
|
||||
'transitions', data=df.values.astype(float))
|
||||
|
||||
# Determine threshold
|
||||
threshold = rx.xs.x[0]
|
||||
idx = np.searchsorted(union_grid, threshold, side='right') - 1
|
||||
|
||||
# Interpolate cross section onto union grid and write
|
||||
photoionization = rx.xs(union_grid[idx:])
|
||||
sub_group.create_dataset('xs', data=photoionization)
|
||||
assert len(union_grid) == len(photoionization) + idx
|
||||
sub_group['xs'].attrs['threshold_idx'] = idx
|
||||
rx.to_hdf5(sub_group, union_grid, Z)
|
||||
|
||||
shell_group.attrs['designators'] = np.array(designators, dtype='S')
|
||||
|
||||
|
|
@ -720,8 +807,8 @@ class IncidentPhoton(EqualityMixin):
|
|||
group = f['{:03}'.format(i)]
|
||||
_BREMSSTRAHLUNG[i] = {
|
||||
'I': group.attrs['I'],
|
||||
'num_electrons': group['num_electrons'].value,
|
||||
'ionization_energy': group['ionization_energy'].value
|
||||
'num_electrons': group['num_electrons'][()],
|
||||
'ionization_energy': group['ionization_energy'][()]
|
||||
}
|
||||
|
||||
filename = os.path.join(os.path.dirname(__file__), 'BREMX.DAT')
|
||||
|
|
@ -805,7 +892,7 @@ class PhotonReaction(EqualityMixin):
|
|||
def __repr__(self):
|
||||
if self.mt in _REACTION_NAME:
|
||||
return "<Photon Reaction: MT={} {}>".format(
|
||||
self.mt, _REACTION_NAME[self.mt])
|
||||
self.mt, _REACTION_NAME[self.mt][0])
|
||||
else:
|
||||
return "<Photon Reaction: MT={}>".format(self.mt)
|
||||
|
||||
|
|
@ -982,3 +1069,93 @@ class PhotonReaction(EqualityMixin):
|
|||
params, rx.anomalous_imag = get_tab1_record(file_obj)
|
||||
|
||||
return rx
|
||||
|
||||
@classmethod
|
||||
def from_hdf5(cls, group, mt, energy):
|
||||
"""Generate photon reaction from an HDF5 group
|
||||
|
||||
Parameters
|
||||
----------
|
||||
group : h5py.Group
|
||||
HDF5 group to read from
|
||||
mt : int
|
||||
The MT value of the reaction to get data for
|
||||
energy : Iterable of float
|
||||
arrays of energies at which cross sections are tabulated at
|
||||
|
||||
Returns
|
||||
-------
|
||||
openmc.data.PhotonReaction
|
||||
Photon reaction data
|
||||
|
||||
"""
|
||||
# Create instance
|
||||
rx = cls(mt)
|
||||
|
||||
# Cross sections
|
||||
xs = group['xs'][()]
|
||||
# Replace zero elements to small non-zero to enable log-log
|
||||
xs[xs == 0.0] = np.exp(-500.0)
|
||||
|
||||
# Threshold
|
||||
threshold_idx = 0
|
||||
if 'threshold_idx' in group['xs'].attrs:
|
||||
threshold_idx = group['xs'].attrs['threshold_idx']
|
||||
|
||||
# Store cross section
|
||||
rx.xs = Tabulated1D(energy[threshold_idx:], xs, [len(xs)], [5])
|
||||
|
||||
# Check for anomalous scattering factor
|
||||
if 'anomalous_real' in group:
|
||||
rx.anomalous_real = Tabulated1D.from_hdf5(group['anomalous_real'])
|
||||
if 'anomalous_imag' in group:
|
||||
rx.anomalous_imag = Tabulated1D.from_hdf5(group['anomalous_imag'])
|
||||
|
||||
# Check for factors / scattering functions
|
||||
if 'scattering_factor' in group:
|
||||
rx.scattering_factor = Tabulated1D.from_hdf5(group['scattering_factor'])
|
||||
|
||||
return rx
|
||||
|
||||
def to_hdf5(self, group, energy, Z):
|
||||
"""Write photon reaction to an HDF5 group
|
||||
|
||||
Parameters
|
||||
----------
|
||||
group : h5py.Group
|
||||
HDF5 group to write to
|
||||
energy : Iterable of float
|
||||
arrays of energies at which cross sections are tabulated at
|
||||
Z : int
|
||||
atomic number
|
||||
|
||||
"""
|
||||
|
||||
# Write cross sections
|
||||
if self.mt >= 534 and self.mt <= 572:
|
||||
# Determine threshold
|
||||
threshold = self.xs.x[0]
|
||||
idx = np.searchsorted(energy, threshold, side='right') - 1
|
||||
|
||||
# Interpolate cross section onto union grid and write
|
||||
photoionization = self.xs(energy[idx:])
|
||||
group.create_dataset('xs', data=photoionization)
|
||||
assert len(energy) == len(photoionization) + idx
|
||||
group['xs'].attrs['threshold_idx'] = idx
|
||||
else:
|
||||
group.create_dataset('xs', data=self.xs(energy))
|
||||
|
||||
# Write scattering factor
|
||||
if self.scattering_factor is not None:
|
||||
if self.mt == 502:
|
||||
# Create integrated form factor
|
||||
ff = deepcopy(self.scattering_factor)
|
||||
ff.x *= ff.x
|
||||
ff.y *= ff.y/Z**2
|
||||
int_ff = Tabulated1D(ff.x, ff.integral())
|
||||
int_ff.to_hdf5(group, 'integrated_scattering_factor')
|
||||
self.scattering_factor.to_hdf5(group, 'scattering_factor')
|
||||
if self.anomalous_real is not None:
|
||||
self.anomalous_real.to_hdf5(group, 'anomalous_real')
|
||||
if self.anomalous_imag is not None:
|
||||
self.anomalous_imag.to_hdf5(group, 'anomalous_imag')
|
||||
|
|
|
|||
|
|
@ -938,7 +938,7 @@ class Reaction(EqualityMixin):
|
|||
'Could not create reaction cross section for MT={} '
|
||||
'at T={} because no corresponding energy grid '
|
||||
'exists.'.format(mt, T))
|
||||
xs = Tgroup['xs'].value
|
||||
xs = Tgroup['xs'][()]
|
||||
threshold_idx = Tgroup['xs'].attrs['threshold_idx'] - 1
|
||||
tabulated_xs = Tabulated1D(energy[T][threshold_idx:], xs)
|
||||
tabulated_xs._threshold_idx = threshold_idx
|
||||
|
|
|
|||
|
|
@ -200,8 +200,8 @@ class CoherentElastic(EqualityMixin):
|
|||
Coherent elastic scattering cross section
|
||||
|
||||
"""
|
||||
bragg_edges = dataset.value[0, :]
|
||||
factors = dataset.value[1, :]
|
||||
bragg_edges = dataset[0, :]
|
||||
factors = dataset[1, :]
|
||||
return cls(bragg_edges, factors)
|
||||
|
||||
|
||||
|
|
@ -414,7 +414,7 @@ class ThermalScattering(EqualityMixin):
|
|||
kTg = group['kTs']
|
||||
kTs = []
|
||||
for temp in kTg:
|
||||
kTs.append(kTg[temp].value)
|
||||
kTs.append(kTg[temp][()])
|
||||
temperatures = [str(int(round(kT / K_BOLTZMANN))) + "K" for kT in kTs]
|
||||
|
||||
table = cls(name, atomic_weight_ratio, kTs)
|
||||
|
|
@ -438,7 +438,7 @@ class ThermalScattering(EqualityMixin):
|
|||
|
||||
# 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'][()]
|
||||
|
||||
# Read thermal inelastic scattering
|
||||
if 'inelastic' in Tgroup:
|
||||
|
|
@ -446,8 +446,8 @@ class ThermalScattering(EqualityMixin):
|
|||
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'].value
|
||||
table.inelastic_mu_out[T] = inelastic_group['mu_out'].value
|
||||
table.inelastic_e_out[T] = inelastic_group['energy_out'][()]
|
||||
table.inelastic_mu_out[T] = inelastic_group['mu_out'][()]
|
||||
elif table.secondary_mode == 'continuous':
|
||||
table.inelastic_dist[T] = AngleEnergy.from_hdf5(
|
||||
inelastic_group)
|
||||
|
|
|
|||
|
|
@ -166,8 +166,8 @@ class ProbabilityTables(EqualityMixin):
|
|||
absorption_flag = group.attrs['absorption']
|
||||
multiply_smooth = bool(group.attrs['multiply_smooth'])
|
||||
|
||||
energy = group['energy'].value
|
||||
table = group['table'].value
|
||||
energy = group['energy'][()]
|
||||
table = group['table'][()]
|
||||
|
||||
return cls(energy, table, interpolation, inelastic_flag,
|
||||
absorption_flag, multiply_smooth)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class ResultsList(list):
|
|||
check_filetype_version(fh, 'depletion results', _VERSION_RESULTS[0])
|
||||
|
||||
# Get number of results stored
|
||||
n = fh["number"].value.shape[0]
|
||||
n = fh["number"][...].shape[0]
|
||||
|
||||
for i in range(n):
|
||||
self.append(Results.from_hdf5(fh, i))
|
||||
|
|
|
|||
|
|
@ -170,19 +170,19 @@ class Filter(IDManagerMixin, metaclass=FilterMeta):
|
|||
|
||||
# If the HDF5 'type' variable matches this class's short_name, then
|
||||
# there is no overriden from_hdf5 method. Pass the bins to __init__.
|
||||
if group['type'].value.decode() == cls.short_name.lower():
|
||||
out = cls(group['bins'].value, filter_id=filter_id)
|
||||
out._num_bins = group['n_bins'].value
|
||||
if group['type'][()].decode() == cls.short_name.lower():
|
||||
out = cls(group['bins'][()], filter_id=filter_id)
|
||||
out._num_bins = group['n_bins'][()]
|
||||
return out
|
||||
|
||||
# Search through all subclasses and find the one matching the HDF5
|
||||
# 'type'. Call that class's from_hdf5 method.
|
||||
for subclass in cls._recursive_subclasses():
|
||||
if group['type'].value.decode() == subclass.short_name.lower():
|
||||
if group['type'][()].decode() == subclass.short_name.lower():
|
||||
return subclass.from_hdf5(group, **kwargs)
|
||||
|
||||
raise ValueError("Unrecognized Filter class: '"
|
||||
+ group['type'].value.decode() + "'")
|
||||
+ group['type'][()].decode() + "'")
|
||||
|
||||
@property
|
||||
def bins(self):
|
||||
|
|
@ -618,16 +618,16 @@ class MeshFilter(Filter):
|
|||
|
||||
@classmethod
|
||||
def from_hdf5(cls, group, **kwargs):
|
||||
if group['type'].value.decode() != cls.short_name.lower():
|
||||
if group['type'][()].decode() != cls.short_name.lower():
|
||||
raise ValueError("Expected HDF5 data for filter type '"
|
||||
+ cls.short_name.lower() + "' but got '"
|
||||
+ group['type'].value.decode() + " instead")
|
||||
+ group['type'][()].decode() + " instead")
|
||||
|
||||
if 'meshes' not in kwargs:
|
||||
raise ValueError(cls.__name__ + " requires a 'meshes' keyword "
|
||||
"argument.")
|
||||
|
||||
mesh_id = group['bins'].value
|
||||
mesh_id = group['bins'][()]
|
||||
mesh_obj = kwargs['meshes'][mesh_id]
|
||||
filter_id = int(group.name.split('/')[-1].lstrip('filter '))
|
||||
|
||||
|
|
@ -1191,15 +1191,15 @@ class DistribcellFilter(Filter):
|
|||
|
||||
@classmethod
|
||||
def from_hdf5(cls, group, **kwargs):
|
||||
if group['type'].value.decode() != cls.short_name.lower():
|
||||
if group['type'][()].decode() != cls.short_name.lower():
|
||||
raise ValueError("Expected HDF5 data for filter type '"
|
||||
+ cls.short_name.lower() + "' but got '"
|
||||
+ group['type'].value.decode() + " instead")
|
||||
+ group['type'][()].decode() + " instead")
|
||||
|
||||
filter_id = int(group.name.split('/')[-1].lstrip('filter '))
|
||||
|
||||
out = cls(group['bins'].value, filter_id=filter_id)
|
||||
out._num_bins = group['n_bins'].value
|
||||
out = cls(group['bins'][()], filter_id=filter_id)
|
||||
out._num_bins = group['n_bins'][()]
|
||||
|
||||
return out
|
||||
|
||||
|
|
@ -1638,13 +1638,13 @@ class EnergyFunctionFilter(Filter):
|
|||
|
||||
@classmethod
|
||||
def from_hdf5(cls, group, **kwargs):
|
||||
if group['type'].value.decode() != cls.short_name.lower():
|
||||
if group['type'][()].decode() != cls.short_name.lower():
|
||||
raise ValueError("Expected HDF5 data for filter type '"
|
||||
+ cls.short_name.lower() + "' but got '"
|
||||
+ group['type'].value.decode() + " instead")
|
||||
+ group['type'][()].decode() + " instead")
|
||||
|
||||
energy = group['energy'].value
|
||||
y = group['y'].value
|
||||
energy = group['energy'][()]
|
||||
y = group['y'][()]
|
||||
filter_id = int(group.name.split('/')[-1].lstrip('filter '))
|
||||
|
||||
return cls(energy, y, filter_id=filter_id)
|
||||
|
|
|
|||
|
|
@ -92,14 +92,14 @@ class LegendreFilter(ExpansionFilter):
|
|||
|
||||
@classmethod
|
||||
def from_hdf5(cls, group, **kwargs):
|
||||
if group['type'].value.decode() != cls.short_name.lower():
|
||||
if group['type'][()].decode() != cls.short_name.lower():
|
||||
raise ValueError("Expected HDF5 data for filter type '"
|
||||
+ cls.short_name.lower() + "' but got '"
|
||||
+ group['type'].value.decode() + " instead")
|
||||
+ group['type'][()].decode() + " instead")
|
||||
|
||||
filter_id = int(group.name.split('/')[-1].lstrip('filter '))
|
||||
|
||||
out = cls(group['order'].value, filter_id)
|
||||
out = cls(group['order'][()], filter_id)
|
||||
|
||||
return out
|
||||
|
||||
|
|
@ -198,15 +198,15 @@ class SpatialLegendreFilter(ExpansionFilter):
|
|||
|
||||
@classmethod
|
||||
def from_hdf5(cls, group, **kwargs):
|
||||
if group['type'].value.decode() != cls.short_name.lower():
|
||||
if group['type'][()].decode() != cls.short_name.lower():
|
||||
raise ValueError("Expected HDF5 data for filter type '"
|
||||
+ cls.short_name.lower() + "' but got '"
|
||||
+ group['type'].value.decode() + " instead")
|
||||
+ group['type'][()].decode() + " instead")
|
||||
|
||||
filter_id = int(group.name.split('/')[-1].lstrip('filter '))
|
||||
order = group['order'].value
|
||||
axis = group['axis'].value.decode()
|
||||
min_, max_ = group['min'].value, group['max'].value
|
||||
order = group['order'][()]
|
||||
axis = group['axis'][()].decode()
|
||||
min_, max_ = group['min'][()], group['max'][()]
|
||||
|
||||
return cls(order, axis, min_, max_, filter_id)
|
||||
|
||||
|
|
@ -294,15 +294,15 @@ class SphericalHarmonicsFilter(ExpansionFilter):
|
|||
|
||||
@classmethod
|
||||
def from_hdf5(cls, group, **kwargs):
|
||||
if group['type'].value.decode() != cls.short_name.lower():
|
||||
if group['type'][()].decode() != cls.short_name.lower():
|
||||
raise ValueError("Expected HDF5 data for filter type '"
|
||||
+ cls.short_name.lower() + "' but got '"
|
||||
+ group['type'].value.decode() + " instead")
|
||||
+ group['type'][()].decode() + " instead")
|
||||
|
||||
filter_id = int(group.name.split('/')[-1].lstrip('filter '))
|
||||
|
||||
out = cls(group['order'].value, filter_id)
|
||||
out.cosine = group['cosine'].value.decode()
|
||||
out = cls(group['order'][()], filter_id)
|
||||
out.cosine = group['cosine'][()].decode()
|
||||
|
||||
return out
|
||||
|
||||
|
|
@ -437,14 +437,14 @@ class ZernikeFilter(ExpansionFilter):
|
|||
|
||||
@classmethod
|
||||
def from_hdf5(cls, group, **kwargs):
|
||||
if group['type'].value.decode() != cls.short_name.lower():
|
||||
if group['type'][()].decode() != cls.short_name.lower():
|
||||
raise ValueError("Expected HDF5 data for filter type '"
|
||||
+ cls.short_name.lower() + "' but got '"
|
||||
+ group['type'].value.decode() + " instead")
|
||||
+ group['type'][()].decode() + " instead")
|
||||
|
||||
filter_id = int(group.name.split('/')[-1].lstrip('filter '))
|
||||
order = group['order'].value
|
||||
x, y, r = group['x'].value, group['y'].value, group['r'].value
|
||||
order = group['order'][()]
|
||||
x, y, r = group['x'][()], group['y'][()], group['r'][()]
|
||||
|
||||
return cls(order, x, y, r, filter_id)
|
||||
|
||||
|
|
|
|||
|
|
@ -100,14 +100,14 @@ class Lattice(IDManagerMixin, metaclass=ABCMeta):
|
|||
|
||||
"""
|
||||
lattice_id = int(group.name.split('/')[-1].lstrip('lattice '))
|
||||
name = group['name'].value.decode() if 'name' in group else ''
|
||||
lattice_type = group['type'].value.decode()
|
||||
name = group['name'][()].decode() if 'name' in group else ''
|
||||
lattice_type = group['type'][()].decode()
|
||||
|
||||
if lattice_type == 'rectangular':
|
||||
dimension = group['dimension'][...]
|
||||
lower_left = group['lower_left'][...]
|
||||
pitch = group['pitch'][...]
|
||||
outer = group['outer'].value
|
||||
outer = group['outer'][()]
|
||||
universe_ids = group['universes'][...]
|
||||
|
||||
# Create the Lattice
|
||||
|
|
@ -136,13 +136,13 @@ class Lattice(IDManagerMixin, metaclass=ABCMeta):
|
|||
lattice.universes = uarray
|
||||
|
||||
elif lattice_type == 'hexagonal':
|
||||
n_rings = group['n_rings'].value
|
||||
n_axial = group['n_axial'].value
|
||||
center = group['center'][...]
|
||||
pitch = group['pitch'][...]
|
||||
outer = group['outer'].value
|
||||
n_rings = group['n_rings'][()]
|
||||
n_axial = group['n_axial'][()]
|
||||
center = group['center'][()]
|
||||
pitch = group['pitch'][()]
|
||||
outer = group['outer'][()]
|
||||
|
||||
universe_ids = group['universes'][...]
|
||||
universe_ids = group['universes'][()]
|
||||
|
||||
# Create the Lattice
|
||||
lattice = openmc.HexLattice(lattice_id, name)
|
||||
|
|
|
|||
|
|
@ -277,8 +277,8 @@ class Material(IDManagerMixin):
|
|||
"""
|
||||
mat_id = int(group.name.split('/')[-1].lstrip('material '))
|
||||
|
||||
name = group['name'].value.decode() if 'name' in group else ''
|
||||
density = group['atom_density'].value
|
||||
name = group['name'][()].decode() if 'name' in group else ''
|
||||
density = group['atom_density'][()]
|
||||
if 'nuclide_densities' in group:
|
||||
nuc_densities = group['nuclide_densities'][...]
|
||||
|
||||
|
|
@ -290,7 +290,7 @@ class Material(IDManagerMixin):
|
|||
|
||||
# Read the names of the S(a,b) tables for this Material and add them
|
||||
if 'sab_names' in group:
|
||||
sab_tables = group['sab_names'].value
|
||||
sab_tables = group['sab_names'][()]
|
||||
for sab_table in sab_tables:
|
||||
name = sab_table.decode()
|
||||
material.add_s_alpha_beta(name)
|
||||
|
|
@ -299,13 +299,13 @@ class Material(IDManagerMixin):
|
|||
material.set_density(density=density, units='atom/b-cm')
|
||||
|
||||
if 'nuclides' in group:
|
||||
nuclides = group['nuclides'].value
|
||||
nuclides = group['nuclides'][()]
|
||||
# Add all nuclides to the Material
|
||||
for fullname, density in zip(nuclides, nuc_densities):
|
||||
name = fullname.decode().strip()
|
||||
material.add_nuclide(name, percent=density, percent_type='ao')
|
||||
if 'macroscopics' in group:
|
||||
macroscopics = group['macroscopics'].value
|
||||
macroscopics = group['macroscopics'][()]
|
||||
# Add all macroscopics to the Material
|
||||
for fullname in macroscopics:
|
||||
name = fullname.decode().strip()
|
||||
|
|
|
|||
|
|
@ -174,11 +174,11 @@ class Mesh(IDManagerMixin):
|
|||
|
||||
# Read and assign mesh properties
|
||||
mesh = cls(mesh_id)
|
||||
mesh.type = group['type'].value.decode()
|
||||
mesh.dimension = group['dimension'].value
|
||||
mesh.lower_left = group['lower_left'].value
|
||||
mesh.upper_right = group['upper_right'].value
|
||||
mesh.width = group['width'].value
|
||||
mesh.type = group['type'][()].decode()
|
||||
mesh.dimension = group['dimension'][()]
|
||||
mesh.lower_left = group['lower_left'][()]
|
||||
mesh.upper_right = group['upper_right'][()]
|
||||
mesh.width = group['width'][()]
|
||||
|
||||
return mesh
|
||||
|
||||
|
|
|
|||
|
|
@ -2183,7 +2183,7 @@ class XSdata(object):
|
|||
kTs_group = group['kTs']
|
||||
float_temperatures = []
|
||||
for temperature in temperatures:
|
||||
kT = kTs_group[temperature].value
|
||||
kT = kTs_group[temperature][()]
|
||||
float_temperatures.append(kT / openmc.data.K_BOLTZMANN)
|
||||
|
||||
attrs = group.attrs.keys()
|
||||
|
|
@ -2219,7 +2219,7 @@ class XSdata(object):
|
|||
for xs_type in xs_types:
|
||||
set_func = 'set_' + xs_type.replace(' ', '_').replace('-', '_')
|
||||
if xs_type in temperature_group:
|
||||
getattr(data, set_func)(temperature_group[xs_type].value,
|
||||
getattr(data, set_func)(temperature_group[xs_type][()],
|
||||
float_temp)
|
||||
|
||||
scatt_group = temperature_group['scatter_data']
|
||||
|
|
@ -2227,7 +2227,7 @@ class XSdata(object):
|
|||
# Get scatter matrix and 'un-flatten' it
|
||||
g_max = scatt_group['g_max']
|
||||
g_min = scatt_group['g_min']
|
||||
flat_scatter = scatt_group['scatter_matrix'].value
|
||||
flat_scatter = scatt_group['scatter_matrix'][()]
|
||||
scatter_matrix = np.zeros(data.xs_shapes["[G][G'][Order]"])
|
||||
G = data.energy_groups.num_groups
|
||||
if data.representation == 'isotropic':
|
||||
|
|
@ -2259,7 +2259,7 @@ class XSdata(object):
|
|||
|
||||
# Repeat for multiplicity
|
||||
if 'multiplicity_matrix' in scatt_group:
|
||||
flat_mult = scatt_group['multiplicity_matrix'].value
|
||||
flat_mult = scatt_group['multiplicity_matrix'][()]
|
||||
mult_matrix = np.zeros(data.xs_shapes["[G][G']"])
|
||||
flat_index = 0
|
||||
for p in range(Np):
|
||||
|
|
|
|||
|
|
@ -49,44 +49,44 @@ class Particle(object):
|
|||
|
||||
@property
|
||||
def current_batch(self):
|
||||
return self._f['current_batch'].value
|
||||
return self._f['current_batch'][()]
|
||||
|
||||
@property
|
||||
def current_generation(self):
|
||||
return self._f['current_generation'].value
|
||||
return self._f['current_generation'][()]
|
||||
|
||||
@property
|
||||
def energy(self):
|
||||
return self._f['energy'].value
|
||||
return self._f['energy'][()]
|
||||
|
||||
@property
|
||||
def generations_per_batch(self):
|
||||
return self._f['generations_per_batch'].value
|
||||
return self._f['generations_per_batch'][()]
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
return self._f['id'].value
|
||||
return self._f['id'][()]
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
return self._f['type'].value
|
||||
return self._f['type'][()]
|
||||
|
||||
@property
|
||||
def n_particles(self):
|
||||
return self._f['n_particles'].value
|
||||
return self._f['n_particles'][()]
|
||||
|
||||
@property
|
||||
def run_mode(self):
|
||||
return self._f['run_mode'].value.decode()
|
||||
return self._f['run_mode'][()].decode()
|
||||
|
||||
@property
|
||||
def uvw(self):
|
||||
return self._f['uvw'].value
|
||||
return self._f['uvw'][()]
|
||||
|
||||
@property
|
||||
def weight(self):
|
||||
return self._f['weight'].value
|
||||
return self._f['weight'][()]
|
||||
|
||||
@property
|
||||
def xyz(self):
|
||||
return self._f['xyz'].value
|
||||
return self._f['xyz'][()]
|
||||
|
|
|
|||
|
|
@ -161,35 +161,35 @@ class StatePoint(object):
|
|||
|
||||
@property
|
||||
def cmfd_balance(self):
|
||||
return self._f['cmfd/cmfd_balance'].value if self.cmfd_on else None
|
||||
return self._f['cmfd/cmfd_balance'][()] if self.cmfd_on else None
|
||||
|
||||
@property
|
||||
def cmfd_dominance(self):
|
||||
return self._f['cmfd/cmfd_dominance'].value if self.cmfd_on else None
|
||||
return self._f['cmfd/cmfd_dominance'][()] if self.cmfd_on else None
|
||||
|
||||
@property
|
||||
def cmfd_entropy(self):
|
||||
return self._f['cmfd/cmfd_entropy'].value if self.cmfd_on else None
|
||||
return self._f['cmfd/cmfd_entropy'][()] if self.cmfd_on else None
|
||||
|
||||
@property
|
||||
def cmfd_indices(self):
|
||||
return self._f['cmfd/indices'].value if self.cmfd_on else None
|
||||
return self._f['cmfd/indices'][()] if self.cmfd_on else None
|
||||
|
||||
@property
|
||||
def cmfd_src(self):
|
||||
if self.cmfd_on:
|
||||
data = self._f['cmfd/cmfd_src'].value
|
||||
data = self._f['cmfd/cmfd_src'][()]
|
||||
return np.reshape(data, tuple(self.cmfd_indices), order='F')
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
def cmfd_srccmp(self):
|
||||
return self._f['cmfd/cmfd_srccmp'].value if self.cmfd_on else None
|
||||
return self._f['cmfd/cmfd_srccmp'][()] if self.cmfd_on else None
|
||||
|
||||
@property
|
||||
def current_batch(self):
|
||||
return self._f['current_batch'].value
|
||||
return self._f['current_batch'][()]
|
||||
|
||||
@property
|
||||
def date_and_time(self):
|
||||
|
|
@ -199,7 +199,7 @@ class StatePoint(object):
|
|||
@property
|
||||
def entropy(self):
|
||||
if self.run_mode == 'eigenvalue':
|
||||
return self._f['entropy'].value
|
||||
return self._f['entropy'][()]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
|
@ -220,14 +220,14 @@ class StatePoint(object):
|
|||
@property
|
||||
def generations_per_batch(self):
|
||||
if self.run_mode == 'eigenvalue':
|
||||
return self._f['generations_per_batch'].value
|
||||
return self._f['generations_per_batch'][()]
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
def global_tallies(self):
|
||||
if self._global_tallies is None:
|
||||
data = self._f['global_tallies'].value
|
||||
data = self._f['global_tallies'][()]
|
||||
gt = np.zeros(data.shape[0], dtype=[
|
||||
('name', 'a14'), ('sum', 'f8'), ('sum_sq', 'f8'),
|
||||
('mean', 'f8'), ('std_dev', 'f8')])
|
||||
|
|
@ -248,42 +248,42 @@ class StatePoint(object):
|
|||
@property
|
||||
def k_cmfd(self):
|
||||
if self.cmfd_on:
|
||||
return self._f['cmfd/k_cmfd'].value
|
||||
return self._f['cmfd/k_cmfd'][()]
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
def k_generation(self):
|
||||
if self.run_mode == 'eigenvalue':
|
||||
return self._f['k_generation'].value
|
||||
return self._f['k_generation'][()]
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
def k_combined(self):
|
||||
if self.run_mode == 'eigenvalue':
|
||||
return ufloat(*self._f['k_combined'].value)
|
||||
return ufloat(*self._f['k_combined'][()])
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
def k_col_abs(self):
|
||||
if self.run_mode == 'eigenvalue':
|
||||
return self._f['k_col_abs'].value
|
||||
return self._f['k_col_abs'][()]
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
def k_col_tra(self):
|
||||
if self.run_mode == 'eigenvalue':
|
||||
return self._f['k_col_tra'].value
|
||||
return self._f['k_col_tra'][()]
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
def k_abs_tra(self):
|
||||
if self.run_mode == 'eigenvalue':
|
||||
return self._f['k_abs_tra'].value
|
||||
return self._f['k_abs_tra'][()]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
|
@ -303,22 +303,22 @@ class StatePoint(object):
|
|||
|
||||
@property
|
||||
def n_batches(self):
|
||||
return self._f['n_batches'].value
|
||||
return self._f['n_batches'][()]
|
||||
|
||||
@property
|
||||
def n_inactive(self):
|
||||
if self.run_mode == 'eigenvalue':
|
||||
return self._f['n_inactive'].value
|
||||
return self._f['n_inactive'][()]
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
def n_particles(self):
|
||||
return self._f['n_particles'].value
|
||||
return self._f['n_particles'][()]
|
||||
|
||||
@property
|
||||
def n_realizations(self):
|
||||
return self._f['n_realizations'].value
|
||||
return self._f['n_realizations'][()]
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
|
|
@ -330,20 +330,20 @@ class StatePoint(object):
|
|||
|
||||
@property
|
||||
def run_mode(self):
|
||||
return self._f['run_mode'].value.decode()
|
||||
return self._f['run_mode'][()].decode()
|
||||
|
||||
@property
|
||||
def runtime(self):
|
||||
return {name: dataset.value
|
||||
return {name: dataset[()]
|
||||
for name, dataset in self._f['runtime'].items()}
|
||||
|
||||
@property
|
||||
def seed(self):
|
||||
return self._f['seed'].value
|
||||
return self._f['seed'][()]
|
||||
|
||||
@property
|
||||
def source(self):
|
||||
return self._f['source_bank'].value if self.source_present else None
|
||||
return self._f['source_bank'][()] if self.source_present else None
|
||||
|
||||
@property
|
||||
def source_present(self):
|
||||
|
|
@ -376,24 +376,24 @@ class StatePoint(object):
|
|||
group = tallies_group['tally {}'.format(tally_id)]
|
||||
|
||||
# Read the number of realizations
|
||||
n_realizations = group['n_realizations'].value
|
||||
n_realizations = group['n_realizations'][()]
|
||||
|
||||
# Create Tally object and assign basic properties
|
||||
tally = openmc.Tally(tally_id)
|
||||
tally._sp_filename = self._f.filename
|
||||
tally.name = group['name'].value.decode() if 'name' in group else ''
|
||||
tally.estimator = group['estimator'].value.decode()
|
||||
tally.name = group['name'][()].decode() if 'name' in group else ''
|
||||
tally.estimator = group['estimator'][()].decode()
|
||||
tally.num_realizations = n_realizations
|
||||
|
||||
# Read derivative information.
|
||||
if 'derivative' in group:
|
||||
deriv_id = group['derivative'].value
|
||||
deriv_id = group['derivative'][()]
|
||||
tally.derivative = self.tally_derivatives[deriv_id]
|
||||
|
||||
# Read all filters
|
||||
n_filters = group['n_filters'].value
|
||||
n_filters = group['n_filters'][()]
|
||||
if n_filters > 0:
|
||||
filter_ids = group['filters'].value
|
||||
filter_ids = group['filters'][()]
|
||||
filters_group = self._f['tallies/filters']
|
||||
for filter_id in filter_ids:
|
||||
filter_group = filters_group['filter {}'.format(
|
||||
|
|
@ -403,15 +403,15 @@ class StatePoint(object):
|
|||
tally.filters.append(new_filter)
|
||||
|
||||
# Read nuclide bins
|
||||
nuclide_names = group['nuclides'].value
|
||||
nuclide_names = group['nuclides'][()]
|
||||
|
||||
# Add all nuclides to the Tally
|
||||
for name in nuclide_names:
|
||||
nuclide = openmc.Nuclide(name.decode().strip())
|
||||
tally.nuclides.append(nuclide)
|
||||
|
||||
scores = group['score_bins'].value
|
||||
n_score_bins = group['n_score_bins'].value
|
||||
scores = group['score_bins'][()]
|
||||
n_score_bins = group['n_score_bins'][()]
|
||||
|
||||
# Add the scores to the Tally
|
||||
for j, score in enumerate(scores):
|
||||
|
|
@ -445,14 +445,14 @@ class StatePoint(object):
|
|||
group = self._f['tallies/derivatives/derivative {}'
|
||||
.format(d_id)]
|
||||
deriv = openmc.TallyDerivative(derivative_id=d_id)
|
||||
deriv.variable = group['independent variable'].value.decode()
|
||||
deriv.variable = group['independent variable'][()].decode()
|
||||
if deriv.variable == 'density':
|
||||
deriv.material = group['material'].value
|
||||
deriv.material = group['material'][()]
|
||||
elif deriv.variable == 'nuclide_density':
|
||||
deriv.material = group['material'].value
|
||||
deriv.nuclide = group['nuclide'].value.decode()
|
||||
deriv.material = group['material'][()]
|
||||
deriv.nuclide = group['nuclide'][()].decode()
|
||||
elif deriv.variable == 'temperature':
|
||||
deriv.material = group['material'].value
|
||||
deriv.material = group['material'][()]
|
||||
self._derivs[d_id] = deriv
|
||||
|
||||
self._derivs_read = True
|
||||
|
|
|
|||
|
|
@ -85,14 +85,14 @@ class Summary(object):
|
|||
|
||||
def _read_nuclides(self):
|
||||
if 'nuclides/names' in self._f:
|
||||
names = self._f['nuclides/names'].value
|
||||
awrs = self._f['nuclides/awrs'].value
|
||||
names = self._f['nuclides/names'][()]
|
||||
awrs = self._f['nuclides/awrs'][()]
|
||||
for name, awr in zip(names, awrs):
|
||||
self._nuclides[name.decode()] = awr
|
||||
|
||||
def _read_macroscopics(self):
|
||||
if 'macroscopics/names' in self._f:
|
||||
names = self._f['macroscopics/names'].value
|
||||
names = self._f['macroscopics/names'][()]
|
||||
for name in names:
|
||||
self._macroscopics = name.decode()
|
||||
|
||||
|
|
@ -130,17 +130,17 @@ class Summary(object):
|
|||
|
||||
for key, group in self._f['geometry/cells'].items():
|
||||
cell_id = int(key.lstrip('cell '))
|
||||
name = group['name'].value.decode() if 'name' in group else ''
|
||||
fill_type = group['fill_type'].value.decode()
|
||||
name = group['name'][()].decode() if 'name' in group else ''
|
||||
fill_type = group['fill_type'][()].decode()
|
||||
|
||||
if fill_type == 'material':
|
||||
fill = group['material'].value
|
||||
fill = group['material'][()]
|
||||
elif fill_type == 'universe':
|
||||
fill = group['fill'].value
|
||||
fill = group['fill'][()]
|
||||
else:
|
||||
fill = group['lattice'].value
|
||||
fill = group['lattice'][()]
|
||||
|
||||
region = group['region'].value.decode() if 'region' in group else ''
|
||||
region = group['region'][()].decode() if 'region' in group else ''
|
||||
|
||||
# Create this Cell
|
||||
cell = openmc.Cell(cell_id=cell_id, name=name)
|
||||
|
|
|
|||
|
|
@ -269,9 +269,9 @@ class Surface(IDManagerMixin, metaclass=ABCMeta):
|
|||
|
||||
"""
|
||||
surface_id = int(group.name.split('/')[-1].lstrip('surface '))
|
||||
name = group['name'].value.decode() if 'name' in group else ''
|
||||
surf_type = group['type'].value.decode()
|
||||
bc = group['boundary_type'].value.decode()
|
||||
name = group['name'][()].decode() if 'name' in group else ''
|
||||
surf_type = group['type'][()].decode()
|
||||
bc = group['boundary_type'][()].decode()
|
||||
coeffs = group['coefficients'][...]
|
||||
|
||||
# Create the Surface based on its type
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ class Tally(IDManagerMixin):
|
|||
f = h5py.File(self._sp_filename, 'r')
|
||||
|
||||
# Extract Tally data from the file
|
||||
data = f['tallies/tally {0}/results'.format(self.id)].value
|
||||
data = f['tallies/tally {0}/results'.format(self.id)][()]
|
||||
sum = data[:, :, 0]
|
||||
sum_sq = data[:, :, 1]
|
||||
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ class Universe(IDManagerMixin):
|
|||
|
||||
"""
|
||||
universe_id = int(group.name.split('/')[-1].lstrip('universe '))
|
||||
cell_ids = group['cells'].value
|
||||
cell_ids = group['cells'][()]
|
||||
|
||||
# Create this Universe
|
||||
universe = cls(universe_id)
|
||||
|
|
|
|||
|
|
@ -211,9 +211,9 @@ class VolumeCalculation(object):
|
|||
domain_id = int(obj_name[7:])
|
||||
ids.append(domain_id)
|
||||
group = f[obj_name]
|
||||
volume = ufloat(*group['volume'].value)
|
||||
nucnames = group['nuclides'].value
|
||||
atoms_ = group['atoms'].value
|
||||
volume = ufloat(*group['volume'][()])
|
||||
nucnames = group['nuclides'][()]
|
||||
atoms_ = group['atoms'][()]
|
||||
|
||||
atom_dict = OrderedDict()
|
||||
for name_i, atoms_i in zip(nucnames, atoms_):
|
||||
|
|
|
|||
|
|
@ -129,3 +129,20 @@ def test_export_to_hdf5(tmpdir, element):
|
|||
filename = str(tmpdir.join('tmp.h5'))
|
||||
element.export_to_hdf5(filename)
|
||||
assert os.path.exists(filename)
|
||||
# Read in data from hdf5
|
||||
element2 = openmc.data.IncidentPhoton.from_hdf5(filename)
|
||||
# Check for some cross section and datasets of element and element2
|
||||
energy = np.logspace(np.log10(1.0), np.log10(1.0e10), num=100)
|
||||
for mt in (502, 504, 515, 517, 522, 541, 570):
|
||||
xs = element[mt].xs(energy)
|
||||
xs2 = element2[mt].xs(energy)
|
||||
assert np.allclose(xs, xs2)
|
||||
assert element[502].scattering_factor == element2[502].scattering_factor
|
||||
assert element.atomic_relaxation.transitions['O3'].equals(
|
||||
element2.atomic_relaxation.transitions['O3'])
|
||||
assert (element.compton_profiles['binding_energy'] ==
|
||||
element2.compton_profiles['binding_energy']).all()
|
||||
assert (element.bremsstrahlung['electron_energy'] ==
|
||||
element2.bremsstrahlung['electron_energy']).all()
|
||||
# Export to hdf5 again
|
||||
element2.export_to_hdf5(filename, 'w')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue