mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 21:55:41 -04:00
Removed Tally summation, minimum and maximum routines
This commit is contained in:
parent
f6128ff387
commit
e8ab4b9731
2 changed files with 59 additions and 204 deletions
|
|
@ -1,30 +1,29 @@
|
|||
from openmc import Filter, Nuclide
|
||||
from openmc.checkvalue import check_type
|
||||
|
||||
|
||||
class _CrossScore(object):
|
||||
"""A special-purpose tally score used to encapsulate all combinations of two
|
||||
tally's scores as a cross product for tally arithmetic.
|
||||
tally's scores as a outer product for tally arithmetic.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
left_score : str or _CrossScore
|
||||
The left score in the cross product.
|
||||
The left score in the outer product
|
||||
right_score : str or _CrossScore
|
||||
The right score in the cross product.
|
||||
The right score in the outer product
|
||||
binary_op : str
|
||||
The tally arithmetic binary operator (e.g., '+', '-', etc.) used to
|
||||
combine two tally's scores with this _CrossNuclide.
|
||||
combine two tally's scores with this _CrossNuclide
|
||||
|
||||
Attributes
|
||||
----------
|
||||
left_score : str or _CrossScore
|
||||
The left score in the cross product.
|
||||
The left score in the outer product
|
||||
right_score : str or _CrossScore
|
||||
The right score in the cross product.
|
||||
The right score in the outer product
|
||||
binary_op : str
|
||||
The tally arithmetic binary operator (e.g., '+', '-', etc.) used to
|
||||
combine two tally's scores with this _CrossNuclide.
|
||||
combine two tally's scores with this _CrossNuclide
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -55,17 +54,14 @@ class _CrossScore(object):
|
|||
|
||||
@left_score.setter
|
||||
def left_score(self, left_score):
|
||||
check_type('left score', left_score, (str, _CrossScore))
|
||||
self._left_score = left_score
|
||||
|
||||
@right_score.setter
|
||||
def right_score(self, right_score):
|
||||
check_type('right score', right_score, (str, _CrossScore))
|
||||
self._right_score = right_score
|
||||
|
||||
@binary_op.setter
|
||||
def binary_op(self, binary_op):
|
||||
check_type('binary op', binary_op, str)
|
||||
self._binary_op = binary_op
|
||||
|
||||
def __repr__(self):
|
||||
|
|
@ -76,27 +72,27 @@ class _CrossScore(object):
|
|||
|
||||
class _CrossNuclide(object):
|
||||
"""A special-purpose nuclide used to encapsulate all combinations of two
|
||||
tally's nuclides as a cross product for tally arithmetic.
|
||||
tally's nuclides as a outer product for tally arithmetic.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
left_nuclide : Nuclide or _CrossNuclide
|
||||
The left nuclide in the cross product.
|
||||
The left nuclide in the outer product
|
||||
right_nuclide : Nuclide or _CrossNuclide
|
||||
The right nuclide in the cross product.
|
||||
The right nuclide in the outer product
|
||||
binary_op : str
|
||||
The tally arithmetic binary operator (e.g., '+', '-', etc.) used to
|
||||
combine two tally's nuclides with this _CrossNuclide.
|
||||
combine two tally's nuclides with this _CrossNuclide
|
||||
|
||||
Attributes
|
||||
----------
|
||||
left_nuclide : Nuclide or _CrossNuclide
|
||||
The left nuclide in the cross product.
|
||||
The left nuclide in the outer product
|
||||
right_nuclide : Nuclide or _CrossNuclide
|
||||
The right nuclide in the cross product.
|
||||
The right nuclide in the outer product
|
||||
binary_op : str
|
||||
The tally arithmetic binary operator (e.g., '+', '-', etc.) used to
|
||||
combine two tally's nuclides with this _CrossNuclide.
|
||||
combine two tally's nuclides with this _CrossNuclide
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -127,17 +123,14 @@ class _CrossNuclide(object):
|
|||
|
||||
@left_nuclide.setter
|
||||
def left_nuclide(self, left_nuclide):
|
||||
check_type('left nuclide', left_nuclide, (Nuclide, _CrossNuclide))
|
||||
self._left_nuclide = left_nuclide
|
||||
|
||||
@right_nuclide.setter
|
||||
def right_nuclide(self, right_nuclide):
|
||||
check_type('right nuclide', right_nuclide, (Nuclide, _CrossNuclide))
|
||||
self._right_nuclide = right_nuclide
|
||||
|
||||
@binary_op.setter
|
||||
def binary_op(self, binary_op):
|
||||
check_type('binary op', binary_op, str)
|
||||
self._binary_op = binary_op
|
||||
|
||||
def __repr__(self):
|
||||
|
|
@ -165,32 +158,41 @@ class _CrossNuclide(object):
|
|||
|
||||
class _CrossFilter(object):
|
||||
"""A special-purpose filter used to encapsulate all combinations of two
|
||||
tally's filter bins as a cross product for tally arithmetic.
|
||||
tally's filter bins as a outer product for tally arithmetic.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
left_filter : Filter or _CrossFilter
|
||||
The left filter in the cross product.
|
||||
The left filter in the outer product
|
||||
right_filter : Filter or _CrossFilter
|
||||
The right filter in the cross product.
|
||||
The right filter in the outer product
|
||||
binary_op : str
|
||||
The tally arithmetic binary operator (e.g., '+', '-', etc.) used to
|
||||
combine two tally's filter bins with this _CrossFilter.
|
||||
combine two tally's filter bins with this _CrossFilter
|
||||
|
||||
Attributes
|
||||
----------
|
||||
left_filter : Filter or _CrossFilter
|
||||
The left filter in the cross product.
|
||||
The left filter in the outer product
|
||||
right_filter : Filter or _CrossFilter
|
||||
The right filter in the cross product.
|
||||
The right filter in the outer product
|
||||
binary_op : str
|
||||
The tally arithmetic binary operator (e.g., '+', '-', etc.) used to
|
||||
combine two tally's filter bins with this _CrossFilter.
|
||||
combine two tally's filter bins with this _CrossFilter
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, left_filter=None, right_filter=None, binary_op=None):
|
||||
|
||||
left_type = left_filter.type
|
||||
right_type = right_filter.type
|
||||
self.type = '({0} {1} {2})'.format(left_type, binary_op, right_type)
|
||||
|
||||
self._bins = {}
|
||||
self._bins['left'] = left_filter.bins
|
||||
self._bins['right'] = right_filter.bins
|
||||
self._num_bins = left_filter.num_bins * right_filter.num_bins
|
||||
|
||||
self._left_filter = None
|
||||
self._right_filter = None
|
||||
self._binary_op = None
|
||||
|
|
@ -216,33 +218,34 @@ class _CrossFilter(object):
|
|||
|
||||
@property
|
||||
def type(self):
|
||||
return (self.right_filter.type, self.left_filter.type)
|
||||
return self._type
|
||||
|
||||
@property
|
||||
def bins(self):
|
||||
return (self.right_filter.bins, self.left_filter.bins)
|
||||
return (self._bins['left'], self._bins['right'])
|
||||
|
||||
@property
|
||||
def num_bins(self):
|
||||
return self.left_filter.num_bins * self.right_filter.num_bins
|
||||
return self._num_bins
|
||||
|
||||
@property
|
||||
def stride(self):
|
||||
return self.left_filter.stride * self.right_filter.stride
|
||||
|
||||
@type.setter
|
||||
def type(self, filter_type):
|
||||
self._type = filter_type
|
||||
|
||||
@left_filter.setter
|
||||
def left_filter(self, left_filter):
|
||||
check_type('left filter', left_filter, (Filter, _CrossFilter))
|
||||
self._left_filter = left_filter
|
||||
|
||||
@right_filter.setter
|
||||
def right_filter(self, right_filter):
|
||||
check_type('right filter', right_filter, (Filter, _CrossFilter))
|
||||
self._right_filter = right_filter
|
||||
|
||||
@binary_op.setter
|
||||
def binary_op(self, binary_op):
|
||||
check_type('binary op', binary_op, str)
|
||||
self._binary_op = binary_op
|
||||
|
||||
def __repr__(self):
|
||||
|
|
|
|||
|
|
@ -479,7 +479,7 @@ class Tally(object):
|
|||
string += '{0: <16}{1}{2}\n'.format('\tID', '=\t', self.id)
|
||||
string += '{0: <16}{1}{2}\n'.format('\tName', '=\t', self.name)
|
||||
|
||||
string += '{0: <16}\n'.format('\tFilters')
|
||||
string += '{0: <16}{1}\n'.format('\tFilters', '=\t')
|
||||
|
||||
for filter in self.filters:
|
||||
string += '{0: <16}\t\t{1}\t{2}\n'.format('', filter.type,
|
||||
|
|
@ -864,10 +864,6 @@ class Tally(object):
|
|||
'Tally.get_values(...)'.format(self.id)
|
||||
raise ValueError(msg)
|
||||
|
||||
# Compute batch statistics if not yet computed
|
||||
if not self.with_batch_statistics:
|
||||
self.compute_std_dev()
|
||||
|
||||
############################ FILTERS #########################
|
||||
# Determine the score indices from any of the requested scores
|
||||
if filters:
|
||||
|
|
@ -1027,10 +1023,6 @@ class Tally(object):
|
|||
msg = 'The pandas Python package must be installed on your system'
|
||||
raise ImportError(msg)
|
||||
|
||||
# Compute batch statistics if not yet computed
|
||||
if not self.with_batch_statistics:
|
||||
self.compute_std_dev()
|
||||
|
||||
# Initialize a pandas dataframe for the tally data
|
||||
df = pd.DataFrame()
|
||||
|
||||
|
|
@ -1452,7 +1444,7 @@ class Tally(object):
|
|||
|
||||
"""
|
||||
|
||||
new_tally.name = '({0} {1} {2})'.format(self.name, other.name, binary_op)
|
||||
new_tally.name = '({0} {1} {2})'.format(self.name, binary_op, other.name)
|
||||
|
||||
if self.estimator == other.estimator:
|
||||
new_tally.estimator = self.estimator
|
||||
|
|
@ -1464,12 +1456,12 @@ class Tally(object):
|
|||
# Generate filter "outer products"
|
||||
if self.filters == other.filters:
|
||||
for self_filter in self.filters:
|
||||
new_filter = _CrossScore(self_filter, self_filter, binary_op)
|
||||
new_filter = _CrossFilter(self_filter, self_filter, binary_op)
|
||||
new_tally.add_filter(new_filter)
|
||||
else:
|
||||
all_filters = [self.filters, other.filters]
|
||||
for self_filter, other_filter in itertools.product(*all_filters):
|
||||
new_filter = _CrossScore(self_filter, other_filter, binary_op)
|
||||
new_filter = _CrossFilter(self_filter, other_filter, binary_op)
|
||||
new_tally.add_filter(new_filter)
|
||||
|
||||
# Generate score "outer products"
|
||||
|
|
@ -1487,7 +1479,7 @@ class Tally(object):
|
|||
if self.nuclides == other.nuclides:
|
||||
for self_nuclide in self.nuclides:
|
||||
new_nuclide = _CrossNuclide(self_nuclide, self_nuclide, binary_op)
|
||||
new_tally.add_nuclide(new_nuclide)
|
||||
new_tally.nuclides.append(new_nuclide)
|
||||
else:
|
||||
all_nuclides = [self.nuclides, other.nuclides]
|
||||
for self_nuclide, other_nuclide in itertools.product(*all_nuclides):
|
||||
|
|
@ -1612,7 +1604,7 @@ class Tally(object):
|
|||
"""
|
||||
|
||||
# Check that results have been read
|
||||
if self.mean is None:
|
||||
if 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)
|
||||
|
|
@ -1623,7 +1615,7 @@ class Tally(object):
|
|||
if isinstance(other, Tally):
|
||||
|
||||
# Check that results have been read
|
||||
if other.mean is None:
|
||||
if other.sum is None:
|
||||
msg = 'Unable to use tally arithmetic with Tally ID={0} ' \
|
||||
'since it does not contain any results.'.format(other.id)
|
||||
raise ValueError(msg)
|
||||
|
|
@ -1691,7 +1683,7 @@ class Tally(object):
|
|||
"""
|
||||
|
||||
# Check that results have been read
|
||||
if self.mean is None:
|
||||
if 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)
|
||||
|
|
@ -1702,7 +1694,7 @@ class Tally(object):
|
|||
if isinstance(other, Tally):
|
||||
|
||||
# Check that results have been read
|
||||
if other.mean is None:
|
||||
if other.sum is None:
|
||||
msg = 'Unable to use tally arithmetic with Tally ID={0} ' \
|
||||
'since it does not contain any results.'.format(other.id)
|
||||
raise ValueError(msg)
|
||||
|
|
@ -1771,7 +1763,7 @@ class Tally(object):
|
|||
"""
|
||||
|
||||
# Check that results have been read
|
||||
if self.mean is None:
|
||||
if 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)
|
||||
|
|
@ -1782,7 +1774,7 @@ class Tally(object):
|
|||
if isinstance(other, Tally):
|
||||
|
||||
# Check that results have been read
|
||||
if other.mean is None:
|
||||
if other.sum is None:
|
||||
msg = 'Unable to use tally arithmetic with Tally ID={0} ' \
|
||||
'since it does not contain any results.'.format(other.id)
|
||||
raise ValueError(msg)
|
||||
|
|
@ -1853,7 +1845,7 @@ class Tally(object):
|
|||
"""
|
||||
|
||||
# Check that results have been read
|
||||
if self.mean is None:
|
||||
if 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)
|
||||
|
|
@ -1864,7 +1856,7 @@ class Tally(object):
|
|||
if isinstance(other, Tally):
|
||||
|
||||
# Check that results have been read
|
||||
if other.mean is None:
|
||||
if other.sum is None:
|
||||
msg = 'Unable to use tally arithmetic with Tally ID={0} ' \
|
||||
'since it does not contain any results.'.format(other.id)
|
||||
raise ValueError(msg)
|
||||
|
|
@ -1935,7 +1927,7 @@ class Tally(object):
|
|||
"""
|
||||
|
||||
# Check that results have been read
|
||||
if self.mean is None:
|
||||
if 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)
|
||||
|
|
@ -1946,7 +1938,7 @@ class Tally(object):
|
|||
if isinstance(power, Tally):
|
||||
|
||||
# Check that results have been read
|
||||
if power.mean is None:
|
||||
if power.sum is None:
|
||||
msg = 'Unable to use tally arithmetic with Tally ID={0} ' \
|
||||
'since it does not contain any results.'.format(power.id)
|
||||
raise ValueError(msg)
|
||||
|
|
@ -2081,153 +2073,16 @@ class Tally(object):
|
|||
new_tally = self * -1
|
||||
return new_tally
|
||||
|
||||
def minimum(self, scores=[], filters=[], filter_bins=[],
|
||||
nuclides=[], value='mean'):
|
||||
"""Returns the minimum of a slice of the Tally's data.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
scores : list
|
||||
A list of one or more score strings
|
||||
(e.g., ['absorption', 'nu-fission']; default is [])
|
||||
|
||||
filters : list
|
||||
A list of filter type strings
|
||||
(e.g., ['mesh', 'energy']; default is [])
|
||||
|
||||
filter_bins : list
|
||||
A list of the filter bins corresponding to the filter_types
|
||||
parameter (e.g., [1, (0., 0.625e-6)]; default is []). Each bin in
|
||||
the list is the integer ID for 'material', 'surface', 'cell',
|
||||
'cellborn', and 'universe' Filters. Each bin is an integer for the
|
||||
cell instance ID for 'distribcell Filters. Each bin is a 2-tuple of
|
||||
floats for 'energy' and 'energyout' filters corresponding to the
|
||||
energy boundaries of the bin of interest. The bin is a (x,y,z)
|
||||
3-tuple for 'mesh' filters corresponding to the mesh cell of
|
||||
interest. The order of the bins in the list must correspond of the
|
||||
filter_types parameter.
|
||||
|
||||
nuclides : list
|
||||
A list of nuclide name strings
|
||||
(e.g., ['U-235', 'U-238']; default is [])
|
||||
|
||||
value : str
|
||||
A string for the type of value to return - 'mean' (default),
|
||||
'std_dev', 'rel_err', 'sum', or 'sum_sq' are accepted
|
||||
|
||||
Returns
|
||||
-------
|
||||
float
|
||||
A scalar float of the minimum value in the Tally data indexed by
|
||||
each filter, nuclide and score as listed in the parameters.
|
||||
"""
|
||||
|
||||
data = self.get_values(scores, filters, filter_bins, nuclides, value)
|
||||
return np.min(data)
|
||||
|
||||
def maximum(self, scores=[], filters=[], filter_bins=[],
|
||||
nuclides=[], value='mean'):
|
||||
"""Returns the maximum of a slice of the Tally's data.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
scores : list
|
||||
A list of one or more score strings
|
||||
(e.g., ['absorption', 'nu-fission']; default is [])
|
||||
|
||||
filters : list
|
||||
A list of filter type strings
|
||||
(e.g., ['mesh', 'energy']; default is [])
|
||||
|
||||
filter_bins : list
|
||||
A list of the filter bins corresponding to the filter_types
|
||||
parameter (e.g., [1, (0., 0.625e-6)]; default is []). Each bin in
|
||||
the list is the integer ID for 'material', 'surface', 'cell',
|
||||
'cellborn', and 'universe' Filters. Each bin is an integer for the
|
||||
cell instance ID for 'distribcell Filters. Each bin is a 2-tuple of
|
||||
floats for 'energy' and 'energyout' filters corresponding to the
|
||||
energy boundaries of the bin of interest. The bin is a (x,y,z)
|
||||
3-tuple for 'mesh' filters corresponding to the mesh cell of
|
||||
interest. The order of the bins in the list must correspond of the
|
||||
filter_types parameter.
|
||||
|
||||
nuclides : list
|
||||
A list of nuclide name strings
|
||||
(e.g., ['U-235', 'U-238']; default is [])
|
||||
|
||||
value : str
|
||||
A string for the type of value to return - 'mean' (default),
|
||||
'std_dev', 'rel_err', 'sum', or 'sum_sq' are accepted
|
||||
|
||||
Returns
|
||||
-------
|
||||
float
|
||||
A scalar float of the maximum value in the Tally data indexed by
|
||||
each filter, nuclide and score as listed in the parameters.
|
||||
"""
|
||||
|
||||
data = self.get_values(scores, filters, filter_bins, nuclides, value)
|
||||
return np.max(data)
|
||||
|
||||
def summation(self, scores=[], filters=[], filter_bins=[],
|
||||
nuclides=[], value='mean'):
|
||||
"""Returns the sum of a slice of the Tally's data.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
scores : list
|
||||
A list of one or more score strings
|
||||
(e.g., ['absorption', 'nu-fission']; default is [])
|
||||
|
||||
filters : list
|
||||
A list of filter type strings
|
||||
(e.g., ['mesh', 'energy']; default is [])
|
||||
|
||||
filter_bins : list
|
||||
A list of the filter bins corresponding to the filter_types
|
||||
parameter (e.g., [1, (0., 0.625e-6)]; default is []). Each bin in
|
||||
the list is the integer ID for 'material', 'surface', 'cell',
|
||||
'cellborn', and 'universe' Filters. Each bin is an integer for the
|
||||
cell instance ID for 'distribcell Filters. Each bin is a 2-tuple of
|
||||
floats for 'energy' and 'energyout' filters corresponding to the
|
||||
energy boundaries of the bin of interest. The bin is a (x,y,z)
|
||||
3-tuple for 'mesh' filters corresponding to the mesh cell of
|
||||
interest. The order of the bins in the list must correspond of the
|
||||
filter_types parameter.
|
||||
|
||||
nuclides : list
|
||||
A list of nuclide name strings
|
||||
(e.g., ['U-235', 'U-238']; default is [])
|
||||
|
||||
value : str
|
||||
A string for the type of value to return - 'mean' (default),
|
||||
'std_dev', 'rel_err', 'sum', or 'sum_sq' are accepted
|
||||
|
||||
Returns
|
||||
-------
|
||||
float
|
||||
A scalar float of the sum of the Tally data indexed by
|
||||
each filter, nuclide and score as listed in the parameters.
|
||||
"""
|
||||
|
||||
data = self.get_values(scores, filters, filter_bins, nuclides, value)
|
||||
return np.sum(data)
|
||||
|
||||
def slice(self, scores=[], filters=[], filter_bins=[], nuclides=[]):
|
||||
"""
|
||||
"""
|
||||
|
||||
# Ensure that StatePoint.read_results() was called first
|
||||
if (self.mean is None) or (self.std_dev is None):
|
||||
msg = 'The Tally ID={0} has no data to slice. Call the ' \
|
||||
'StatePoint.read_results() method before using ' \
|
||||
'Tally.slice(...)'.format(self.id)
|
||||
if 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)
|
||||
|
||||
# Compute batch statistics if not yet computed
|
||||
if not self.with_batch_statistics:
|
||||
self.compute_std_dev()
|
||||
|
||||
new_tally = copy.deepcopy(self)
|
||||
new_sum = self.get_values(scores, filters, filter_bins,
|
||||
nuclides, 'sum')
|
||||
|
|
@ -2264,10 +2119,8 @@ class Tally(object):
|
|||
# Create a list of the first energy edge
|
||||
bins = [filter_bin[0] for filter_bin in filter_bins]
|
||||
|
||||
|
||||
|
||||
############################ NUCLIDES ########################
|
||||
# Determine the score indices from any of the requested scores
|
||||
############################ NUCLIDES #########################
|
||||
# Determine the nuclide indices from any of the requested nuclides
|
||||
if nuclides:
|
||||
|
||||
# Initialize list of indices to Nuclides to exclude from slice
|
||||
|
|
@ -2288,15 +2141,14 @@ class Tally(object):
|
|||
for nuclide_index in nuclide_indices[::-1]:
|
||||
new_tally.remove_nuclide(self.nuclides[nuclide_index])
|
||||
|
||||
############################# SCORES #########################
|
||||
############################ SCORES ##########################
|
||||
# Determine the score indices from any of the requested scores
|
||||
if scores:
|
||||
|
||||
# Initialize list of indices to Nuclides to exclude from slice
|
||||
# Initialize list of indices to scores to exclude from slice
|
||||
score_indices = []
|
||||
|
||||
for score in self.scores:
|
||||
|
||||
if score not in scores:
|
||||
score_index = self.get_score_index(score)
|
||||
score_indices.append(score_index)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue