mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 13:45:36 -04:00
Fixed merge conflicts with tally-align branch
This commit is contained in:
commit
f7d3380251
17 changed files with 439 additions and 384 deletions
|
|
@ -92,7 +92,7 @@ class MGXS(object):
|
|||
xs_tally : Tally
|
||||
Derived tally for the multi-group cross section. This attribute
|
||||
is None unless the multi-group cross section has been computed.
|
||||
num_sumbdomains : Integral
|
||||
num_subdomains : Integral
|
||||
The number of subdomains is unity for 'material', 'cell' and 'universe'
|
||||
domain types. When the This is equal to the number of cell instances
|
||||
for 'distribcell' domain types (it is equal to unity prior to loading
|
||||
|
|
@ -790,7 +790,7 @@ class MGXS(object):
|
|||
|
||||
# Reshape condensed data arrays with one dimension for all filters
|
||||
new_shape = \
|
||||
(tally.num_filter_bins, tally.num_nuclides, tally.num_score_bins,)
|
||||
(tally.num_filter_bins, tally.num_nuclides, tally.num_scores,)
|
||||
mean = np.reshape(mean, new_shape)
|
||||
std_dev = np.reshape(std_dev, new_shape)
|
||||
|
||||
|
|
@ -874,7 +874,7 @@ class MGXS(object):
|
|||
|
||||
# Reshape averaged data arrays with one dimension for all filters
|
||||
new_shape = \
|
||||
(tally.num_filter_bins, tally.num_nuclides, tally.num_score_bins,)
|
||||
(tally.num_filter_bins, tally.num_nuclides, tally.num_scores,)
|
||||
mean = np.reshape(mean, new_shape)
|
||||
std_dev = np.reshape(std_dev, new_shape)
|
||||
|
||||
|
|
@ -1458,7 +1458,7 @@ class AbsorptionXS(MGXS):
|
|||
class CaptureXS(MGXS):
|
||||
"""A capture multi-group cross section.
|
||||
|
||||
The Neutron capture reaction rate is defined as the difference between
|
||||
The neutron capture reaction rate is defined as the difference between
|
||||
OpenMC's 'absorption' and 'fission' reaction rate score types. This includes
|
||||
not only radiative capture, but all forms of neutron disappearance aside
|
||||
from fission (e.g., MT > 100).
|
||||
|
|
@ -1760,8 +1760,8 @@ class ScatterMatrixXS(MGXS):
|
|||
if self.correction == 'P0':
|
||||
scatter_p1 = self.tallies['scatter-P1']
|
||||
scatter_p1 = scatter_p1.get_slice(scores=['scatter-P1'])
|
||||
energy_filter = copy.deepcopy(self.tallies['scatter'].
|
||||
find_filter('energy'))
|
||||
energy_filter = self.tallies['scatter'].find_filter('energy')
|
||||
energy_filter = copy.deepcopy(energy_filter)
|
||||
scatter_p1 = scatter_p1.diagonalize_filter(energy_filter)
|
||||
rxn_tally = self.tallies['scatter'] - scatter_p1
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ if sys.version > '3':
|
|||
|
||||
|
||||
class StatePoint(object):
|
||||
"""State information on a simulation at a certain point in time (at the end of a
|
||||
given batch). Statepoints can be used to analyze tally results as well as
|
||||
restart a simulation.
|
||||
"""State information on a simulation at a certain point in time (at the end
|
||||
of a given batch). Statepoints can be used to analyze tally results as well
|
||||
as restart a simulation.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
|
|
@ -391,15 +391,10 @@ class StatePoint(object):
|
|||
nuclide = openmc.Nuclide(name.decode().strip())
|
||||
tally.add_nuclide(nuclide)
|
||||
|
||||
# Read score bins
|
||||
n_score_bins = self._f['{0}{1}/n_score_bins'.format(base, tally_key)].value
|
||||
|
||||
tally.num_score_bins = n_score_bins
|
||||
|
||||
scores = self._f['{0}{1}/score_bins'.format(
|
||||
base, tally_key)].value
|
||||
n_user_scores = self._f['{0}{1}/n_user_score_bins'
|
||||
.format(base, tally_key)].value
|
||||
n_score_bins = self._f['{0}{1}/n_score_bins'
|
||||
.format(base, tally_key)].value
|
||||
|
||||
# Compute and set the filter strides
|
||||
for i in range(n_filters):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import numpy as np
|
||||
import re
|
||||
|
||||
import openmc
|
||||
from openmc.region import Region
|
||||
|
|
@ -520,12 +521,19 @@ class Summary(object):
|
|||
# Create Tally object and assign basic properties
|
||||
tally = openmc.Tally(tally_id, tally_name)
|
||||
|
||||
# Read scattering moment order strings (e.g., P3, Y-1,2, etc.)
|
||||
moments = self._f['{0}/moment_orders'.format(subbase)].value
|
||||
|
||||
# Read score metadata
|
||||
scores = self._f['{0}/score_bins'.format(subbase)].value
|
||||
for score in scores:
|
||||
tally.add_score(score.decode())
|
||||
num_score_bins = self._f['{0}/n_score_bins'.format(subbase)][...]
|
||||
tally.num_score_bins = num_score_bins
|
||||
for j, score in enumerate(scores):
|
||||
score = score.decode()
|
||||
|
||||
# If this is a moment, use generic moment order
|
||||
pattern = r'-n$|-pn$|-yn$'
|
||||
score = re.sub(pattern, '-' + moments[j].decode(), score)
|
||||
|
||||
tally.add_score(score)
|
||||
|
||||
# Read filter metadata
|
||||
num_filters = self._f['{0}/n_filters'.format(subbase)].value
|
||||
|
|
|
|||
|
|
@ -25,8 +25,14 @@ if sys.version_info[0] >= 3:
|
|||
# "Static" variable for auto-generated Tally IDs
|
||||
AUTO_TALLY_ID = 10000
|
||||
|
||||
# The tally arithmetic product types. The tensor product performs the full
|
||||
# cross product of the data in two tallies with respect to a specified axis
|
||||
# (filters, nuclides, or scores). The entrywise product performs the arithmetic
|
||||
# operation entrywise across the entries in two tallies with respect to a
|
||||
# specified axis.
|
||||
_PRODUCT_TYPES = ['tensor', 'entrywise']
|
||||
|
||||
|
||||
def reset_auto_tally_id():
|
||||
global AUTO_TALLY_ID
|
||||
AUTO_TALLY_ID = 10000
|
||||
|
|
@ -60,10 +66,6 @@ class Tally(object):
|
|||
Type of estimator for the tally
|
||||
triggers : list of openmc.trigger.Trigger
|
||||
List of tally triggers
|
||||
num_score_bins : Integral
|
||||
Total number of scores, accounting for the fact that a single
|
||||
user-specified score, e.g. scatter-P3 or flux-Y2,2, might have multiple
|
||||
bins
|
||||
num_scores : Integral
|
||||
Total number of user-specified scores
|
||||
num_filter_bins : Integral
|
||||
|
|
@ -104,7 +106,6 @@ class Tally(object):
|
|||
self._estimator = None
|
||||
self._triggers = []
|
||||
|
||||
self._num_score_bins = 0
|
||||
self._num_realizations = 0
|
||||
self._with_summary = False
|
||||
|
||||
|
|
@ -128,7 +129,6 @@ class Tally(object):
|
|||
clone.id = self.id
|
||||
clone.name = self.name
|
||||
clone.estimator = self.estimator
|
||||
clone.num_score_bins = self.num_score_bins
|
||||
clone.num_realizations = self.num_realizations
|
||||
clone._sum = copy.deepcopy(self._sum, memo)
|
||||
clone._sum_sq = copy.deepcopy(self._sum_sq, memo)
|
||||
|
|
@ -258,10 +258,6 @@ class Tally(object):
|
|||
def num_scores(self):
|
||||
return len(self._scores)
|
||||
|
||||
@property
|
||||
def num_score_bins(self):
|
||||
return self._num_score_bins
|
||||
|
||||
@property
|
||||
def num_filter_bins(self):
|
||||
num_bins = 1
|
||||
|
|
@ -275,12 +271,12 @@ class Tally(object):
|
|||
def num_bins(self):
|
||||
num_bins = self.num_filter_bins
|
||||
num_bins *= self.num_nuclides
|
||||
num_bins *= self.num_score_bins
|
||||
num_bins *= self.num_scores
|
||||
return num_bins
|
||||
|
||||
@property
|
||||
def shape(self):
|
||||
return (self.num_filter_bins, self.num_nuclides, self.num_score_bins)
|
||||
return (self.num_filter_bins, self.num_nuclides, self.num_scores)
|
||||
|
||||
@property
|
||||
def estimator(self):
|
||||
|
|
@ -496,9 +492,13 @@ class Tally(object):
|
|||
'not a string'.format(score, self.id)
|
||||
raise ValueError(msg)
|
||||
|
||||
# If the score is already in the Tally, don't add it again
|
||||
# If the score is already in the Tally, raise an error
|
||||
if score in self.scores:
|
||||
return
|
||||
msg = 'Unable to add a duplicate score {0} to Tally ID="{1}" ' \
|
||||
'since duplicate scores are not supported in the OpenMC ' \
|
||||
'Python API'.format(score, self.id)
|
||||
raise ValueError(msg)
|
||||
|
||||
# Normal score strings
|
||||
if isinstance(score, basestring):
|
||||
self._scores.append(score.strip())
|
||||
|
|
@ -506,10 +506,6 @@ class Tally(object):
|
|||
else:
|
||||
self._scores.append(score)
|
||||
|
||||
@num_score_bins.setter
|
||||
def num_score_bins(self, num_score_bins):
|
||||
self._num_score_bins = num_score_bins
|
||||
|
||||
@num_realizations.setter
|
||||
def num_realizations(self, num_realizations):
|
||||
cv.check_type('number of realizations', num_realizations, Integral)
|
||||
|
|
@ -723,9 +719,10 @@ class Tally(object):
|
|||
merged_tally.filters[i] = merged_filter
|
||||
break
|
||||
|
||||
# Add scores from second tally to merged tally
|
||||
# Add unique scores from second tally to merged tally
|
||||
for score in tally.scores:
|
||||
merged_tally.add_score(score)
|
||||
if score not in merged_tally.scores:
|
||||
merged_tally.add_score(score)
|
||||
|
||||
# Add triggers from second tally to merged tally
|
||||
for trigger in tally.triggers:
|
||||
|
|
@ -1091,7 +1088,12 @@ class Tally(object):
|
|||
|
||||
"""
|
||||
|
||||
cv.check_iterable_type('scores', scores, basestring)
|
||||
for score in scores:
|
||||
if not isinstance(score, (basestring, CrossScore)):
|
||||
msg = 'Unable to get score indices for score "{0}" in Tally ' \
|
||||
'ID="{1}" since it is not a string or CrossScore'\
|
||||
.format(score, self.id)
|
||||
raise ValueError(msg)
|
||||
|
||||
# Determine the score indices from any of the requested scores
|
||||
if scores:
|
||||
|
|
@ -1356,7 +1358,7 @@ class Tally(object):
|
|||
for filter in self.filters:
|
||||
new_shape += (filter.num_bins, )
|
||||
new_shape += (self.num_nuclides,)
|
||||
new_shape += (self.num_score_bins,)
|
||||
new_shape += (self.num_scores,)
|
||||
|
||||
# Reshape the data with one dimension for each filter
|
||||
data = np.reshape(data, new_shape)
|
||||
|
|
@ -1503,20 +1505,20 @@ class Tally(object):
|
|||
# Pickle the Tally results to a file
|
||||
pickle.dump(tally_results, open(filename, 'wb'))
|
||||
|
||||
def hybrid_product(self, other, binary_op, filter_product='None',
|
||||
nuclide_product='None', score_product='None'):
|
||||
def hybrid_product(self, other, binary_op, filter_product=None,
|
||||
nuclide_product=None, score_product=None):
|
||||
"""Combines filters, scores and nuclides with another tally.
|
||||
|
||||
This is a helper method for the tally arithmetic methods. It is called a
|
||||
"hybrid product" because it performs a combination of tensor
|
||||
(or Kronecker) and entrywise (or Hadamard) products. The filters,
|
||||
nuclides, and scores from both tallies are combined using an entrywise
|
||||
This is a helper method for the tally arithmetic operator overloaded
|
||||
methods. It is called a "hybrid product" because it performs a
|
||||
combination of tensor (or Kronecker) and entrywise (or Hadamard)
|
||||
products. The filters from both tallies are combined using an entrywise
|
||||
(or Hadamard) product on matching filters. By default, if all nuclides
|
||||
are identical in the two tallies, the entrywise product is performed
|
||||
across nuclides; else the tensor product is performed. By default, if all
|
||||
scores are identical in the two tallies, the entrywise product is
|
||||
performed across scores; else the tensor product is performed. Users can
|
||||
also call the method explicitly and specify the desired product.
|
||||
across nuclides; else the tensor product is performed. By default, if
|
||||
all scores are identical in the two tallies, the entrywise product is
|
||||
performed across scores; else the tensor product is performed. Users
|
||||
can also call the method explicitly and specify the desired product.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
@ -1524,17 +1526,17 @@ class Tally(object):
|
|||
The tally on the right hand side of the hybrid product
|
||||
binary_op : {'+', '-', '*', '/', '^'}
|
||||
The binary operation in the hybrid product
|
||||
filter_product : str, optional
|
||||
filter_product : {'tensor', 'entrywise' or None}
|
||||
The type of product (tensor or entrywise) to be performed between
|
||||
filter data. The default is the entrywise product. Currently only
|
||||
the entrywise product is supported since a tally cannot contain
|
||||
two of the same tallies.
|
||||
nuclide_product : str, optional
|
||||
two of the same filter.
|
||||
nuclide_product : {'tensor', 'entrywise' or None}
|
||||
The type of product (tensor or entrywise) to be performed between
|
||||
nuclide data. The default is the entrywise product if all nuclides
|
||||
between the two tallies are the same; otherwise the default is
|
||||
the tensor product.
|
||||
score_product : str, optional
|
||||
score_product : {'tensor', 'entrywise' or None}
|
||||
The type of product (tensor or entrywise) to be performed between
|
||||
score data. The default is the entrywise product if all scores
|
||||
between the two tallies are the same; otherwise the default is
|
||||
|
|
@ -1554,22 +1556,22 @@ class Tally(object):
|
|||
"""
|
||||
|
||||
# Set default value for filter product if it was not set
|
||||
if filter_product == 'None':
|
||||
if filter_product is None:
|
||||
filter_product = 'entrywise'
|
||||
elif filter_product == 'tensor':
|
||||
msg = 'Unable to perform Tally arithmetic with a tensor product' \
|
||||
'for the filter data as this not currently supported.'
|
||||
'for the filter data as this is not currently supported.'
|
||||
raise ValueError(msg)
|
||||
|
||||
# Set default value for nuclide product if it was not set
|
||||
if nuclide_product == 'None':
|
||||
if nuclide_product is None:
|
||||
if self.nuclides == other.nuclides:
|
||||
nuclide_product = 'entrywise'
|
||||
else:
|
||||
nuclide_product = 'tensor'
|
||||
|
||||
# Set default value for score product if it was not set
|
||||
if score_product == 'None':
|
||||
if score_product is None:
|
||||
if self.scores == other.scores:
|
||||
score_product = 'entrywise'
|
||||
else:
|
||||
|
|
@ -1597,10 +1599,7 @@ class Tally(object):
|
|||
|
||||
# Query the mean and std dev so the tally data is read in from file
|
||||
# if it has not already been read in.
|
||||
self.mean
|
||||
self.std_dev
|
||||
other.mean
|
||||
other.std_dev
|
||||
self.mean, self.std_dev, other.mean, other.std_dev
|
||||
|
||||
# Create copies of self and other tallies to rearrange for tally
|
||||
# arithmetic
|
||||
|
|
@ -1661,7 +1660,7 @@ class Tally(object):
|
|||
# Add filters to the new tally
|
||||
if filter_product == 'entrywise':
|
||||
for self_filter in self_copy.filters:
|
||||
new_tally.filters.append(self_filter)
|
||||
new_tally.add_filter(self_filter)
|
||||
else:
|
||||
all_filters = [self_copy.filters, other_copy.filters]
|
||||
for self_filter, other_filter in itertools.product(*all_filters):
|
||||
|
|
@ -1671,7 +1670,7 @@ class Tally(object):
|
|||
# Add nuclides to the new tally
|
||||
if nuclide_product == 'entrywise':
|
||||
for self_nuclide in self_copy.nuclides:
|
||||
new_tally.nuclides.append(self_nuclide)
|
||||
new_tally.add_nuclide(self_nuclide)
|
||||
else:
|
||||
all_nuclides = [self_copy.nuclides, other_copy.nuclides]
|
||||
for self_nuclide, other_nuclide in itertools.product(*all_nuclides):
|
||||
|
|
@ -1681,19 +1680,16 @@ class Tally(object):
|
|||
|
||||
# Add scores to the new tally
|
||||
if score_product == 'entrywise':
|
||||
new_tally.num_score_bins = self_copy.num_score_bins
|
||||
for self_score in self_copy.scores:
|
||||
new_tally.add_score(self_score)
|
||||
else:
|
||||
new_tally.num_score_bins = \
|
||||
self_copy.num_score_bins * other_copy.num_score_bins
|
||||
all_scores = [self_copy.scores, other_copy.scores]
|
||||
for self_score, other_score in itertools.product(*all_scores):
|
||||
new_score = CrossScore(self_score, other_score, binary_op)
|
||||
new_tally.add_score(new_score)
|
||||
|
||||
# Correct each Filter's stride
|
||||
stride = new_tally.num_nuclides * new_tally.num_score_bins
|
||||
stride = new_tally.num_nuclides * new_tally.num_scores
|
||||
for filter in reversed(new_tally.filters):
|
||||
filter.stride = stride
|
||||
stride *= filter.num_bins
|
||||
|
|
@ -1715,13 +1711,13 @@ class Tally(object):
|
|||
----------
|
||||
other : Tally
|
||||
The tally to outer product with this tally
|
||||
filter_product : str
|
||||
The type of product (tensor or entrywise) to be performed between
|
||||
filter data.
|
||||
nuclide_product : str
|
||||
filter_product : {'entrywise'}
|
||||
The type of product to be performed between filter data. Currently,
|
||||
only the entrywise product is supported for the filter product.
|
||||
nuclide_product : {'tensor', 'entrywise'}
|
||||
The type of product (tensor or entrywise) to be performed between
|
||||
nuclide data.
|
||||
score_product : str
|
||||
score_product : {'tensor', 'entrywise'}
|
||||
The type of product (tensor or entrywise) to be performed between
|
||||
score data.
|
||||
Returns
|
||||
|
|
@ -1757,7 +1753,7 @@ class Tally(object):
|
|||
|
||||
# If necessary, swap other filter
|
||||
if other_index != i:
|
||||
other.swap_filters(filter, other.filters[i], inplace=True)
|
||||
other._swap_filters(filter, other.filters[i])
|
||||
|
||||
# Repeat and tile the data by nuclide in preparation for performing
|
||||
# the tensor product across nuclides.
|
||||
|
|
@ -1800,27 +1796,23 @@ class Tally(object):
|
|||
|
||||
# Align other nuclides with self nuclides
|
||||
for i, nuclide in enumerate(self.nuclides):
|
||||
other_index = other.nuclides.index(nuclide)
|
||||
other_index = other.get_nuclide_index(nuclide)
|
||||
|
||||
# If necessary, swap other nuclide
|
||||
if other_index != i:
|
||||
other.swap_nuclides(nuclide, other.nuclides[i])
|
||||
other._swap_nuclides(nuclide, other.nuclides[i])
|
||||
|
||||
# Repeat and tile the data by score in preparation for performing
|
||||
# the tensor product across scores.
|
||||
if score_product == 'tensor':
|
||||
self._mean = \
|
||||
np.repeat(self.mean, other.num_score_bins, axis=2)
|
||||
self._std_dev = \
|
||||
np.repeat(self.std_dev, other.num_score_bins, axis=2)
|
||||
other._mean = \
|
||||
np.tile(other.mean, (1, 1, self.num_score_bins))
|
||||
other._std_dev = \
|
||||
np.tile(other.std_dev, (1, 1, self.num_score_bins))
|
||||
self._mean = np.repeat(self.mean, other.num_scores, axis=2)
|
||||
self._std_dev = np.repeat(self.std_dev, other.num_scores, axis=2)
|
||||
other._mean = np.tile(other.mean, (1, 1, self.num_scores))
|
||||
other._std_dev = np.tile(other.std_dev, (1, 1, self.num_scores))
|
||||
|
||||
# Add scores to each tally such that each tally contains the complete
|
||||
# set of scores necessary to perform an entrywise product. New scores
|
||||
# added to a tally will be set to zero.
|
||||
# Add scores to each tally such that each tally contains the complete set
|
||||
# of scores necessary to perform an entrywise product. New scores added
|
||||
# to a tally will be set to zero.
|
||||
else:
|
||||
|
||||
# Get the set of scores that each tally is missing
|
||||
|
|
@ -1831,18 +1823,14 @@ class Tally(object):
|
|||
|
||||
# Add scores present in self but not in other to other
|
||||
for score in other_missing_scores:
|
||||
other._mean = \
|
||||
np.insert(other.mean, other.num_score_bins, 0, axis=2)
|
||||
other._std_dev = \
|
||||
np.insert(other.std_dev, other.num_score_bins, 0, axis=2)
|
||||
other._mean = np.insert(other.mean, other.num_scores, 0, axis=2)
|
||||
other._std_dev = np.insert(other.std_dev, other.num_scores, 0, axis=2)
|
||||
other.add_score(score)
|
||||
|
||||
# Add scores present in other but not in self to self
|
||||
for score in self_missing_scores:
|
||||
self._mean = \
|
||||
np.insert(self.mean, self.num_score_bins, 0, axis=2)
|
||||
self._std_dev = \
|
||||
np.insert(self.std_dev, self.num_score_bins, 0, axis=2)
|
||||
self._mean = np.insert(self.mean, self.num_scores, 0, axis=2)
|
||||
self._std_dev = np.insert(self.std_dev, self.num_scores, 0, axis=2)
|
||||
self.add_score(score)
|
||||
|
||||
# Align other scores with self scores
|
||||
|
|
@ -1851,42 +1839,35 @@ class Tally(object):
|
|||
|
||||
# If necessary, swap other score
|
||||
if other_index != i:
|
||||
other.swap_scores(score, other.scores[i])
|
||||
other._swap_scores(score, other.scores[i])
|
||||
|
||||
# Correct the stride for other filters
|
||||
stride = other.num_nuclides * other.num_score_bins
|
||||
stride = other.num_nuclides * other.num_scores
|
||||
for filter in reversed(other.filters):
|
||||
filter.stride = stride
|
||||
stride *= filter.num_bins
|
||||
|
||||
# Correct the stride for self filters
|
||||
stride = self.num_nuclides * self.num_score_bins
|
||||
stride = self.num_nuclides * self.num_scores
|
||||
for filter in reversed(self.filters):
|
||||
filter.stride = stride
|
||||
stride *= filter.num_bins
|
||||
|
||||
# Deep copy the mean and std dev data
|
||||
self_mean = copy.deepcopy(self.mean)
|
||||
self_std_dev = copy.deepcopy(self.std_dev)
|
||||
other_mean = copy.deepcopy(other.mean)
|
||||
other_std_dev = copy.deepcopy(other.std_dev)
|
||||
|
||||
data = {}
|
||||
data['self'] = {}
|
||||
data['other'] = {}
|
||||
data['self']['mean'] = self_mean
|
||||
data['other']['mean'] = other_mean
|
||||
data['self']['std. dev.'] = self_std_dev
|
||||
data['other']['std. dev.'] = other_std_dev
|
||||
|
||||
data['self']['mean'] = self.mean
|
||||
data['other']['mean'] = other.mean
|
||||
data['self']['std. dev.'] = self.std_dev
|
||||
data['other']['std. dev.'] = other.std_dev
|
||||
return data
|
||||
|
||||
def swap_filters(self, filter1, filter2, inplace=False):
|
||||
def _swap_filters(self, filter1, filter2):
|
||||
"""Reverse the ordering of two filters in this tally
|
||||
|
||||
This is a helper method for tally arithmetic which helps align the data
|
||||
in two tallies with shared filters. This method copies this tally and
|
||||
reverses the order of the two filters.
|
||||
in two tallies with shared filters. This method reverses the order of
|
||||
the two filters in place.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
@ -1896,16 +1877,6 @@ class Tally(object):
|
|||
filter2 : Filter
|
||||
The filter to swap with filter1
|
||||
|
||||
inplace : bool, optional
|
||||
Whether to perform operation inplace or return new tally with the
|
||||
filters swapped.
|
||||
|
||||
Returns
|
||||
-------
|
||||
swap_tally
|
||||
If inplace is false, a copy of this tally with the filters swapped.
|
||||
Otherwise, nothing is returned.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
|
|
@ -1923,6 +1894,7 @@ class Tally(object):
|
|||
cv.check_type('filter1', filter1, Filter)
|
||||
cv.check_type('filter2', filter2, Filter)
|
||||
|
||||
# Check that the filters exist in the tally and are not the same
|
||||
if filter1 == filter2:
|
||||
msg = 'Unable to swap a filter with itself'
|
||||
raise ValueError(msg)
|
||||
|
|
@ -1935,25 +1907,15 @@ class Tally(object):
|
|||
'does not contain such a filter'.format(filter2.type, self.id)
|
||||
raise ValueError(msg)
|
||||
|
||||
# Create a copy of the tally that preserves the original data formatting
|
||||
# throughout swapping process
|
||||
tally_copy = copy.deepcopy(self)
|
||||
|
||||
# Set the swap tally
|
||||
if inplace:
|
||||
swap_tally = self
|
||||
else:
|
||||
swap_tally = copy.deepcopy(self)
|
||||
|
||||
# Swap the filters in the copied version of this Tally
|
||||
filter1_index = swap_tally.filters.index(filter1)
|
||||
filter2_index = swap_tally.filters.index(filter2)
|
||||
swap_tally.filters[filter1_index] = filter2
|
||||
swap_tally.filters[filter2_index] = filter1
|
||||
filter1_index = self.filters.index(filter1)
|
||||
filter2_index = self.filters.index(filter2)
|
||||
self.filters[filter1_index] = filter2
|
||||
self.filters[filter2_index] = filter1
|
||||
|
||||
# Update the strides for each of the filters
|
||||
stride = swap_tally.num_nuclides * swap_tally.num_score_bins
|
||||
for filter in reversed(swap_tally.filters):
|
||||
stride = self.num_nuclides * self.num_scores
|
||||
for filter in reversed(self.filters):
|
||||
filter.stride = stride
|
||||
stride *= filter.num_bins
|
||||
|
||||
|
|
@ -1964,51 +1926,30 @@ class Tally(object):
|
|||
else:
|
||||
filter1_bins = [(filter1.get_bin(i)) for i in range(filter1.num_bins)]
|
||||
|
||||
if filter1.type == 'distribcell':
|
||||
if filter2.type == 'distribcell':
|
||||
filter2_bins = np.arange(filter2.num_bins)
|
||||
else:
|
||||
filter2_bins = [filter2.get_bin(i) for i in range(filter2.num_bins)]
|
||||
|
||||
# Adjust the sum data array to relect the new filter order
|
||||
if swap_tally.sum is not None:
|
||||
for bin1, bin2 in itertools.product(filter1_bins, filter2_bins):
|
||||
filter_bins = [(bin1,), (bin2,)]
|
||||
data = tally_copy.get_values(
|
||||
filters=filters, filter_bins=filter_bins, value='sum')
|
||||
indices = swap_tally.get_filter_indices(filters, filter_bins)
|
||||
swap_tally.sum[indices, :, :] = data
|
||||
|
||||
# Adjust the sum_sq data array to relect the new filter order
|
||||
if swap_tally.sum_sq is not None:
|
||||
for bin1, bin2 in itertools.product(filter1_bins, filter2_bins):
|
||||
filter_bins = [(bin1,), (bin2,)]
|
||||
data = tally_copy.get_values(
|
||||
filters=filters, filter_bins=filter_bins, value='sum_sq')
|
||||
indices = swap_tally.get_filter_indices(filters, filter_bins)
|
||||
swap_tally.sum_sq[indices, :, :] = data
|
||||
|
||||
# Adjust the mean data array to relect the new filter order
|
||||
if swap_tally.mean is not None:
|
||||
if self.mean is not None:
|
||||
for bin1, bin2 in itertools.product(filter1_bins, filter2_bins):
|
||||
filter_bins = [(bin1,), (bin2,)]
|
||||
data = tally_copy.get_values(
|
||||
data = self.get_values(
|
||||
filters=filters, filter_bins=filter_bins, value='mean')
|
||||
indices = swap_tally.get_filter_indices(filters, filter_bins)
|
||||
swap_tally._mean[indices, :, :] = data
|
||||
indices = self.get_filter_indices(filters, filter_bins)
|
||||
self._mean[indices, :, :] = data
|
||||
|
||||
# Adjust the std_dev data array to relect the new filter order
|
||||
if swap_tally.std_dev is not None:
|
||||
if self.std_dev is not None:
|
||||
for bin1, bin2 in itertools.product(filter1_bins, filter2_bins):
|
||||
filter_bins = [(bin1,), (bin2,)]
|
||||
data = tally_copy.get_values(
|
||||
data = self.get_values(
|
||||
filters=filters, filter_bins=filter_bins, value='std_dev')
|
||||
indices = swap_tally.get_filter_indices(filters, filter_bins)
|
||||
swap_tally._std_dev[indices, :, :] = data
|
||||
indices = self.get_filter_indices(filters, filter_bins)
|
||||
self._std_dev[indices, :, :] = data
|
||||
|
||||
if not inplace:
|
||||
return swap_tally
|
||||
|
||||
def swap_nuclides(self, nuclide1, nuclide2):
|
||||
def _swap_nuclides(self, nuclide1, nuclide2):
|
||||
"""Reverse the ordering of two nuclides in this tally
|
||||
|
||||
This is a helper method for tally arithmetic which helps align the data
|
||||
|
|
@ -2037,45 +1978,57 @@ class Tally(object):
|
|||
'since it does not contain any results.'.format(self.id)
|
||||
raise ValueError(msg)
|
||||
|
||||
cv.check_type('nuclide1', nuclide1, Nuclide)
|
||||
cv.check_type('nuclide2', nuclide2, Nuclide)
|
||||
|
||||
# Check that the nuclides exist in the tally and are not the same
|
||||
if nuclide1 == nuclide2:
|
||||
msg = 'Unable to swap a nuclide with itself'
|
||||
raise ValueError(msg)
|
||||
elif nuclide1 not in self.nuclides:
|
||||
msg = 'Unable to swap nuclide1 "{0}" in Tally ID="{1}" since it ' \
|
||||
'does not contain such a nuclide'\
|
||||
.format(nuclide1.name, self.id)
|
||||
raise ValueError(msg)
|
||||
elif nuclide2 not in self.nuclides:
|
||||
msg = 'Unable to swap "{0}" nuclide2 in Tally ID="{1}" since it ' \
|
||||
'does not contain such a nuclide'\
|
||||
.format(nuclide2.name, self.id)
|
||||
raise ValueError(msg)
|
||||
|
||||
# Swap the nuclides in the Tally
|
||||
nuclide1_index = self.nuclides.index(nuclide1)
|
||||
nuclide2_index = self.nuclides.index(nuclide2)
|
||||
nuclide1_index = self.get_nuclide_index(nuclide1)
|
||||
nuclide2_index = self.get_nuclide_index(nuclide2)
|
||||
self.nuclides[nuclide1_index] = nuclide2
|
||||
self.nuclides[nuclide2_index] = nuclide1
|
||||
|
||||
# Copy the tally data
|
||||
self_mean = copy.deepcopy(self.mean)
|
||||
self_std_dev = copy.deepcopy(self.std_dev)
|
||||
# Adjust the mean data array to relect the new nuclide order
|
||||
if self.mean is not None:
|
||||
nuclide1_mean = self._mean[:, nuclide1_index, :].copy()
|
||||
nuclide2_mean = self._mean[:, nuclide2_index, :].copy()
|
||||
self._mean[:, nuclide2_index, :] = nuclide1_mean
|
||||
self._mean[:, nuclide1_index, :] = nuclide2_mean
|
||||
|
||||
# Swap nuclide 1 in place of nuclide 2
|
||||
self._mean = np.delete(self.mean, nuclide2_index, axis=1)
|
||||
self._mean = np.insert(self.mean, nuclide2_index,
|
||||
self_mean[:,nuclide1_index,:], axis=1)
|
||||
self._std_dev = np.delete(self.std_dev, nuclide2_index, axis=1)
|
||||
self._std_dev = np.insert(self.std_dev, nuclide2_index,
|
||||
self_mean[:,nuclide1_index,:], axis=1)
|
||||
# Adjust the std_dev data array to relect the new nuclide order
|
||||
if self.std_dev is not None:
|
||||
nuclide1_std_dev = self._std_dev[:, nuclide1_index, :].copy()
|
||||
nuclide2_std_dev = self._std_dev[:, nuclide2_index, :].copy()
|
||||
self._std_dev[:, nuclide2_index, :] = nuclide1_std_dev
|
||||
self._std_dev[:, nuclide1_index, :] = nuclide2_std_dev
|
||||
|
||||
# Swap nuclide 2 in place of nuclide 1
|
||||
self._mean = np.delete(self.mean, nuclide1_index, axis=1)
|
||||
self._mean = np.insert(self.mean, nuclide1_index,
|
||||
self_mean[:,nuclide2_index,:], axis=1)
|
||||
self._std_dev = np.delete(self.std_dev, nuclide1_index, axis=1)
|
||||
self._std_dev = np.insert(self.std_dev, nuclide1_index,
|
||||
self_mean[:,nuclide2_index,:], axis=1)
|
||||
|
||||
def swap_scores(self, score1, score2):
|
||||
def _swap_scores(self, score1, score2):
|
||||
"""Reverse the ordering of two scores in this tally
|
||||
|
||||
This is a helper method for tally arithmetic which helps align the data
|
||||
in two tallies with shared scores. This method copies reverses the order
|
||||
in two tallies with shared scores. This method reverses the order
|
||||
of the two scores in place.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
score1 : Score
|
||||
score1 : str or CrossScore
|
||||
The score to swap with score2
|
||||
|
||||
score2 : Score
|
||||
score2 : str or CrossScore
|
||||
The score to swap with score1
|
||||
|
||||
Raises
|
||||
|
|
@ -2092,31 +2045,48 @@ class Tally(object):
|
|||
'since it does not contain any results.'.format(self.id)
|
||||
raise ValueError(msg)
|
||||
|
||||
# Check that the scores are valid
|
||||
if not isinstance(score1, (basestring, CrossScore)):
|
||||
msg = 'Unable to swap score1 "{0}" in Tally ID="{1}" since it is ' \
|
||||
'not a string or CrossScore'.format(score1, self.id)
|
||||
raise ValueError(msg)
|
||||
elif not isinstance(score2, (basestring, CrossScore)):
|
||||
msg = 'Unable to swap score2 "{0}" in Tally ID="{1}" since it is ' \
|
||||
'not a string or CrossScore'.format(score2, self.id)
|
||||
raise ValueError(msg)
|
||||
|
||||
# Check that the scores exist in the tally and are not the same
|
||||
if score1 == score2:
|
||||
msg = 'Unable to swap a score with itself'
|
||||
raise ValueError(msg)
|
||||
elif score1 not in self.scores:
|
||||
msg = 'Unable to swap score1 "{0}" in Tally ID="{1}" since it ' \
|
||||
'does not contain such a score'.format(score1, self.id)
|
||||
raise ValueError(msg)
|
||||
elif score2 not in self.scores:
|
||||
msg = 'Unable to swap score2 "{0}" in Tally ID="{1}" since it ' \
|
||||
'does not contain such a score'.format(score2, self.id)
|
||||
raise ValueError(msg)
|
||||
|
||||
# Swap the scores in the Tally
|
||||
score1_index = self.scores.index(score1)
|
||||
score2_index = self.scores.index(score2)
|
||||
score1_index = self.get_score_index(score1)
|
||||
score2_index = self.get_score_index(score2)
|
||||
self.scores[score1_index] = score2
|
||||
self.scores[score2_index] = score1
|
||||
|
||||
# Copy the tally data
|
||||
self_mean = copy.deepcopy(self.mean)
|
||||
self_std_dev = copy.deepcopy(self.std_dev)
|
||||
# Adjust the mean data array to relect the new nuclide order
|
||||
if self.mean is not None:
|
||||
score1_mean = self._mean[:, :, score1_index].copy()
|
||||
score2_mean = self._mean[:, :, score2_index].copy()
|
||||
self._mean[:, :, score2_index] = score1_mean
|
||||
self._mean[:, :, score1_index] = score2_mean
|
||||
|
||||
# Swap score 1 in place of score 2
|
||||
self._mean = np.delete(self.mean, score2_index, axis=2)
|
||||
self._mean = np.insert(self.mean, score2_index,
|
||||
self_mean[:,:,score1_index], axis=2)
|
||||
self._std_dev = np.delete(self.std_dev, score2_index, axis=2)
|
||||
self._std_dev = np.insert(self.std_dev, score2_index,
|
||||
self_mean[:,:,score1_index], axis=2)
|
||||
|
||||
# Swap score 2 in place of score 1
|
||||
self._mean = np.delete(self.mean, score1_index, axis=2)
|
||||
self._mean = np.insert(self.mean, score1_index,
|
||||
self_mean[:,:,score2_index], axis=2)
|
||||
self._std_dev = np.delete(self.std_dev, score1_index, axis=2)
|
||||
self._std_dev = np.insert(self.std_dev, score1_index,
|
||||
self_mean[:,:,score2_index], axis=2)
|
||||
# Adjust the std_dev data array to relect the new nuclide order
|
||||
if self.std_dev is not None:
|
||||
score1_std_dev = self._std_dev[:, :, score1_index].copy()
|
||||
score2_std_dev = self._std_dev[:, :, score2_index].copy()
|
||||
self._std_dev[:, :, score2_index] = score1_std_dev
|
||||
self._std_dev[:, :, score1_index] = score2_std_dev
|
||||
|
||||
def __add__(self, other):
|
||||
"""Adds this tally to another tally or scalar value.
|
||||
|
|
@ -2176,7 +2146,6 @@ class Tally(object):
|
|||
new_tally.estimator = self.estimator
|
||||
new_tally.with_summary = self.with_summary
|
||||
new_tally.num_realization = self.num_realizations
|
||||
new_tally.num_score_bins = self.num_score_bins
|
||||
|
||||
for filter in self.filters:
|
||||
new_tally.add_filter(filter)
|
||||
|
|
@ -2251,7 +2220,6 @@ class Tally(object):
|
|||
new_tally.estimator = self.estimator
|
||||
new_tally.with_summary = self.with_summary
|
||||
new_tally.num_realization = self.num_realizations
|
||||
new_tally.num_score_bins = self.num_score_bins
|
||||
|
||||
for filter in self.filters:
|
||||
new_tally.add_filter(filter)
|
||||
|
|
@ -2327,7 +2295,6 @@ class Tally(object):
|
|||
new_tally.estimator = self.estimator
|
||||
new_tally.with_summary = self.with_summary
|
||||
new_tally.num_realization = self.num_realizations
|
||||
new_tally.num_score_bins = self.num_score_bins
|
||||
|
||||
for filter in self.filters:
|
||||
new_tally.add_filter(filter)
|
||||
|
|
@ -2403,7 +2370,6 @@ class Tally(object):
|
|||
new_tally.estimator = self.estimator
|
||||
new_tally.with_summary = self.with_summary
|
||||
new_tally.num_realization = self.num_realizations
|
||||
new_tally.num_score_bins = self.num_score_bins
|
||||
|
||||
for filter in self.filters:
|
||||
new_tally.add_filter(filter)
|
||||
|
|
@ -2483,7 +2449,6 @@ class Tally(object):
|
|||
new_tally.estimator = self.estimator
|
||||
new_tally.with_summary = self.with_summary
|
||||
new_tally.num_realization = self.num_realizations
|
||||
new_tally.num_score_bins = self.num_score_bins
|
||||
|
||||
for filter in self.filters:
|
||||
new_tally.add_filter(filter)
|
||||
|
|
@ -2688,7 +2653,6 @@ class Tally(object):
|
|||
# Loop over indices in reverse to remove excluded scores
|
||||
for score_index in reversed(score_indices):
|
||||
new_tally.remove_score(self.scores[score_index])
|
||||
new_tally.num_score_bins -= 1
|
||||
|
||||
# NUCLIDES
|
||||
if nuclides:
|
||||
|
|
@ -2728,7 +2692,7 @@ class Tally(object):
|
|||
filter.num_bins = len(filter_bins[i])
|
||||
|
||||
# Correct each Filter's stride
|
||||
stride = new_tally.num_nuclides * new_tally.num_score_bins
|
||||
stride = new_tally.num_nuclides * new_tally.num_scores
|
||||
for filter in reversed(new_tally.filters):
|
||||
filter.stride = stride
|
||||
stride *= filter.num_bins
|
||||
|
|
@ -2878,7 +2842,8 @@ class Tally(object):
|
|||
# Determine the shape of data in the new diagonalized Tally
|
||||
num_filter_bins = new_tally.num_filter_bins
|
||||
num_nuclides = new_tally.num_nuclides
|
||||
num_score_bins = new_tally.num_score_bins
|
||||
num_scores = new_tally.num_scores
|
||||
new_shape = (num_filter_bins, num_nuclides, num_scores)
|
||||
|
||||
# Determine "base" indices along the new "diagonal", and the factor
|
||||
# by which the "base" indices should be repeated to account for all
|
||||
|
|
@ -2908,7 +2873,7 @@ class Tally(object):
|
|||
new_tally._std_dev[diag_indices, :, :] = self.std_dev
|
||||
|
||||
# Correct each Filter's stride
|
||||
stride = new_tally.num_nuclides * new_tally.num_score_bins
|
||||
stride = new_tally.num_nuclides * new_tally.num_scores
|
||||
for filter in reversed(new_tally.filters):
|
||||
filter.stride = stride
|
||||
stride *= filter.num_bins
|
||||
|
|
|
|||
|
|
@ -484,8 +484,10 @@ contains
|
|||
subroutine write_tallies(file_id)
|
||||
integer(HID_T), intent(in) :: file_id
|
||||
|
||||
integer :: i, j
|
||||
integer :: i, j, k
|
||||
integer :: i_list, i_xs
|
||||
integer :: n_order ! loop index for moment orders
|
||||
integer :: nm_order ! loop index for Ynm moment orders
|
||||
integer(HID_T) :: tallies_group
|
||||
integer(HID_T) :: mesh_group
|
||||
integer(HID_T) :: tally_group
|
||||
|
|
@ -664,6 +666,37 @@ contains
|
|||
|
||||
deallocate(str_array)
|
||||
|
||||
! Write explicit moment order strings for each score bin
|
||||
k = 1
|
||||
allocate(str_array(t%n_score_bins))
|
||||
MOMENT_LOOP: do j = 1, t%n_user_score_bins
|
||||
select case(t%score_bins(k))
|
||||
case (SCORE_SCATTER_N, SCORE_NU_SCATTER_N)
|
||||
str_array(k) = 'P' // trim(to_str(t%moment_order(k)))
|
||||
k = k + 1
|
||||
case (SCORE_SCATTER_PN, SCORE_NU_SCATTER_PN)
|
||||
do n_order = 0, t%moment_order(k)
|
||||
str_array(k) = 'P' // trim(to_str(n_order))
|
||||
k = k + 1
|
||||
end do
|
||||
case (SCORE_SCATTER_YN, SCORE_NU_SCATTER_YN, SCORE_FLUX_YN, &
|
||||
SCORE_TOTAL_YN)
|
||||
do n_order = 0, t%moment_order(k)
|
||||
do nm_order = -n_order, n_order
|
||||
str_array(k) = 'Y' // trim(to_str(n_order)) // ',' // &
|
||||
trim(to_str(nm_order))
|
||||
k = k + 1
|
||||
end do
|
||||
end do
|
||||
case default
|
||||
str_array(k) = ''
|
||||
k = k + 1
|
||||
end select
|
||||
end do MOMENT_LOOP
|
||||
|
||||
call write_dataset(tally_group, "moment_orders", str_array)
|
||||
deallocate(str_array)
|
||||
|
||||
call close_group(tally_group)
|
||||
end do TALLY_METADATA
|
||||
|
||||
|
|
|
|||
|
|
@ -11,18 +11,6 @@ tally 1:
|
|||
2.483728E+01
|
||||
5.102293E-01
|
||||
8.710841E-02
|
||||
8.628000E+00
|
||||
2.481430E+01
|
||||
9.329009E-01
|
||||
2.902534E-01
|
||||
5.102293E-01
|
||||
8.710841E-02
|
||||
5.087118E-01
|
||||
8.657086E-02
|
||||
8.632000E+00
|
||||
2.483728E+01
|
||||
9.328366E-01
|
||||
2.902108E-01
|
||||
5.087118E-01
|
||||
8.657086E-02
|
||||
9.212024E+00
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
<tally id="1">
|
||||
<filter type="cell" bins="21" />
|
||||
<scores>
|
||||
flux total scatter nu-scatter scatter-2 scatter-p2 nu-scatter-2
|
||||
nu-scatter-p2 transport n1n absorption nu-fission kappa-fission
|
||||
flux-y2 total-y2 scatter-y2 nu-scatter-y2 events delayed-nu-fission
|
||||
flux total scatter nu-scatter scatter-2 nu-scatter-2 transport n1n
|
||||
absorption nu-fission kappa-fission flux-y2 total-y2 scatter-y2
|
||||
nu-scatter-y2 events delayed-nu-fission
|
||||
</scores>
|
||||
</tally>
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
63295b9d510370e65e63a3db627d47d286f5479e53c8eabeda9a5cb25ffe35becb636835aadad11691e34c23292fe11b5f688daee76d76ceac4b5dfd2f9ede4c
|
||||
7270299e4a4dde19d250825b0124fa36b60df847f046e058ccdfc74d4690beaaaaf387e050f596cb3445caf793d6a390ddb2d19650a3dccd4eb60056ae3b1477
|
||||
|
|
@ -7,10 +7,6 @@ tally 1:
|
|||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
1.538090E-03
|
||||
1.381456E-06
|
||||
1.538090E-03
|
||||
1.381456E-06
|
||||
3.974412E-01
|
||||
|
|
@ -19,16 +15,12 @@ tally 1:
|
|||
3.796357E-01
|
||||
5.252455E-06
|
||||
2.290531E-11
|
||||
5.252455E-06
|
||||
2.290531E-11
|
||||
3.359792E-02
|
||||
2.267331E-04
|
||||
2.459115E-02
|
||||
1.233078E-04
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
7.004005E-05
|
||||
1.748739E-09
|
||||
8.104946E-02
|
||||
|
|
@ -42,18 +34,12 @@ tally 2:
|
|||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
2.000000E-01
|
||||
9.000000E-03
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
2.000000E-02
|
||||
2.000000E-04
|
||||
0.000000E+00
|
||||
|
|
@ -64,8 +50,6 @@ tally 2:
|
|||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
tally 3:
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
|
|
@ -73,10 +57,6 @@ tally 3:
|
|||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
1.408027E-03
|
||||
1.849607E-06
|
||||
1.408027E-03
|
||||
1.849607E-06
|
||||
3.946436E-01
|
||||
|
|
@ -85,16 +65,12 @@ tally 3:
|
|||
3.382059E-01
|
||||
2.179241E-05
|
||||
4.749090E-10
|
||||
2.179241E-05
|
||||
4.749090E-10
|
||||
3.146594E-02
|
||||
2.159308E-04
|
||||
4.278352E-02
|
||||
4.094478E-04
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
0.000000E+00
|
||||
1.736514E-04
|
||||
1.245171E-08
|
||||
7.989710E-02
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ class ScoreMTTestHarness(PyAPITestHarness):
|
|||
filt = openmc.Filter(type='cell', bins=(10, 21, 22, 23))
|
||||
tallies = [openmc.Tally(tally_id=i) for i in range(1, 4)]
|
||||
[t.add_filter(filt) for t in tallies]
|
||||
[t.add_score('n2n') for t in tallies]
|
||||
[t.add_score('16') for t in tallies]
|
||||
[t.add_score('51') for t in tallies]
|
||||
[t.add_score('102') for t in tallies]
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<geometry>
|
||||
|
||||
<!-- Sphere with radius 10 -->
|
||||
<surface id="1" type="sphere" coeffs="0 0 0 10" boundary="vacuum"/>
|
||||
<cell id="1" material="1" region="-1" />
|
||||
|
||||
</geometry>
|
||||
1
tests/test_tally_arithmetic/inputs_true.dat
Normal file
1
tests/test_tally_arithmetic/inputs_true.dat
Normal file
|
|
@ -0,0 +1 @@
|
|||
df6318b76cd37a29ef9dd09da48a70c191ed07c1a2ceb75eb502ab35086c31250872406f22c2587edfcee16f67dd95c81db012ccd728710ed2509084438aea56
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<materials>
|
||||
|
||||
<material id="1">
|
||||
<density value="4.5" units="g/cc" />
|
||||
<nuclide name="U-238" xs="71c" ao="1.0" />
|
||||
<nuclide name="U-235" xs="71c" ao="1.0" />
|
||||
<nuclide name="Pu-239" xs="71c" ao="1.0" />
|
||||
</material>
|
||||
|
||||
</materials>
|
||||
|
|
@ -1,53 +1,134 @@
|
|||
Tally
|
||||
ID = 10000
|
||||
Name = (tally 1 + tally 2)
|
||||
Filters =
|
||||
cell [1]
|
||||
energy [ 0. 20.]
|
||||
material [1]
|
||||
Nuclides = (U-235 + U-235) (U-235 + Pu-239) (U-238 + U-235) (U-238 + Pu-239)
|
||||
Scores = [(fission + fission), (fission + absorption), (nu-fission + fission), (nu-fission + absorption)]
|
||||
Estimator = tracklength
|
||||
[[[ 0.07510122 0.07839105 0.13713377 0.1404236 ]
|
||||
[ 0.0916553 0.09321683 0.15368785 0.15524938]
|
||||
[ 0.04596277 0.0492526 0.06126275 0.06455259]
|
||||
[ 0.06251685 0.06407838 0.07781683 0.07937836]]]Tally
|
||||
ID = 10001
|
||||
Name = (tally 1 - tally 2)
|
||||
Filters =
|
||||
cell [1]
|
||||
energy [ 0. 20.]
|
||||
material [1]
|
||||
Nuclides = (U-235 - U-235) (U-235 - Pu-239) (U-238 - U-235) (U-238 - Pu-239)
|
||||
Scores = [(fission - fission), (fission - absorption), (nu-fission - fission), (nu-fission - absorption)]
|
||||
Estimator = tracklength
|
||||
[[[ 0. -0.00328983 0.06203255 0.05874271]
|
||||
[-0.01655408 -0.01811561 0.04547847 0.04391694]
|
||||
[-0.02913845 -0.03242829 -0.01383847 -0.0171283 ]
|
||||
[-0.04569253 -0.04725406 -0.03039255 -0.03195408]]]Tally
|
||||
ID = 10002
|
||||
Name = (tally 1 * tally 2)
|
||||
Filters =
|
||||
cell [1]
|
||||
energy [ 0. 20.]
|
||||
material [1]
|
||||
Nuclides = (U-235 * U-235) (U-235 * Pu-239) (U-238 * U-235) (U-238 * Pu-239)
|
||||
Scores = [(fission * fission), (fission * absorption), (nu-fission * fission), (nu-fission * absorption)]
|
||||
Estimator = tracklength
|
||||
[[[ 0.00141005 0.00153358 0.00373941 0.00406702]
|
||||
[ 0.00203166 0.0020903 0.00538792 0.00554342]
|
||||
[ 0.00031588 0.00034356 0.00089041 0.00096841]
|
||||
[ 0.00045514 0.00046827 0.00128294 0.00131997]]]Tally
|
||||
ID = 10003
|
||||
Name = (tally 1 / tally 2)
|
||||
Filters =
|
||||
cell [1]
|
||||
energy [ 0. 20.]
|
||||
material [1]
|
||||
Nuclides = (U-235 / U-235) (U-235 / Pu-239) (U-238 / U-235) (U-238 / Pu-239)
|
||||
Scores = [(fission / fission), (fission / absorption), (nu-fission / fission), (nu-fission / absorption)]
|
||||
Estimator = tracklength
|
||||
[[[ 1. 0.91944666 2.65197177 2.4383466 ]
|
||||
[ 0.69403611 0.67456727 1.84056418 1.78893335]
|
||||
[ 0.22402189 0.20597618 0.63147153 0.58060439]
|
||||
[ 0.15547928 0.15111784 0.43826405 0.42597002]]]
|
||||
[[[ 8.90240785e-05 8.31464209e-11 4.41507090e-05 4.12357364e-11]
|
||||
[ 7.29618709e-05 5.98879928e-05 3.61847984e-05 2.97009235e-05]
|
||||
[ 4.69276830e-05 4.38293656e-11 2.35903380e-05 2.20328275e-11]
|
||||
[ 3.84607356e-05 3.15690405e-05 1.93340411e-05 1.58696166e-05]]
|
||||
|
||||
[[ 8.90240785e-05 8.31464209e-11 4.41507090e-05 4.12357364e-11]
|
||||
[ 7.29618709e-05 5.98879928e-05 3.61847984e-05 2.97009235e-05]
|
||||
[ 4.69276830e-05 4.38293656e-11 2.35903380e-05 2.20328275e-11]
|
||||
[ 3.84607356e-05 3.15690405e-05 1.93340411e-05 1.58696166e-05]]
|
||||
|
||||
[[ 8.90240785e-05 8.31464209e-11 4.41507090e-05 4.12357364e-11]
|
||||
[ 7.29618709e-05 5.98879928e-05 3.61847984e-05 2.97009235e-05]
|
||||
[ 4.69276830e-05 4.38293656e-11 2.35903380e-05 2.20328275e-11]
|
||||
[ 3.84607356e-05 3.15690405e-05 1.93340411e-05 1.58696166e-05]]
|
||||
|
||||
...,
|
||||
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
|
||||
|
||||
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
|
||||
|
||||
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]][[[ 8.90240785e-05 8.31464209e-11 4.41507090e-05 4.12357364e-11]
|
||||
[ 7.29618709e-05 5.98879928e-05 3.61847984e-05 2.97009235e-05]
|
||||
[ 4.69276830e-05 4.38293656e-11 2.35903380e-05 2.20328275e-11]
|
||||
[ 3.84607356e-05 3.15690405e-05 1.93340411e-05 1.58696166e-05]]
|
||||
|
||||
[[ 8.90240785e-05 8.31464209e-11 4.41507090e-05 4.12357364e-11]
|
||||
[ 7.29618709e-05 5.98879928e-05 3.61847984e-05 2.97009235e-05]
|
||||
[ 4.69276830e-05 4.38293656e-11 2.35903380e-05 2.20328275e-11]
|
||||
[ 3.84607356e-05 3.15690405e-05 1.93340411e-05 1.58696166e-05]]
|
||||
|
||||
[[ 8.90240785e-05 8.31464209e-11 4.41507090e-05 4.12357364e-11]
|
||||
[ 7.29618709e-05 5.98879928e-05 3.61847984e-05 2.97009235e-05]
|
||||
[ 4.69276830e-05 4.38293656e-11 2.35903380e-05 2.20328275e-11]
|
||||
[ 3.84607356e-05 3.15690405e-05 1.93340411e-05 1.58696166e-05]]
|
||||
|
||||
...,
|
||||
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
|
||||
|
||||
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
|
||||
|
||||
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]][[[ 7.29618709e-05 5.98879928e-05 3.61847984e-05 2.97009235e-05]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
|
||||
|
||||
[[ 7.29618709e-05 5.98879928e-05 3.61847984e-05 2.97009235e-05]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
|
||||
|
||||
[[ 7.29618709e-05 5.98879928e-05 3.61847984e-05 2.97009235e-05]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
|
||||
|
||||
...,
|
||||
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
|
||||
|
||||
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
|
||||
|
||||
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]][[[ 0.00000000e+00 4.41507090e-05 0.00000000e+00]
|
||||
[ 0.00000000e+00 3.61847984e-05 0.00000000e+00]
|
||||
[ 0.00000000e+00 2.35903380e-05 0.00000000e+00]
|
||||
[ 0.00000000e+00 1.93340411e-05 0.00000000e+00]]
|
||||
|
||||
[[ 0.00000000e+00 4.41507090e-05 0.00000000e+00]
|
||||
[ 0.00000000e+00 3.61847984e-05 0.00000000e+00]
|
||||
[ 0.00000000e+00 2.35903380e-05 0.00000000e+00]
|
||||
[ 0.00000000e+00 1.93340411e-05 0.00000000e+00]]
|
||||
|
||||
[[ 0.00000000e+00 4.41507090e-05 0.00000000e+00]
|
||||
[ 0.00000000e+00 3.61847984e-05 0.00000000e+00]
|
||||
[ 0.00000000e+00 2.35903380e-05 0.00000000e+00]
|
||||
[ 0.00000000e+00 1.93340411e-05 0.00000000e+00]]
|
||||
|
||||
...,
|
||||
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
|
||||
|
||||
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
|
||||
|
||||
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]]][[[ 0.00000000e+00 3.61847984e-05 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
|
||||
|
||||
[[ 0.00000000e+00 3.61847984e-05 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
|
||||
|
||||
[[ 0.00000000e+00 3.61847984e-05 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
|
||||
|
||||
...,
|
||||
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
|
||||
|
||||
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
|
||||
|
||||
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
|
||||
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]]]
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<settings>
|
||||
|
||||
<eigenvalue>
|
||||
<batches>10</batches>
|
||||
<inactive>5</inactive>
|
||||
<particles>1000</particles>
|
||||
</eigenvalue>
|
||||
|
||||
<source>
|
||||
<space type="box">
|
||||
<parameters>-4 -4 -4 4 4 4</parameters>
|
||||
</space>
|
||||
</source>
|
||||
|
||||
<output summary="true"/>
|
||||
|
||||
</settings>
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<tallies>
|
||||
<tally id="10000" name="tally 1">
|
||||
<filter bins="1" type="cell" />
|
||||
<filter bins="0.0 20.0" type="energy" />
|
||||
<nuclides>U-235 U-238</nuclides>
|
||||
<scores>fission nu-fission</scores>
|
||||
</tally>
|
||||
<tally id="10001" name="tally 2">
|
||||
<filter bins="1" type="material" />
|
||||
<filter bins="0.0 20.0" type="energy" />
|
||||
<nuclides>U-235 Pu-239</nuclides>
|
||||
<scores>fission absorption</scores>
|
||||
</tally>
|
||||
</tallies>
|
||||
|
|
@ -5,11 +5,64 @@ import sys
|
|||
import glob
|
||||
import hashlib
|
||||
sys.path.insert(0, os.pardir)
|
||||
from testing_harness import TestHarness
|
||||
from testing_harness import PyAPITestHarness
|
||||
import openmc
|
||||
|
||||
|
||||
class TallyArithmeticTestHarness(TestHarness):
|
||||
class TallyArithmeticTestHarness(PyAPITestHarness):
|
||||
def _build_inputs(self):
|
||||
|
||||
# The summary.h5 file needs to be created to read in the tallies
|
||||
self._input_set.settings.output = {'summary': True}
|
||||
|
||||
# Initialize the tallies file
|
||||
tallies_file = openmc.TalliesFile()
|
||||
|
||||
# Initialize the nuclides
|
||||
u235 = openmc.Nuclide('U-235')
|
||||
u238 = openmc.Nuclide('U-238')
|
||||
pu239 = openmc.Nuclide('Pu-239')
|
||||
|
||||
# Initialize Mesh
|
||||
mesh = openmc.Mesh(mesh_id=1)
|
||||
mesh.type = 'regular'
|
||||
mesh.dimension = [2, 2, 2]
|
||||
mesh.lower_left = [-160.0, -160.0, -183.0]
|
||||
mesh.upper_right = [160.0, 160.0, 183.0]
|
||||
|
||||
# Initialize the filters
|
||||
energy_filter = openmc.Filter(type='energy', bins=(0.0, 0.253e-6,
|
||||
1.0e-3, 1.0, 20.0))
|
||||
material_filter = openmc.Filter(type='material', bins=(1, 3))
|
||||
distrib_filter = openmc.Filter(type='distribcell', bins=(60))
|
||||
mesh_filter = openmc.Filter(type='mesh')
|
||||
mesh_filter.mesh = mesh
|
||||
|
||||
# Initialized the tallies
|
||||
tally = openmc.Tally(name='tally 1')
|
||||
tally.add_filter(material_filter)
|
||||
tally.add_filter(energy_filter)
|
||||
tally.add_filter(distrib_filter)
|
||||
tally.add_score('nu-fission')
|
||||
tally.add_score('total')
|
||||
tally.add_nuclide(u235)
|
||||
tally.add_nuclide(pu239)
|
||||
tallies_file.add_tally(tally)
|
||||
|
||||
tally = openmc.Tally(name='tally 2')
|
||||
tally.add_filter(energy_filter)
|
||||
tally.add_filter(mesh_filter)
|
||||
tally.add_score('total')
|
||||
tally.add_score('fission')
|
||||
tally.add_nuclide(u238)
|
||||
tally.add_nuclide(u235)
|
||||
tallies_file.add_tally(tally)
|
||||
tallies_file.add_mesh(mesh)
|
||||
|
||||
# Export tallies to file
|
||||
self._input_set.tallies = tallies_file
|
||||
super(TallyArithmeticTestHarness, self)._build_inputs()
|
||||
|
||||
def _get_results(self, hash_output=False):
|
||||
"""Digest info in the statepoint and return as a string."""
|
||||
|
||||
|
|
@ -28,20 +81,23 @@ class TallyArithmeticTestHarness(TestHarness):
|
|||
|
||||
# Perform all the tally arithmetic operations and output results
|
||||
outstr = ''
|
||||
tally_3 = tally_1 + tally_2
|
||||
outstr += repr(tally_3)
|
||||
outstr += str(tally_3.mean)
|
||||
|
||||
tally_3 = tally_1 - tally_2
|
||||
outstr += repr(tally_3)
|
||||
outstr += str(tally_3.mean)
|
||||
|
||||
tally_3 = tally_1 * tally_2
|
||||
outstr += repr(tally_3)
|
||||
outstr += str(tally_3.mean)
|
||||
|
||||
tally_3 = tally_1 / tally_2
|
||||
outstr += repr(tally_3)
|
||||
tally_3 = tally_1.hybrid_product(tally_2, '*', 'entrywise', 'tensor',
|
||||
'tensor')
|
||||
outstr += str(tally_3.mean)
|
||||
|
||||
tally_3 = tally_1.hybrid_product(tally_2, '*', 'entrywise', 'entrywise',
|
||||
'tensor')
|
||||
outstr += str(tally_3.mean)
|
||||
|
||||
tally_3 = tally_1.hybrid_product(tally_2, '*', 'entrywise', 'tensor',
|
||||
'entrywise')
|
||||
outstr += str(tally_3.mean)
|
||||
|
||||
tally_3 = tally_1.hybrid_product(tally_2, '*', 'entrywise', 'entrywise',
|
||||
'entrywise')
|
||||
outstr += str(tally_3.mean)
|
||||
|
||||
print(outstr)
|
||||
|
|
@ -54,6 +110,11 @@ class TallyArithmeticTestHarness(TestHarness):
|
|||
|
||||
return outstr
|
||||
|
||||
def _cleanup(self):
|
||||
super(TallyArithmeticTestHarness, self)._cleanup()
|
||||
f = os.path.join(os.getcwd(), 'tallies.xml')
|
||||
if os.path.exists(f): os.remove(f)
|
||||
|
||||
if __name__ == '__main__':
|
||||
harness = TallyArithmeticTestHarness('statepoint.10.h5', True)
|
||||
harness.main()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue