From 672bb9e431158b4f1c352701f8843f83063df232 Mon Sep 17 00:00:00 2001 From: Miriam Rathbun Date: Mon, 22 Nov 2021 22:46:40 -0700 Subject: [PATCH 1/3] I believe I successfully implemented condensation of diffusion coefficients (as opposed to transport cross sections). --- openmc/mgxs/mgxs.py | 125 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 114 insertions(+), 11 deletions(-) diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index ff739fe851..6502a5ef2c 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -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. From 12db3d12ac2baca91683dff70edcc77a84f6ab5e Mon Sep 17 00:00:00 2001 From: Miriam Rathbun Date: Mon, 22 Nov 2021 22:56:13 -0700 Subject: [PATCH 2/3] Updated results from mgxs_library_condense to reflect new changes. --- .../mgxs_library_condense/results_true.dat | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/regression_tests/mgxs_library_condense/results_true.dat b/tests/regression_tests/mgxs_library_condense/results_true.dat index 349d9debe2..ac0dd2163e 100644 --- a/tests/regression_tests/mgxs_library_condense/results_true.dat +++ b/tests/regression_tests/mgxs_library_condense/results_true.dat @@ -214,16 +214,16 @@ 28 2 2 y-min out 1 total 4.548 0.156691 mesh 1 group in nuclide mean std. dev. x y z -0 1 1 1 1 total 0.757948 0.035459 -2 1 2 1 1 total 0.779112 0.047034 -1 2 1 1 1 total 0.787475 0.050368 -3 2 2 1 1 total 0.769656 0.058065 +0 1 1 1 1 total 0.931945 0.045510 +2 1 2 1 1 total 0.962029 0.072431 +1 2 1 1 1 total 0.971983 0.071094 +3 2 2 1 1 total 0.930013 0.102254 mesh 1 group in nuclide mean std. dev. x y z -0 1 1 1 1 total 0.757948 0.035459 -2 1 2 1 1 total 0.778934 0.047027 -1 2 1 1 1 total 0.787475 0.050368 -3 2 2 1 1 total 0.769656 0.058065 +0 1 1 1 1 total 0.931945 0.045510 +2 1 2 1 1 total 0.961685 0.072418 +1 2 1 1 1 total 0.971983 0.071094 +3 2 2 1 1 total 0.930013 0.102254 mesh 1 delayedgroup group in nuclide mean std. dev. x y z 0 1 1 1 1 1 total 0.000006 3.699363e-07 From 985b2d26960f4a9765b189ba3832baf1f0f33b3b Mon Sep 17 00:00:00 2001 From: Miriam Kreher Date: Fri, 26 Aug 2022 21:07:15 -0400 Subject: [PATCH 3/3] Removed the option to condense transport cross sections instead of diffusion coefficients. --- openmc/mgxs/mgxs.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 6502a5ef2c..8760dfc36c 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -3154,6 +3154,8 @@ class DiffusionCoefficient(TransportXS): raise ValueError(msg) # Switch EnergyoutFilter to EnergyFilter + # If 'scatter-1' is not in tallies, it is because the transport correction has + # already occurred on this MGXS in another function or in a previous call to this function. if 'scatter-1' in self.tallies: p1_tally = self.tallies['scatter-1'] old_filt = p1_tally.filters[-2] @@ -3176,7 +3178,7 @@ class DiffusionCoefficient(TransportXS): return self._xs_tally - def get_condensed_xs(self, coarse_groups, condense_diff_coef=True): + def get_condensed_xs(self, coarse_groups): """Construct an energy-condensed version of this cross section. Parameters @@ -3202,7 +3204,9 @@ class DiffusionCoefficient(TransportXS): # Clone this MGXS to initialize the condensed version condensed_xs = copy.deepcopy(self) - if condense_diff_coef: + # If 'scatter-1' is not in tallies, it is because the transport correction has + # already occurred on this MGXS in another function or in a previous call to this function. + 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)