Fixed merge conflicts with tally-align branch

This commit is contained in:
wbinventor@gmail.com 2015-12-24 20:44:41 -05:00
commit f7d3380251
17 changed files with 439 additions and 384 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1 +1 @@
63295b9d510370e65e63a3db627d47d286f5479e53c8eabeda9a5cb25ffe35becb636835aadad11691e34c23292fe11b5f688daee76d76ceac4b5dfd2f9ede4c
7270299e4a4dde19d250825b0124fa36b60df847f046e058ccdfc74d4690beaaaaf387e050f596cb3445caf793d6a390ddb2d19650a3dccd4eb60056ae3b1477

View file

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

View file

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

View file

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

View file

@ -0,0 +1 @@
df6318b76cd37a29ef9dd09da48a70c191ed07c1a2ceb75eb502ab35086c31250872406f22c2587edfcee16f67dd95c81db012ccd728710ed2509084438aea56

View file

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

View file

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

View file

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

View file

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

View file

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