mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 22:26:08 -04:00
Refactor ThermalScattering.add_temperature_from_ace() to use from_ace()
This commit is contained in:
parent
3a021a2438
commit
b6a866f7b7
1 changed files with 29 additions and 133 deletions
|
|
@ -191,8 +191,6 @@ class ThermalScattering(EqualityMixin):
|
|||
self.name = name
|
||||
self.atomic_weight_ratio = atomic_weight_ratio
|
||||
self.kTs = kTs
|
||||
self.temperatures = [str(int(round(kT / K_BOLTZMANN))) + "K"
|
||||
for kT in kTs]
|
||||
self.elastic_xs = {}
|
||||
self.elastic_mu_out = {}
|
||||
self.inelastic_xs = {}
|
||||
|
|
@ -208,6 +206,10 @@ class ThermalScattering(EqualityMixin):
|
|||
else:
|
||||
return "<Thermal Scattering Data>"
|
||||
|
||||
@property
|
||||
def temperatures(self):
|
||||
return ["{}K".format(int(round(kT / K_BOLTZMANN))) for kT in self.kTs]
|
||||
|
||||
def export_to_hdf5(self, path, mode='a'):
|
||||
"""Export table to an HDF5 file.
|
||||
|
||||
|
|
@ -277,142 +279,36 @@ class ThermalScattering(EqualityMixin):
|
|||
Thermal scattering data
|
||||
|
||||
"""
|
||||
if isinstance(ace_or_filename, Table):
|
||||
ace = ace_or_filename
|
||||
else:
|
||||
ace = get_table(ace_or_filename)
|
||||
data = ThermalScattering.from_ace(ace_or_filename, name)
|
||||
|
||||
# Get new name that is GND-consistent
|
||||
ace_name, xs = ace.name.split('.')
|
||||
if name is None:
|
||||
if ace_name.lower() in _THERMAL_NAMES:
|
||||
name = _THERMAL_NAMES[ace_name.lower()]
|
||||
else:
|
||||
# Make an educated guess? This actually works well for JEFF-3.2
|
||||
# which stupidly uses names like lw00.32t, lw01.32t, etc. for
|
||||
# different temperatures
|
||||
matches = get_close_matches(
|
||||
ace_name.lower(), _THERMAL_NAMES.keys(), cutoff=0.5)
|
||||
if len(matches) > 0:
|
||||
name = _THERMAL_NAMES[matches[0]]
|
||||
else:
|
||||
# OK, we give up. Just use the ACE name.
|
||||
name = 'c_' + ace.name
|
||||
warn('Thermal scattering material "{}" is not recognized. '
|
||||
'Assigning a name of {}.'.format(ace.name, name))
|
||||
# Check if temprature already exists
|
||||
strT = data.temperatures[0]
|
||||
if strT in self.temperatures:
|
||||
warn('S(a,b) data at T={} already exists.'.format(strT))
|
||||
return
|
||||
|
||||
# If this ACE data matches the data within self then get the data
|
||||
if ace.temperature not in self.kTs:
|
||||
if name == self.name:
|
||||
# Add temperature and kTs
|
||||
strT = str(int(round(ace.temperature / K_BOLTZMANN))) + "K"
|
||||
self.temperatures.append(strT)
|
||||
self.kTs.append(ace.temperature)
|
||||
# Check that name matches
|
||||
if data.name != self.name:
|
||||
raise ValueError('Data provided for an incorrect material.')
|
||||
|
||||
# Incoherent inelastic scattering cross section
|
||||
idx = ace.jxs[1]
|
||||
n_energy = int(ace.xss[idx])
|
||||
energy = ace.xss[idx + 1: idx + 1 + n_energy]
|
||||
xs = ace.xss[idx + 1 + n_energy: idx + 1 + 2 * n_energy]
|
||||
self.inelastic_xs[strT] = Tabulated1D(energy, xs)
|
||||
# Add temperature
|
||||
self.kTs += data.kTs
|
||||
|
||||
# Make sure secondary_mode is always equal. This should always
|
||||
# be the case, but to reduce future debugging should something
|
||||
# change, this will alert the developers to the issue.
|
||||
if ace.nxs[7] == 0:
|
||||
secondary_mode = 'equal'
|
||||
elif ace.nxs[7] == 1:
|
||||
secondary_mode = 'skewed'
|
||||
elif ace.nxs[7] == 2:
|
||||
secondary_mode = 'continuous'
|
||||
# Add inelastic cross section and distributions
|
||||
if strT in data.inelastic_xs:
|
||||
self.inelastic_xs[strT] = data.inelastic_xs[strT]
|
||||
if strT in data.inelastic_e_out:
|
||||
self.inelastic_e_out[strT] = data.inelastic_e_out[strT]
|
||||
if strT in data.inelastic_mu_out:
|
||||
self.inelastic_mu_out[strT] = data.inelastic_mu_out[strT]
|
||||
if strT in data.inelastic_dist:
|
||||
self.inelastic_dist[strT] = data.inelastic_dist[strT]
|
||||
|
||||
if secondary_mode != self.secondary_mode:
|
||||
raise ValueError('Secondary Modes are inconsistent.')
|
||||
|
||||
n_energy_out = ace.nxs[4]
|
||||
if self.secondary_mode in ('equal', 'skewed'):
|
||||
n_mu = ace.nxs[3]
|
||||
idx = ace.jxs[3]
|
||||
self.inelastic_e_out[strT] = \
|
||||
ace.xss[idx:idx + n_energy * n_energy_out * (n_mu + 2):
|
||||
n_mu + 2]
|
||||
self.inelastic_e_out[strT].shape = \
|
||||
(n_energy, n_energy_out)
|
||||
|
||||
self.inelastic_mu_out[strT] = \
|
||||
ace.xss[idx:idx + n_energy * n_energy_out * (n_mu + 2)]
|
||||
self.inelastic_mu_out[strT].shape = \
|
||||
(n_energy, n_energy_out, n_mu + 2)
|
||||
self.inelastic_mu_out[strT] = \
|
||||
self.inelastic_mu_out[strT][:, :, 1:]
|
||||
else:
|
||||
n_mu = ace.nxs[3] - 1
|
||||
idx = ace.jxs[3]
|
||||
locc = ace.xss[idx:idx + n_energy].astype(int)
|
||||
n_energy_out = \
|
||||
ace.xss[idx + n_energy:idx + 2 * n_energy].astype(int)
|
||||
energy_out = []
|
||||
mu_out = []
|
||||
for i in range(n_energy):
|
||||
idx = locc[i]
|
||||
|
||||
# Outgoing energy distribution for incoming energy i
|
||||
e = ace.xss[idx + 1:idx + 1 + n_energy_out[i]*(n_mu + 3):
|
||||
n_mu + 3]
|
||||
p = ace.xss[idx + 2:idx + 2 + n_energy_out[i]*(n_mu + 3):
|
||||
n_mu + 3]
|
||||
c = ace.xss[idx + 3:idx + 3 + n_energy_out[i]*(n_mu + 3):
|
||||
n_mu + 3]
|
||||
eout_i = Tabular(e, p, 'linear-linear', ignore_negative=True)
|
||||
eout_i.c = c
|
||||
|
||||
# Outgoing angle distribution for each
|
||||
# (incoming, outgoing) energy pair
|
||||
mu_i = []
|
||||
for j in range(n_energy_out[i]):
|
||||
mu = ace.xss[idx + 4:idx + 4 + n_mu]
|
||||
p_mu = 1. / n_mu * np.ones(n_mu)
|
||||
mu_ij = Discrete(mu, p_mu)
|
||||
mu_ij.c = np.cumsum(p_mu)
|
||||
mu_i.append(mu_ij)
|
||||
idx += 3 + n_mu
|
||||
|
||||
energy_out.append(eout_i)
|
||||
mu_out.append(mu_i)
|
||||
|
||||
# Create correlated angle-energy distribution
|
||||
breakpoints = [n_energy]
|
||||
interpolation = [2]
|
||||
energy = self.inelastic_xs[strT].x
|
||||
self.inelastic_dist[strT] = CorrelatedAngleEnergy(
|
||||
breakpoints, interpolation, energy, energy_out, mu_out)
|
||||
|
||||
# Incoherent/coherent elastic scattering cross section
|
||||
idx = ace.jxs[4]
|
||||
if idx != 0:
|
||||
n_energy = int(ace.xss[idx])
|
||||
energy = ace.xss[idx + 1: idx + 1 + n_energy]
|
||||
P = ace.xss[idx + 1 + n_energy: idx + 1 + 2 * n_energy]
|
||||
|
||||
if ace.nxs[5] == 4:
|
||||
self.elastic_xs[strT] = CoherentElastic(energy, P)
|
||||
else:
|
||||
self.elastic_xs[strT] = Tabulated1D(energy, P)
|
||||
|
||||
# Angular distribution
|
||||
n_mu = ace.nxs[6]
|
||||
if n_mu != -1:
|
||||
idx = ace.jxs[6]
|
||||
self.elastic_mu_out[strT] = \
|
||||
ace.xss[idx:idx + n_energy * n_mu]
|
||||
self.elastic_mu_out[strT].shape = \
|
||||
(n_energy, n_mu)
|
||||
|
||||
else:
|
||||
raise ValueError('Data provided for an incorrect library')
|
||||
else:
|
||||
warn('{} already has data for T={:.1f} K'.format(
|
||||
self.name, ace.temperature / K_BOLTZMANN))
|
||||
# Add elastic cross sectoin and angular distribution
|
||||
if strT in data.elastic_xs:
|
||||
self.elastic_xs[strT] = data.elastic_xs[strT]
|
||||
if strT in data.elastic_mu_out:
|
||||
self.elastic_mu_out[strT] = data.elastic_mu_out[strT]
|
||||
|
||||
@classmethod
|
||||
def from_hdf5(cls, group_or_filename):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue