I believe I successfully implemented condensation of diffusion coefficients (as opposed to transport cross sections).

This commit is contained in:
Miriam Rathbun 2021-11-22 22:46:40 -07:00
parent e61db57485
commit 672bb9e431

View file

@ -3154,30 +3154,133 @@ class DiffusionCoefficient(TransportXS):
raise ValueError(msg)
# Switch EnergyoutFilter to EnergyFilter
if 'scatter-1' in self.tallies:
p1_tally = self.tallies['scatter-1']
old_filt = p1_tally.filters[-2]
new_filt = openmc.EnergyFilter(old_filt.values)
p1_tally.filters[-2] = new_filt
p1_tally = p1_tally.get_slice(filters=[openmc.LegendreFilter],
filter_bins=[('P1',)],squeeze=True)
p1_tally._scores = ['scatter-1']
total_xs = self.tallies['total'] / self.tallies['flux (tracklength)']
trans_corr = p1_tally / self.tallies['flux (analog)']
transport = total_xs - trans_corr
diff_coef = transport**(-1) / 3.0
self._xs_tally = diff_coef
self._compute_xs()
else:
self._xs_tally = self.tallies[self._rxn_type] / self.tallies['flux (tracklength)']
self._compute_xs()
return self._xs_tally
def get_condensed_xs(self, coarse_groups, condense_diff_coef=True):
"""Construct an energy-condensed version of this cross section.
Parameters
----------
coarse_groups : openmc.mgxs.EnergyGroups
The coarse energy group structure of interest
Returns
-------
MGXS
A new MGXS condensed to the group structure of interest
"""
cv.check_type('coarse_groups', coarse_groups, EnergyGroups)
cv.check_less_than('coarse groups', coarse_groups.num_groups,
self.num_groups, equality=True)
cv.check_value('upper coarse energy', coarse_groups.group_edges[-1],
[self.energy_groups.group_edges[-1]])
cv.check_value('lower coarse energy', coarse_groups.group_edges[0],
[self.energy_groups.group_edges[0]])
# Clone this MGXS to initialize the condensed version
condensed_xs = copy.deepcopy(self)
if condense_diff_coef:
p1_tally = self.tallies['scatter-1']
old_filt = p1_tally.filters[-2]
new_filt = openmc.EnergyFilter(old_filt.values)
p1_tally.filters[-2] = new_filt
# Slice Legendre expansion filter and change name of score
p1_tally = p1_tally.get_slice(filters=[openmc.LegendreFilter],
filter_bins=[('P1',)],
squeeze=True)
p1_tally._scores = ['scatter-1']
# Compute total cross section
total_xs = self.tallies['total'] / self.tallies['flux (tracklength)']
# Compute transport correction term
trans_corr = p1_tally / self.tallies['flux (analog)']
# Compute the diffusion coefficient
transport = total_xs - trans_corr
diff_coef = transport**(-1) / 3.0
self._xs_tally = diff_coef
self._compute_xs()
diff_coef *= self.tallies['flux (tracklength)']
flux_tally = condensed_xs.tallies['flux (tracklength)']
condensed_xs._tallies = OrderedDict()
condensed_xs._tallies[self._rxn_type] = diff_coef
condensed_xs._tallies['flux (tracklength)'] = flux_tally
condensed_xs._rxn_rate_tally = diff_coef
condensed_xs._xs_tally = None
condensed_xs._sparse = False
condensed_xs._energy_groups = coarse_groups
return self._xs_tally
else:
condensed_xs._rxn_rate_tally = None
condensed_xs._xs_tally = None
condensed_xs._sparse = False
condensed_xs._energy_groups = coarse_groups
# Build energy indices to sum across
energy_indices = []
for group in range(coarse_groups.num_groups, 0, -1):
low, high = coarse_groups.get_group_bounds(group)
low_index = np.where(self.energy_groups.group_edges == low)[0][0]
energy_indices.append(low_index)
fine_edges = self.energy_groups.group_edges
# Condense each of the tallies to the coarse group structure
for tally in condensed_xs.tallies.values():
# Make condensed tally derived and null out sum, sum_sq
tally._derived = True
tally._sum = None
tally._sum_sq = None
# Get tally data arrays reshaped with one dimension per filter
mean = tally.get_reshaped_data(value='mean')
std_dev = tally.get_reshaped_data(value='std_dev')
# Sum across all applicable fine energy group filters
for i, tally_filter in enumerate(tally.filters):
if not isinstance(tally_filter, (openmc.EnergyFilter,
openmc.EnergyoutFilter)):
continue
elif len(tally_filter.bins) != len(fine_edges) - 1:
continue
elif not np.allclose(tally_filter.bins[:, 0], fine_edges[:-1]):
continue
else:
cedge = coarse_groups.group_edges
tally_filter.values = cedge
tally_filter.bins = np.vstack((cedge[:-1], cedge[1:])).T
mean = np.add.reduceat(mean, energy_indices, axis=i)
std_dev = np.add.reduceat(std_dev**2, energy_indices,
axis=i)
std_dev = np.sqrt(std_dev)
# Reshape condensed data arrays with one dimension for all filters
mean = np.reshape(mean, tally.shape)
std_dev = np.reshape(std_dev, tally.shape)
# Override tally's data with the new condensed data
tally._mean = mean
tally._std_dev = std_dev
# Compute the energy condensed multi-group cross section
condensed_xs.sparse = self.sparse
return condensed_xs
class AbsorptionXS(MGXS):
r"""An absorption multi-group cross section.