Added Tally.tile_filter(...) routine for multi-group chi with distribcells

This commit is contained in:
Will Boyd 2015-09-12 02:04:21 -04:00
parent 6d3d794c3e
commit 85a67ce17b
2 changed files with 86 additions and 2 deletions

View file

@ -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)

View file

@ -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)