mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-26 21:25:36 -04:00
Added Tally.tile_filter(...) routine for multi-group chi with distribcells
This commit is contained in:
parent
6d3d794c3e
commit
85a67ce17b
2 changed files with 86 additions and 2 deletions
|
|
@ -1059,6 +1059,7 @@ class ScatterMatrixXS(MultiGroupXS):
|
|||
scatter_p1 = scatter_p1.get_slice(scores=['scatter-P1'])
|
||||
energy_filter = openmc.Filter(type='energy')
|
||||
energy_filter.bins = self.energy_groups.group_edges
|
||||
energy_filter.num_bins = self.num_groups
|
||||
scatter_p1 = scatter_p1.diagonalize_filter(energy_filter)
|
||||
rxn_tally = self.tallies['scatter'] - scatter_p1
|
||||
else:
|
||||
|
|
@ -1281,6 +1282,9 @@ class Chi(MultiGroupXS):
|
|||
sum_nu_fission_in = nu_fission_in.summation(filters=['energy'],
|
||||
filter_bins=energy_bins)
|
||||
|
||||
# FIXME: Need ability to override energy groups with group numbers
|
||||
# FIXME: Reverse from fast to thermal with energy groups
|
||||
|
||||
# FIXME: CrossFilter for energy + energy messes up tally arithmetic
|
||||
sum_nu_fission_in.remove_filter(sum_nu_fission_in.filters[-1])
|
||||
|
||||
|
|
@ -1291,7 +1295,12 @@ class Chi(MultiGroupXS):
|
|||
filter_bins=energy_bins)
|
||||
|
||||
# FIXME: CrossFilter for energy + energy messes up tally arithmetic
|
||||
norm.remove_filter(sum_nu_fission_in.filters[-1])
|
||||
norm.remove_filter(norm.filters[-1])
|
||||
|
||||
energy_filter = openmc.Filter(type='energyout')
|
||||
energy_filter.bins = self.energy_groups.group_edges
|
||||
energy_filter.num_bins = self.num_groups
|
||||
norm = norm.tile_filter(energy_filter)
|
||||
|
||||
self._xs_tally /= norm
|
||||
self._xs_tally._mean = np.nan_to_num(self._xs_tally.mean)
|
||||
|
|
|
|||
|
|
@ -2387,6 +2387,74 @@ class Tally(object):
|
|||
|
||||
return tally_sum
|
||||
|
||||
def tile_filter(self, new_filter):
|
||||
"""Combines filters, scores and nuclides with another tally.
|
||||
|
||||
This is a helper method for the tally arithmetic methods. The filters,
|
||||
scores and nuclides from both tallies are enumerated into all possible
|
||||
combinations and expressed as CrossFilter, CrossScore and
|
||||
CrossNuclide objects in the new derived tally.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
other : Tally
|
||||
The tally on the right hand side of the outer product
|
||||
binary_op : {'+', '-', '*', '/', '^'}
|
||||
The binary operation in the outer product
|
||||
|
||||
Returns
|
||||
-------
|
||||
Tally
|
||||
A new Tally outer that is the outer product with this one.
|
||||
|
||||
"""
|
||||
|
||||
cv.check_type('new_filter', new_filter, Filter)
|
||||
|
||||
if new_filter in self.filters:
|
||||
msg = 'Unable to tile Tally ID="{0}" which already ' \
|
||||
'contains a "{1}" filter'.format(self.id, new_filter.type)
|
||||
raise ValueError(msg)
|
||||
|
||||
new_tally = copy.deepcopy(self)
|
||||
new_tally.add_filter(new_filter)
|
||||
|
||||
num_filter_bins = new_tally.num_filter_bins
|
||||
num_nuclides = new_tally.num_nuclides
|
||||
num_score_bins = new_tally.num_score_bins
|
||||
new_shape = (num_filter_bins, num_nuclides, num_score_bins)
|
||||
|
||||
repeat_indices = np.arange(0, new_tally.num_bins, new_filter.num_bins)
|
||||
repeat_factor = new_filter.num_bins
|
||||
|
||||
if self.sum is not None:
|
||||
new_tally._sum = np.zeros(new_shape, dtype=np.float64)
|
||||
if self.sum_sq is not None:
|
||||
new_tally._sum_sq = np.zeros(new_shape, dtype=np.float64)
|
||||
if self.mean is not None:
|
||||
new_tally._mean = np.zeros(new_shape, dtype=np.float64)
|
||||
if self.std_dev is not None:
|
||||
new_tally._std_dev = np.zeros(new_shape, dtype=np.float64)
|
||||
|
||||
for i in range(repeat_factor):
|
||||
if self.sum is not None:
|
||||
new_tally._sum[repeat_indices+i, :, :] = self.sum
|
||||
if self.sum_sq is not None:
|
||||
new_tally._sum_sq[repeat_indices+i, :, :] = self.sum_sq
|
||||
if self.mean is not None:
|
||||
new_tally._mean[repeat_indices+i, :, :] = self.mean
|
||||
if self.std_dev is not None:
|
||||
new_tally._std_dev[repeat_indices+i, :, :] = self.std_dev
|
||||
|
||||
# Correct each Filter's stride
|
||||
stride = new_tally.num_nuclides * new_tally.num_score_bins
|
||||
for filter in reversed(new_tally.filters):
|
||||
filter.stride = stride
|
||||
stride *= filter.num_bins
|
||||
|
||||
return new_tally
|
||||
|
||||
|
||||
def diagonalize_filter(self, new_filter):
|
||||
"""Combines filters, scores and nuclides with another tally.
|
||||
|
||||
|
|
@ -2424,7 +2492,14 @@ class Tally(object):
|
|||
num_score_bins = new_tally.num_score_bins
|
||||
new_shape = (num_filter_bins, num_nuclides, num_score_bins)
|
||||
|
||||
diag_indices = np.arange(0, new_tally.num_filter_bins, new_filter.num_bins+1)
|
||||
indices = np.arange(0, new_filter.num_bins**2, new_filter.num_bins+1)
|
||||
diag_indices = np.zeros(self.num_bins, dtype=np.int)
|
||||
diag_factor = self.num_bins / new_filter.num_bins
|
||||
|
||||
for i in range(diag_factor):
|
||||
start = i * new_filter.num_bins
|
||||
end = (i+1) * new_filter.num_bins
|
||||
diag_indices[start:end] = indices + (i * new_filter.num_bins**2)
|
||||
|
||||
if self.sum is not None:
|
||||
new_tally._sum = np.zeros(new_shape, dtype=np.float64)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue