mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 22:26:08 -04:00
Fixed bugs in tally merge method
This commit is contained in:
parent
76f9c462b5
commit
a2ac93a843
2 changed files with 71 additions and 57 deletions
|
|
@ -953,6 +953,10 @@ class MGXS(object):
|
|||
slice_xs.sparse = self.sparse
|
||||
return slice_xs
|
||||
|
||||
# FIXME
|
||||
def merge(self, other):
|
||||
raise NotImplementedError('not yet implemented')
|
||||
|
||||
def print_xs(self, subdomains='all', nuclides='all', xs_type='macro'):
|
||||
"""Print a string representation for the multi-group cross section.
|
||||
|
||||
|
|
|
|||
|
|
@ -695,10 +695,11 @@ class Tally(object):
|
|||
# Return False if only one tally has a delayed group filter
|
||||
tally1_dg = self.contains_filter('delayedgroup')
|
||||
tally2_dg = other.contains_filter('delayedgroup')
|
||||
if sum(tally1_dg, tally2_dg) == 1:
|
||||
if sum([tally1_dg, tally2_dg]) == 1:
|
||||
return False
|
||||
|
||||
# Look to see if all filters are the same, or one or more can be merged
|
||||
merge_filters = False
|
||||
for filter1 in self.filters:
|
||||
mergeable_filter = False
|
||||
|
||||
|
|
@ -758,9 +759,9 @@ class Tally(object):
|
|||
no_nuclides_match = False
|
||||
|
||||
# Either all nuclides should match, or none should
|
||||
if no_nuclides_match:
|
||||
if no_nuclides_match or all_nuclides_match:
|
||||
return True
|
||||
if not no_nuclides_match and not all_nuclides_match:
|
||||
else:
|
||||
return False
|
||||
|
||||
def _can_merge_scores(self, other):
|
||||
|
|
@ -794,15 +795,23 @@ class Tally(object):
|
|||
else:
|
||||
no_scores_match = False
|
||||
|
||||
# Nuclides cannot be specified on 'flux' scores
|
||||
if 'flux' in self.scores or 'flux' in other.scores:
|
||||
if self.nuclides != other.nuclides:
|
||||
return False
|
||||
|
||||
# Either all scores should match, or none should
|
||||
if no_scores_match:
|
||||
if no_scores_match or all_scores_match:
|
||||
return True
|
||||
elif not no_scores_match and not all_scores_match:
|
||||
else:
|
||||
return False
|
||||
|
||||
def can_merge(self, other):
|
||||
"""Determine if another tally can be merged with this one
|
||||
|
||||
If results have been loaded from a statepoint, then tallies are only
|
||||
mergeable along one and only one of filter bins, nuclides or scores.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
other : Tally
|
||||
|
|
@ -821,39 +830,43 @@ class Tally(object):
|
|||
merge_filters = self._can_merge_filters(other)
|
||||
merge_nuclides = self._can_merge_nuclides(other)
|
||||
merge_scores = self._can_merge_scores(other)
|
||||
mergeability = [merge_filters, merge_nuclides, merge_scores]
|
||||
|
||||
# Tallies are mergeable if only one of filters, nuclides and
|
||||
# scores is mergeable
|
||||
if sum(merge_filters, merge_nuclides, merge_scores) == 1:
|
||||
return True
|
||||
else:
|
||||
# If the tally results have been read from the statepoint, we can only
|
||||
# merge along one of filter bins, scores or nuclides
|
||||
if self._results_read and sum(mergeability) > 1:
|
||||
return False
|
||||
else:
|
||||
return all([merge_filters, merge_nuclides, merge_scores])
|
||||
|
||||
def merge(self, other):
|
||||
"""Join another tally with this one
|
||||
"""Merge another tally with this one
|
||||
|
||||
If results have been loaded from a statepoint, then tallies are only
|
||||
mergeable along one and only one of filter bins, nuclides or scores.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
tally : Tally
|
||||
Tally to join with this one
|
||||
Tally to merge with this one
|
||||
|
||||
Returns
|
||||
-------
|
||||
joined_tally : Tally
|
||||
Joined tallies
|
||||
merged_tally : Tally
|
||||
Merged tallies
|
||||
|
||||
"""
|
||||
|
||||
if not self.can_merge(other):
|
||||
msg = 'Unable to join tally ID="{0}" with ' + \
|
||||
msg = 'Unable to merge tally ID="{0}" with ' \
|
||||
'"{1}"'.format(other.id, self.id)
|
||||
raise ValueError(msg)
|
||||
|
||||
# Create deep copy of tally to return as merged tally
|
||||
joined_tally = copy.deepcopy(self)
|
||||
merged_tally = copy.deepcopy(self)
|
||||
|
||||
# Differentiate Tally with a new auto-generated Tally ID
|
||||
joined_tally.id = None
|
||||
merged_tally.id = None
|
||||
|
||||
# Create deep copy of other tally to use for array concatenation
|
||||
other_copy = copy.deepcopy(other)
|
||||
|
|
@ -865,79 +878,76 @@ class Tally(object):
|
|||
for i, filter1 in enumerate(self.filters):
|
||||
for j, filter2 in enumerate(other.filters):
|
||||
if filter1 != filter2 and filter1.can_merge(filter2):
|
||||
other_copy._swap_filters(other_copy.filters[i], filter1)
|
||||
joined_tally.filters[i] = filter1.merge(filter2)
|
||||
join_axis = i
|
||||
other_copy._swap_filters(other_copy.filters[i], filter2)
|
||||
merged_tally.filters[i] = filter1.merge(filter2)
|
||||
merge_axis = i
|
||||
break
|
||||
|
||||
# If two tallies can be merged along nuclide bins
|
||||
elif self._can_merge_nuclides(other):
|
||||
join_axis = self.num_filters
|
||||
if self._can_merge_nuclides(other):
|
||||
merge_axis = self.num_filters
|
||||
|
||||
# Add unique nuclides from other tally to merged tally
|
||||
for nuclide in other.nuclides:
|
||||
if nuclide not in joined_tally.nuclides:
|
||||
joined_tally.add_score(nuclide)
|
||||
if nuclide not in merged_tally.nuclides:
|
||||
merged_tally.add_nuclide(nuclide)
|
||||
|
||||
# If two tallies can be merged along score bins
|
||||
elif self._can_merge_scores(other):
|
||||
join_axis = self.num_filters + 1
|
||||
if self._can_merge_scores(other):
|
||||
merge_axis = self.num_filters + 1
|
||||
|
||||
# Add unique scores from other tally to merged tally
|
||||
for score in other.scores:
|
||||
if score not in joined_tally.scores:
|
||||
joined_tally.add_score(score)
|
||||
if score not in merged_tally.scores:
|
||||
merged_tally.add_score(score)
|
||||
|
||||
else:
|
||||
raise ValueError('Unable to merge tallies')
|
||||
|
||||
# Update filter strides in joined tally
|
||||
joined_tally._update_filter_strides()
|
||||
# Update filter strides in merged tally
|
||||
merged_tally._update_filter_strides()
|
||||
|
||||
# Concatenate sum arrays if present in both tallies
|
||||
if self.sum is not None and other_copy.sum is not None:
|
||||
self_sum = self.get_reshaped_data(value='sum')
|
||||
other_sum = other_copy.get_reshaped_data(value='sum')
|
||||
joined_tally._sum = \
|
||||
np.concatenate((self_sum, other_sum), axis=join_axis)
|
||||
joined_tally._sum = \
|
||||
np.reshape(joined_tally._sum, joined_tally.shape)
|
||||
merged_tally._sum = \
|
||||
np.concatenate((self_sum, other_sum), axis=merge_axis)
|
||||
merged_tally._sum = \
|
||||
np.reshape(merged_tally._sum, merged_tally.shape)
|
||||
|
||||
# Concatenate sum_sq arrays if present in both tallies
|
||||
if self.sum_sq is not None and other.sum_sq is not None:
|
||||
self_sum_sq = self.get_reshaped_data(value='sum_sq')
|
||||
other_sum_sq = other_copy.get_reshaped_data(value='sum_sq')
|
||||
joined_tally._sum_sq = \
|
||||
np.concatenate((self_sum_sq, other_sum_sq), axis=join_axis)
|
||||
joined_tally._sum_sq = \
|
||||
np.reshape(joined_tally._sum_sq, joined_tally.shape)
|
||||
merged_tally._sum_sq = \
|
||||
np.concatenate((self_sum_sq, other_sum_sq), axis=merge_axis)
|
||||
merged_tally._sum_sq = \
|
||||
np.reshape(merged_tally._sum_sq, merged_tally.shape)
|
||||
|
||||
# Concatenate mean arrays if present in both tallies
|
||||
if self.mean is not None and other.mean is not None:
|
||||
self_mean = self.get_reshaped_data(value='mean')
|
||||
other_mean = other_copy.get_reshaped_data(value='mean')
|
||||
joined_tally._mean = \
|
||||
np.concatenate((self_mean, other_mean), axis=join_axis)
|
||||
joined_tally._mean = \
|
||||
np.reshape(joined_tally._mean, joined_tally.shape)
|
||||
merged_tally._mean = \
|
||||
np.concatenate((self_mean, other_mean), axis=merge_axis)
|
||||
merged_tally._mean = \
|
||||
np.reshape(merged_tally._mean, merged_tally.shape)
|
||||
|
||||
# Concatenate std. dev. arrays if present in both tallies
|
||||
if self.std_dev is not None and other.std_dev is not None:
|
||||
self_std_dev = self.get_reshaped_data(value='std_dev')
|
||||
other_std_dev = other_copy.get_reshaped_data(value='std_dev')
|
||||
joined_tally._std_dev = \
|
||||
np.concatenate((self_std_dev, other_std_dev), axis=join_axis)
|
||||
joined_tally._std_dev = \
|
||||
np.reshape(joined_tally._std_dev, joined_tally.shape)
|
||||
merged_tally._std_dev = \
|
||||
np.concatenate((self_std_dev, other_std_dev), axis=merge_axis)
|
||||
merged_tally._std_dev = \
|
||||
np.reshape(merged_tally._std_dev, merged_tally.shape)
|
||||
|
||||
# Sparsify joined tally if both tallies are sparse
|
||||
joined_tally.sparse = self.sparse and other.sparse
|
||||
# Sparsify merged tally if both tallies are sparse
|
||||
merged_tally.sparse = self.sparse and other.sparse
|
||||
|
||||
# Add triggers from other tally to merged tally
|
||||
for trigger in other.triggers:
|
||||
joined_tally.add_trigger(trigger)
|
||||
merged_tally.add_trigger(trigger)
|
||||
|
||||
return joined_tally
|
||||
return merged_tally
|
||||
|
||||
def get_tally_xml(self):
|
||||
"""Return XML representation of the tally
|
||||
|
|
@ -2131,10 +2141,10 @@ class Tally(object):
|
|||
"""
|
||||
|
||||
# Check that results have been read
|
||||
if not self.derived and self.sum is None:
|
||||
msg = 'Unable to use tally arithmetic with Tally ID="{0}" ' \
|
||||
'since it does not contain any results.'.format(self.id)
|
||||
raise ValueError(msg)
|
||||
# if not self.derived and self.sum is None:
|
||||
# msg = 'Unable to use tally arithmetic with Tally ID="{0}" ' \
|
||||
# 'since it does not contain any results.'.format(self.id)
|
||||
# raise ValueError(msg)
|
||||
|
||||
cv.check_type('filter1', filter1, Filter)
|
||||
cv.check_type('filter2', filter2, Filter)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue