Add property setters for Tally.scores, nuclides, filters, triggers

This commit is contained in:
Paul Romano 2016-02-02 10:07:08 -06:00
parent 12f2467d6e
commit 9b152b0ddf
14 changed files with 257 additions and 279 deletions

View file

@ -109,29 +109,20 @@ energyout_filter = openmc.Filter(type='energyout', bins=[0., 20.])
# Instantiate the first Tally
first_tally = openmc.Tally(tally_id=1, name='first tally')
first_tally.add_filter(cell_filter)
scores = ['total', 'scatter', 'nu-scatter', \
first_tally.filters = [cell_filter]
scores = ['total', 'scatter', 'nu-scatter',
'absorption', 'fission', 'nu-fission']
for score in scores:
first_tally.add_score(score)
first_tally.scores = scores
# Instantiate the second Tally
second_tally = openmc.Tally(tally_id=2, name='second tally')
second_tally.add_filter(cell_filter)
second_tally.add_filter(energy_filter)
scores = ['total', 'scatter', 'nu-scatter', \
'absorption', 'fission', 'nu-fission']
for score in scores:
second_tally.add_score(score)
second_tally.filters = [cell_filter, energy_filter]
second_tally.scores = scores
# Instantiate the third Tally
third_tally = openmc.Tally(tally_id=3, name='third tally')
third_tally.add_filter(cell_filter)
third_tally.add_filter(energy_filter)
third_tally.add_filter(energyout_filter)
scores = ['scatter', 'nu-scatter', 'nu-fission']
for score in scores:
third_tally.add_score(score)
third_tally.filters = [cell_filter, energy_filter, energyout_filter]
third_tally.scores = ['scatter', 'nu-scatter', 'nu-fission']
# Instantiate a TalliesFile, register all Tallies, and export to XML
tallies_file = openmc.TalliesFile()

View file

@ -166,8 +166,8 @@ plot_file.export_to_xml()
# Instantiate a distribcell Tally
tally = openmc.Tally(tally_id=1)
tally.add_filter(openmc.Filter(type='distribcell', bins=[cell2.id]))
tally.add_score('total')
tally.filters = [openmc.Filter(type='distribcell', bins=[cell2.id])]
tally.scores = ['total']
# Instantiate a TalliesFile, register Tally/Mesh, and export to XML
tallies_file = openmc.TalliesFile()

View file

@ -175,8 +175,8 @@ mesh_filter.mesh = mesh
# Instantiate the Tally
tally = openmc.Tally(tally_id=1)
tally.add_filter(mesh_filter)
tally.add_score('total')
tally.filters = [mesh_filter]
tally.scores = ['total']
# Instantiate a TalliesFile, register Tally/Mesh, and export to XML
tallies_file = openmc.TalliesFile()

View file

@ -167,13 +167,13 @@ mesh_filter.mesh = mesh
# Instantiate tally Trigger
trigger = openmc.Trigger(trigger_type='rel_err', threshold=1E-2)
trigger.add_score('all')
trigger.scores = ['all']
# Instantiate the Tally
tally = openmc.Tally(tally_id=1)
tally.add_filter(mesh_filter)
tally.add_score('total')
tally.add_trigger(trigger)
tally.filters = [mesh_filter]
tally.scores = ['total']
tally.triggers = [trigger]
# Instantiate a TalliesFile, register Tally/Mesh, and export to XML
tallies_file = openmc.TalliesFile()

View file

@ -196,11 +196,8 @@ mesh_filter.mesh = mesh
# Instantiate the Tally
tally = openmc.Tally(tally_id=1, name='tally 1')
tally.add_filter(energy_filter)
tally.add_filter(mesh_filter)
tally.add_score('flux')
tally.add_score('fission')
tally.add_score('nu-fission')
tally.filters = [energy_filter, mesh_filter]
tally.scores = ['flux', 'fission', 'nu-fission']
# Instantiate a TalliesFile, register all Tallies, and export to XML
tallies_file = openmc.TalliesFile()

View file

@ -41,9 +41,9 @@ def check_type(name, value, expected_type, expected_iter_type=None):
Description of value being checked
value : object
Object to check type of
expected_type : type
expected_type : type or Iterable of type
type to check object against
expected_iter_type : type or None, optional
expected_iter_type : type or Iterable of type or None, optional
Expected type of each element in value, assuming it is iterable. If
None, no check will be performed.
@ -57,9 +57,15 @@ def check_type(name, value, expected_type, expected_iter_type=None):
if expected_iter_type:
for item in value:
if not _isinstance(item, expected_iter_type):
msg = 'Unable to set "{0}" to "{1}" since each item must be ' \
'of type "{2}"'.format(name, value,
expected_iter_type.__name__)
if isinstance(expected_iter_type, Iterable):
msg = 'Unable to set "{0}" to "{1}" since each item must be ' \
'one of the following types: "{2}"'.format(
name, value, ', '.join([t.__name__ for t in
expected_iter_type]))
else:
msg = 'Unable to set "{0}" to "{1}" since each item must be ' \
'of type "{2}"'.format(name, value,
expected_iter_type.__name__)
raise ValueError(msg)

View file

@ -510,27 +510,27 @@ class MGXS(object):
# Create each Tally needed to compute the multi group cross section
for score, key, filters in zip(scores, keys, all_filters):
self.tallies[key] = openmc.Tally(name=self.name)
self.tallies[key].add_score(score)
self.tallies[key].scores.append(score)
self.tallies[key].estimator = estimator
self.tallies[key].add_filter(domain_filter)
self.tallies[key].filters.append(domain_filter)
# If a tally trigger was specified, add it to each tally
if self.tally_trigger:
trigger_clone = copy.deepcopy(self.tally_trigger)
trigger_clone.add_score(score)
self.tallies[key].add_trigger(trigger_clone)
trigger_clone.scores.append(score)
self.tallies[key].triggers.append(trigger_clone)
# Add all non-domain specific Filters (e.g., 'energy') to the Tally
for add_filter in filters:
self.tallies[key].add_filter(add_filter)
self.tallies[key].filters.append(add_filter)
# If this is a by-nuclide cross-section, add all nuclides to Tally
if self.by_nuclide and score != 'flux':
all_nuclides = self.domain.get_all_nuclides()
for nuclide in all_nuclides:
self.tallies[key].add_nuclide(nuclide)
self.tallies[key].nuclides.append(nuclide)
else:
self.tallies[key].add_nuclide('total')
self.tallies[key].nuclides.append('total')
def _compute_xs(self):
"""Performs generic cleanup after a subclass' uses tally arithmetic to
@ -552,7 +552,7 @@ class MGXS(object):
self.xs_tally._nuclides = []
nuclides = self.domain.get_all_nuclides()
for nuclide in nuclides:
self.xs_tally.add_nuclide(openmc.Nuclide(nuclide))
self.xs_tally.nuclides.append(openmc.Nuclide(nuclide))
# Remove NaNs which may have resulted from divide-by-zero operations
self.xs_tally._mean = np.nan_to_num(self.xs_tally.mean)
@ -2087,7 +2087,7 @@ class Chi(MGXS):
super(Chi, self)._compute_xs()
# Add the coarse energy filter back to the nu-fission tally
nu_fission_in.add_filter(energy_filter)
nu_fission_in.filters.append(energy_filter)
return self._xs_tally
@ -2179,7 +2179,7 @@ class Chi(MGXS):
xs_tally = nu_fission_out / nu_fission_in
# Add the coarse energy filter back to the nu-fission tally
nu_fission_in.add_filter(energy_filter)
nu_fission_in.filters.append(energy_filter)
xs = xs_tally.get_values(filters=filters,
filter_bins=filter_bins, value=value)

View file

@ -389,7 +389,7 @@ class StatePoint(object):
new_filter.mesh = self.meshes[key]
# Add Filter to the Tally
tally.add_filter(new_filter)
tally.filters.append(new_filter)
# Read Nuclide bins
nuclide_names = \
@ -398,7 +398,7 @@ class StatePoint(object):
# Add all Nuclides to the Tally
for name in nuclide_names:
nuclide = openmc.Nuclide(name.decode().strip())
tally.add_nuclide(nuclide)
tally.nuclides.append(nuclide)
scores = self._f['{0}{1}/score_bins'.format(
base, tally_key)].value
@ -425,7 +425,7 @@ class StatePoint(object):
pattern = r'-n$|-pn$|-yn$'
score = re.sub(pattern, '-' + moments[j].decode(), score)
tally.add_score(score)
tally.scores.append(score)
# Add Tally to the global dictionary of all Tallies
tally.sparse = self.sparse

View file

@ -276,7 +276,7 @@ class Summary(object):
# Get the distribcell index
ind = self._f['geometry/cells'][key]['distribcell_index'].value
if ind != 0:
cell.distribcell_index = ind
cell.distribcell_index = ind
# Add the Cell to the global dictionary of all Cells
self.cells[index] = cell
@ -539,7 +539,7 @@ class Summary(object):
# 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)
tally.scores.append(score)
# Read filter metadata
num_filters = self._f['{0}/n_filters'.format(subbase)].value
@ -560,7 +560,7 @@ class Summary(object):
new_filter.num_bins = num_bins
# Add Filter to the Tally
tally.add_filter(new_filter)
tally.filters.append(new_filter)
# Add Tally to the global dictionary of all Tallies
self.tallies[tally_id] = tally

View file

@ -7,8 +7,9 @@ import os
import pickle
import itertools
from numbers import Integral, Real
from xml.etree import ElementTree as ET
import sys
import warnings
from xml.etree import ElementTree as ET
import numpy as np
@ -18,10 +19,13 @@ from openmc.filter import _FILTER_TYPES
import openmc.checkvalue as cv
from openmc.clean_xml import *
if sys.version_info[0] >= 3:
basestring = str
# DeprecationWarning filter for the Tally.add_*(...) methods
warnings.simplefilter('always', DeprecationWarning)
# "Static" variable for auto-generated Tally IDs
AUTO_TALLY_ID = 10000
@ -75,7 +79,7 @@ class Tally(object):
num_bins : Integral
Total number of bins for the tally
shape : 3-tuple of Integral
The shape of the tally data array ordered as the number of filter bins,
The shape of the tally data array ordered as the number of filter bins,
nuclide bins and score bins
num_realizations : Integral
Total number of realizations
@ -145,19 +149,19 @@ class Tally(object):
clone._filters = []
for self_filter in self.filters:
clone.add_filter(copy.deepcopy(self_filter, memo))
clone.filters.append(copy.deepcopy(self_filter, memo))
clone._nuclides = []
for nuclide in self.nuclides:
clone.add_nuclide(copy.deepcopy(nuclide, memo))
clone.nuclides.append(copy.deepcopy(nuclide, memo))
clone._scores = []
for score in self.scores:
clone.add_score(score)
clone.scores.append(score)
clone._triggers = []
for trigger in self.triggers:
clone.add_trigger(trigger)
clone.triggers.append(trigger)
memo[id(self)] = clone
@ -423,6 +427,11 @@ class Tally(object):
['analog', 'tracklength', 'collision'])
self._estimator = estimator
@triggers.setter
def triggers(self, triggers):
cv.check_type('tally triggers', trigger, Iterable, Trigger)
self._triggers = triggers
def add_trigger(self, trigger):
"""Add a tally trigger to the tally
@ -433,13 +442,11 @@ class Tally(object):
"""
if not isinstance(trigger, Trigger):
msg = 'Unable to add a tally trigger for Tally ID="{0}" to ' \
'since "{1}" is not a Trigger'.format(self.id, trigger)
raise ValueError(msg)
if trigger not in self.triggers:
self.triggers.append(trigger)
warnings.warn("Tally.add_trigger(...) has been deprecated and may be "
"removed in a future version. Tally triggers should be "
"defined using the triggers property directly.",
DeprecationWarning)
self.triggers.append(trigger)
@id.setter
def id(self, tally_id):
@ -460,6 +467,55 @@ class Tally(object):
else:
self._name = ''
@filters.setter
def filters(self, filters):
cv.check_type('tally filters', filters, Iterable,
(Filter, CrossFilter, AggregateFilter))
# If the filter is already in the Tally, raise an error
for i, f in enumerate(filters[:-1]):
if f in filters[i+1:]:
msg = 'Unable to add a duplicate filter "{0}" to Tally ID="{1}" ' \
'since duplicate filters are not supported in the OpenMC ' \
'Python API'.format(f, self.id)
raise ValueError(msg)
self._filters = filters
@nuclides.setter
def nuclides(self, nuclides):
cv.check_type('tally nuclides', nuclides, Iterable,
(basestring, Nuclide, CrossNuclide, AggregateNuclide))
# If the nuclide is already in the Tally, raise an error
for i, nuclide in enumerate(nuclides[:-1]):
if nuclide in nuclides[i+1:]:
msg = 'Unable to add a duplicate nuclide "{0}" to Tally ID="{1}" ' \
'since duplicate nuclides are not supported in the OpenMC ' \
'Python API'.format(nuclide, self.id)
raise ValueError(msg)
self._nuclides = nuclides
@scores.setter
def scores(self, scores):
cv.check_type('tally scores', scores, Iterable,
(basestring, CrossScore, AggregateScore))
for i, score in enumerate(scores[:-1]):
# If the score is already in the Tally, raise an error
if score in scores[i+1:]:
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)
# If score is a string, strip whitespace
if isinstance(score, basestring):
scores[i] = score.strip()
self._scores = scores
def add_filter(self, new_filter):
"""Add a filter to the tally
@ -475,19 +531,11 @@ class Tally(object):
"""
if not isinstance(new_filter, (Filter, CrossFilter, AggregateFilter)):
msg = 'Unable to add Filter "{0}" to Tally ID="{1}" since it is ' \
'not a Filter object'.format(new_filter, self.id)
raise ValueError(msg)
# If the filter is already in the Tally, raise an error
if new_filter in self.filters:
msg = 'Unable to add a duplicate filter "{0}" to Tally ID="{1}" ' \
'since duplicate filters are not supported in the OpenMC ' \
'Python API'.format(new_filter, self.id)
raise ValueError(msg)
self._filters.append(new_filter)
warnings.warn("Tally.add_filter(...) has been deprecated and may be "
"removed in a future version. Tally filters should be "
"defined using the filters property directly.",
DeprecationWarning)
self.filters.append(new_filter)
def add_nuclide(self, nuclide):
"""Specify that scores for a particular nuclide should be accumulated
@ -504,20 +552,11 @@ class Tally(object):
"""
if not isinstance(nuclide, (basestring, Nuclide,
CrossNuclide, AggregateNuclide)):
msg = 'Unable to add nuclide "{0}" to Tally ID="{1}" since it is ' \
'not a Nuclide object'.format(nuclide)
raise ValueError(msg)
# If the nuclide is already in the Tally, raise an error
if nuclide in self.nuclides:
msg = 'Unable to add a duplicate nuclide "{0}" to Tally ID="{1}" ' \
'since duplicate nuclides are not supported in the OpenMC ' \
'Python API'.format(nuclide, self.id)
raise ValueError(msg)
self._nuclides.append(nuclide)
warnings.warn("Tally.add_nuclide(...) has been deprecated and may be "
"removed in a future version. Tally nuclides should be "
"defined using the nuclides property directly.",
DeprecationWarning)
self.nuclides.append(nuclide)
def add_score(self, score):
"""Specify a quantity to be scored
@ -533,24 +572,11 @@ class Tally(object):
"""
if not isinstance(score, (basestring, CrossScore, AggregateScore)):
msg = 'Unable to add score "{0}" to Tally ID="{1}" since it is ' \
'not a string'.format(score, self.id)
raise ValueError(msg)
# If the score is already in the Tally, raise an error
if score in self.scores:
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())
# CrossScores and AggrgateScore
else:
self._scores.append(score)
warnings.warn("Tally.add_score(...) has been deprecated and may be "
"removed in a future version. Tally scores should be "
"defined using the scores property directly.",
DeprecationWarning)
self.scores.append(score)
@num_realizations.setter
def num_realizations(self, num_realizations):
@ -771,11 +797,11 @@ class Tally(object):
# Add unique scores from second tally to merged tally
for score in tally.scores:
if score not in merged_tally.scores:
merged_tally.add_score(score)
merged_tally.scores.append(score)
# Add triggers from second tally to merged tally
for trigger in tally.triggers:
merged_tally.add_trigger(trigger)
merged_tally.triggers.append(trigger)
return merged_tally
@ -1723,33 +1749,33 @@ class Tally(object):
# Add filters to the new tally
if filter_product == 'entrywise':
for self_filter in self_copy.filters:
new_tally.add_filter(self_filter)
new_tally.filters.append(self_filter)
else:
all_filters = [self_copy.filters, other_copy.filters]
for self_filter, other_filter in itertools.product(*all_filters):
new_filter = CrossFilter(self_filter, other_filter, binary_op)
new_tally.add_filter(new_filter)
new_tally.filters.append(new_filter)
# Add nuclides to the new tally
if nuclide_product == 'entrywise':
for self_nuclide in self_copy.nuclides:
new_tally.add_nuclide(self_nuclide)
new_tally.nuclides.append(self_nuclide)
else:
all_nuclides = [self_copy.nuclides, other_copy.nuclides]
for self_nuclide, other_nuclide in itertools.product(*all_nuclides):
new_nuclide = \
CrossNuclide(self_nuclide, other_nuclide, binary_op)
new_tally.add_nuclide(new_nuclide)
new_tally.nuclides.append(new_nuclide)
# Add scores to the new tally
if score_product == 'entrywise':
for self_score in self_copy.scores:
new_tally.add_score(self_score)
new_tally.scores.append(self_score)
else:
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)
new_tally.scores.append(new_score)
# Update the new tally's filter strides
new_tally._update_filter_strides()
@ -1812,14 +1838,14 @@ class Tally(object):
filter_copy = copy.deepcopy(other_filter)
other._mean = np.repeat(other.mean, filter_copy.num_bins, axis=0)
other._std_dev = np.repeat(other.std_dev, filter_copy.num_bins, axis=0)
other.add_filter(filter_copy)
other.filters.append(filter_copy)
# Add filters present in other but not in self to self
for self_filter in self_missing_filters:
filter_copy = copy.deepcopy(self_filter)
self._mean = np.repeat(self.mean, filter_copy.num_bins, axis=0)
self._std_dev = np.repeat(self.std_dev, filter_copy.num_bins, axis=0)
self.add_filter(filter_copy)
self.filters.append(filter_copy)
# Align other filters with self filters
for i, self_filter in enumerate(self.filters):
@ -1842,7 +1868,7 @@ class Tally(object):
np.tile(other.std_dev, (1, self.num_nuclides, 1))
# Add nuclides to each tally such that each tally contains the complete
# set of nuclides necessary to perform an entrywise product. New
# set of nuclides necessary to perform an entrywise product. New
# nuclides added to a tally will have all their scores set to zero.
else:
@ -1858,7 +1884,7 @@ class Tally(object):
np.insert(other.mean, other.num_nuclides, 0, axis=1)
other._std_dev = \
np.insert(other.std_dev, other.num_nuclides, 0, axis=1)
other.add_nuclide(nuclide)
other.nuclides.append(nuclide)
# Add nuclides present in other but not in self to self
for nuclide in self_missing_nuclides:
@ -1866,7 +1892,7 @@ class Tally(object):
np.insert(self.mean, self.num_nuclides, 0, axis=1)
self._std_dev = \
np.insert(self.std_dev, self.num_nuclides, 0, axis=1)
self.add_nuclide(nuclide)
self.nuclides.append(nuclide)
# Align other nuclides with self nuclides
for i, nuclide in enumerate(self.nuclides):
@ -1899,13 +1925,13 @@ class Tally(object):
for score in other_missing_scores:
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)
other.scores.append(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_scores, 0, axis=2)
self._std_dev = np.insert(self.std_dev, self.num_scores, 0, axis=2)
self.add_score(score)
self.scores.append(score)
# Align other scores with self scores
for i, score in enumerate(self.scores):
@ -2210,12 +2236,9 @@ class Tally(object):
new_tally.with_summary = self.with_summary
new_tally.num_realization = self.num_realizations
for self_filter in self.filters:
new_tally.add_filter(self_filter)
for nuclide in self.nuclides:
new_tally.add_nuclide(nuclide)
for score in self.scores:
new_tally.add_score(score)
new_tally.filters = self.filters
new_tally.nuclides = self.nuclides
new_tally.scores = self.scores
# If this tally operand is sparse, sparsify the new tally
new_tally.sparse = self.sparse
@ -2284,12 +2307,9 @@ class Tally(object):
new_tally.with_summary = self.with_summary
new_tally.num_realization = self.num_realizations
for self_filter in self.filters:
new_tally.add_filter(self_filter)
for nuclide in self.nuclides:
new_tally.add_nuclide(nuclide)
for score in self.scores:
new_tally.add_score(score)
new_tally.filters = self.filters
new_tally.nuclides = self.nuclides
new_tally.scores = self.scores
# If this tally operand is sparse, sparsify the new tally
new_tally.sparse = self.sparse
@ -2359,12 +2379,9 @@ class Tally(object):
new_tally.with_summary = self.with_summary
new_tally.num_realization = self.num_realizations
for self_filter in self.filters:
new_tally.add_filter(self_filter)
for nuclide in self.nuclides:
new_tally.add_nuclide(nuclide)
for score in self.scores:
new_tally.add_score(score)
new_tally.filters = self.filters
new_tally.nuclides = self.nuclides
new_tally.scores = self.scores
# If this tally operand is sparse, sparsify the new tally
new_tally.sparse = self.sparse
@ -2434,12 +2451,9 @@ class Tally(object):
new_tally.with_summary = self.with_summary
new_tally.num_realization = self.num_realizations
for self_filter in self.filters:
new_tally.add_filter(self_filter)
for nuclide in self.nuclides:
new_tally.add_nuclide(nuclide)
for score in self.scores:
new_tally.add_score(score)
new_tally.filters = self.filters
new_tally.nuclides = self.nuclides
new_tally.scores = self.scores
# If this tally operand is sparse, sparsify the new tally
new_tally.sparse = self.sparse
@ -2513,12 +2527,9 @@ class Tally(object):
new_tally.with_summary = self.with_summary
new_tally.num_realization = self.num_realizations
for self_filter in self.filters:
new_tally.add_filter(self_filter)
for nuclide in self.nuclides:
new_tally.add_nuclide(nuclide)
for score in self.scores:
new_tally.add_score(score)
new_tally.filters = self.filters
new_tally.nuclides = self.nuclides
new_tally.scores = self.scores
# If original tally was sparse, sparsify the exponentiated tally
new_tally.sparse = self.sparse
@ -2853,11 +2864,11 @@ class Tally(object):
if not remove_filter:
filter_sum = \
AggregateFilter(self_filter, filter_bins, 'sum')
tally_sum.add_filter(filter_sum)
tally_sum.filters.append(filter_sum)
# Add a copy of each filter not summed across to the tally sum
else:
tally_sum.add_filter(copy.deepcopy(self_filter))
tally_sum.filters.append(copy.deepcopy(self_filter))
# Add a copy of this tally's filters to the tally sum
else:
@ -2875,7 +2886,7 @@ class Tally(object):
# Add AggregateNuclide to the tally sum
nuclide_sum = AggregateNuclide(nuclides, 'sum')
tally_sum.add_nuclide(nuclide_sum)
tally_sum.nuclides.append(nuclide_sum)
# Add a copy of this tally's nuclides to the tally sum
else:
@ -2893,7 +2904,7 @@ class Tally(object):
# Add AggregateScore to the tally sum
score_sum = AggregateScore(scores, 'sum')
tally_sum.add_score(score_sum)
tally_sum.scores.append(score_sum)
# Add a copy of this tally's scores to the tally sum
else:
@ -2946,7 +2957,7 @@ class Tally(object):
# Add the new filter to a copy of this Tally
new_tally = copy.deepcopy(self)
new_tally.add_filter(new_filter)
new_tally.filters.append(new_filter)
# Determine "base" indices along the new "diagonal", and the factor
# by which the "base" indices should be repeated to account for all

View file

@ -1,6 +1,7 @@
from numbers import Real
from xml.etree import ElementTree as ET
import sys
import warnings
from openmc.checkvalue import check_type, check_value
@ -8,6 +9,10 @@ if sys.version_info[0] >= 3:
basestring = str
# DeprecationWarning filter for the Trigger.add_score(...) method
warnings.simplefilter('always', DeprecationWarning)
class Trigger(object):
"""A criterion for when to finish a simulation based on tally uncertainties.
@ -46,9 +51,7 @@ class Trigger(object):
clone._trigger_type = self._trigger_type
clone._threshold = self._threshold
clone._scores = []
for score in self._scores:
clone.add_score(score)
clone.scores = self.scores
memo[id(self)] = clone
@ -97,6 +100,17 @@ class Trigger(object):
check_type('tally trigger threshold', threshold, Real)
self._threshold = threshold
@scores.setter
def scores(self, scores):
cv.check_type('trigger scores', scores, Iterable, basestring)
# Set scores making sure not to have duplicates
self._scores = []
for score in scores:
if score not in self._scores:
self._scores.append(score)
def add_score(self, score):
"""Add a score to the list of scores to be checked against the trigger.
@ -107,16 +121,11 @@ class Trigger(object):
"""
if not isinstance(score, basestring):
msg = 'Unable to add score "{0}" to tally trigger since ' \
'it is not a string'.format(score)
raise ValueError(msg)
# If the score is already in the Tally, don't add it again
if score in self._scores:
return
else:
self._scores.append(score)
warnings.warn("Trigger.add_score(...) has been deprecated and may be "
"removed in a future version. Tally trigger scores should "
"be defined using the scores property directly.",
DeprecationWarning)
self.scores.append(score)
def get_trigger_xml(self, element):
"""Return XML representation of the trigger

View file

@ -23,19 +23,19 @@ class TalliesTestHarness(PyAPITestHarness):
azimuthal_bins = (-3.1416, -1.8850, -0.6283, 0.6283, 1.8850, 3.1416)
azimuthal_filter1 = Filter(type='azimuthal', bins=azimuthal_bins)
azimuthal_tally1 = Tally()
azimuthal_tally1.add_filter(azimuthal_filter1)
azimuthal_tally1.add_score('flux')
azimuthal_tally1.filters = [azimuthal_filter1]
azimuthal_tally1.scores = ['flux']
azimuthal_tally1.estimator = 'tracklength'
azimuthal_tally2 = Tally()
azimuthal_tally2.add_filter(azimuthal_filter1)
azimuthal_tally2.add_score('flux')
azimuthal_tally2.filters = [azimuthal_filter1]
azimuthal_tally2.scores = ['flux']
azimuthal_tally2.estimator = 'analog'
azimuthal_filter2 = Filter(type='azimuthal', bins=(5,))
azimuthal_tally3 = Tally()
azimuthal_tally3.add_filter(azimuthal_filter2)
azimuthal_tally3.add_score('flux')
azimuthal_tally3.filters = [azimuthal_filter2]
azimuthal_tally3.scores = ['flux']
azimuthal_tally3.estimator = 'tracklength'
mesh_2x2 = Mesh(mesh_id=1)
@ -44,154 +44,129 @@ class TalliesTestHarness(PyAPITestHarness):
mesh_2x2.dimension = [2, 2]
mesh_filter = Filter(type='mesh', bins=(1,))
azimuthal_tally4 = Tally()
azimuthal_tally4.add_filter(azimuthal_filter2)
azimuthal_tally4.add_filter(mesh_filter)
azimuthal_tally4.add_score('flux')
azimuthal_tally4.filters = [azimuthal_filter2, mesh_filter]
azimuthal_tally4.scores = ['flux']
azimuthal_tally4.estimator = 'tracklength'
cellborn_tally = Tally()
cellborn_tally.add_filter(Filter(type='cellborn', bins=(10, 21, 22, 23)))
cellborn_tally.add_score('total')
cellborn_tally.filters = [Filter(type='cellborn', bins=(10, 21, 22, 23))]
cellborn_tally.scores = ['total']
dg_tally = Tally()
dg_tally.add_filter(Filter(type='delayedgroup', bins=(1, 2, 3, 4, 5, 6)))
dg_tally.add_score('delayed-nu-fission')
dg_tally.filters = [Filter(type='delayedgroup', bins=(1, 2, 3, 4, 5, 6))]
dg_tally.scores = ['delayed-nu-fission']
four_groups = (0.0, 0.253e-6, 1.0e-3, 1.0, 20.0)
energy_filter = Filter(type='energy', bins=four_groups)
energy_tally = Tally()
energy_tally.add_filter(energy_filter)
energy_tally.add_score('total')
energy_tally.filters = [energy_filter]
energy_tally.scores = ['total']
energyout_filter = Filter(type='energyout', bins=four_groups)
energyout_tally = Tally()
energyout_tally.add_filter(energyout_filter)
energyout_tally.add_score('scatter')
energyout_tally.filters = [energyout_filter]
energyout_tally.scores = ['scatter']
transfer_tally = Tally()
transfer_tally.add_filter(energy_filter)
transfer_tally.add_filter(energyout_filter)
transfer_tally.add_score('scatter')
transfer_tally.add_score('nu-fission')
transfer_tally.filters = [energy_filter, energyout_filter]
transfer_tally.scores = ['scatter', 'nu-fission']
material_tally = Tally()
material_tally.add_filter(Filter(type='material', bins=(1, 2, 3, 4)))
material_tally.add_score('total')
material_tally.filters = [Filter(type='material', bins=(1, 2, 3, 4))]
material_tally.scores = ['total']
mu_tally1 = Tally()
mu_tally1.add_filter(Filter(type='mu', bins=(-1.0, -0.5, 0.0, 0.5, 1.0)))
mu_tally1.add_score('scatter')
mu_tally1.add_score('nu-scatter')
mu_tally1.filters = [Filter(type='mu', bins=(-1.0, -0.5, 0.0, 0.5, 1.0))]
mu_tally1.scores = ['scatter', 'nu-scatter']
mu_filter = Filter(type='mu', bins=(5,))
mu_tally2 = Tally()
mu_tally2.add_filter(mu_filter)
mu_tally2.add_score('scatter')
mu_tally2.add_score('nu-scatter')
mu_tally2.filters = [mu_filter]
mu_tally2.scores = ['scatter', 'nu-scatter']
mu_tally3 = Tally()
mu_tally3.add_filter(mu_filter)
mu_tally3.add_filter(mesh_filter)
mu_tally3.add_score('scatter')
mu_tally3.add_score('nu-scatter')
mu_tally3.filters = [mu_filter, mesh_filter]
mu_tally3.scores = ['scatter', 'nu-scatter']
polar_bins = (0.0, 0.6283, 1.2566, 1.8850, 2.5132, 3.1416)
polar_filter = Filter(type='polar', bins=polar_bins)
polar_tally1 = Tally()
polar_tally1.add_filter(polar_filter)
polar_tally1.add_score('flux')
polar_tally1.filters = [polar_filter]
polar_tally1.scores = ['flux']
polar_tally1.estimator = 'tracklength'
polar_tally2 = Tally()
polar_tally2.add_filter(polar_filter)
polar_tally2.add_score('flux')
polar_tally2.filters = [polar_filter]
polar_tally2.scores = ['flux']
polar_tally2.estimator = 'analog'
polar_filter2 = Filter(type='polar', bins=(5,))
polar_tally3 = Tally()
polar_tally3.add_filter(polar_filter2)
polar_tally3.add_score('flux')
polar_tally3.filters = [polar_filter2]
polar_tally3.scores = ['flux']
polar_tally3.estimator = 'tracklength'
polar_tally4 = Tally()
polar_tally4.add_filter(polar_filter2)
polar_tally4.add_filter(mesh_filter)
polar_tally4.add_score('flux')
polar_tally4.filters = [polar_filter2, mesh_filter]
polar_tally4.scores = ['flux']
polar_tally4.estimator = 'tracklength'
universe_tally = Tally()
universe_tally.add_filter(Filter(type='universe', bins=(1, 2, 3, 4)))
universe_tally.add_score('total')
universe_tally.filters = [Filter(type='universe', bins=(1, 2, 3, 4))]
universe_tally.scores = ['total']
cell_filter = Filter(type='cell', bins=(10, 21, 22, 23))
score_tallies = [Tally(), Tally(), Tally()]
for t in score_tallies:
t.add_filter(cell_filter)
t.add_score('absorption')
t.add_score('delayed-nu-fission')
t.add_score('events')
t.add_score('fission')
t.add_score('inverse-velocity')
t.add_score('kappa-fission')
t.add_score('(n,2n)')
t.add_score('(n,n1)')
t.add_score('(n,gamma)')
t.add_score('nu-fission')
t.add_score('scatter')
t.add_score('elastic')
t.add_score('total')
t.filters = [cell_filter]
t.scores = ['absorption', 'delayed-nu-fission', 'events', 'fission',
'inverse-velocity', 'kappa-fission', '(n,2n)', '(n,n1)',
'(n,gamma)', 'nu-fission', 'scatter', 'elastic', 'total']
score_tallies[0].estimator = 'tracklength'
score_tallies[1].estimator = 'analog'
score_tallies[2].estimator = 'collision'
cell_filter2 = Filter(type='cell', bins=(21, 22, 23, 27, 28, 29))
flux_tallies = [Tally() for i in range(4)]
[t.add_filter(cell_filter2) for t in flux_tallies]
flux_tallies[0].add_score('flux')
[t.add_score('flux-y5') for t in flux_tallies[1:]]
for t in flux_tallies:
t.filters = [cell_filter2]
flux_tallies[0].scores = ['flux']
for t in flux_tallies[1:]:
t.scores = ['flux-y5']
flux_tallies[1].estimator = 'tracklength'
flux_tallies[2].estimator = 'analog'
flux_tallies[3].estimator = 'collision'
scatter_tally1 = Tally()
scatter_tally1.add_filter(cell_filter)
scatter_tally1.add_score('scatter')
scatter_tally1.add_score('scatter-1')
scatter_tally1.add_score('scatter-2')
scatter_tally1.add_score('scatter-3')
scatter_tally1.add_score('scatter-4')
scatter_tally1.add_score('nu-scatter')
scatter_tally1.add_score('nu-scatter-1')
scatter_tally1.add_score('nu-scatter-2')
scatter_tally1.add_score('nu-scatter-3')
scatter_tally1.add_score('nu-scatter-4')
scatter_tally1.filters = [cell_filter]
scatter_tally1.scores = ['scatter', 'scatter-1', 'scatter-2', 'scatter-3',
'scatter-4', 'nu-scatter', 'nu-scatter-1',
'nu-scatter-2', 'nu-scatter-3', 'nu-scatter-4']
scatter_tally2 = Tally()
scatter_tally2.add_filter(cell_filter)
scatter_tally2.add_score('scatter-p4')
scatter_tally2.add_score('scatter-y4')
scatter_tally2.add_score('nu-scatter-p4')
scatter_tally2.add_score('nu-scatter-y3')
scatter_tally2.filters = [cell_filter]
scatter_tally2.scores = ['scatter-p4', 'scatter-y4', 'nu-scatter-p4',
'nu-scatter-y3']
total_tallies = [Tally() for i in range(4)]
[t.add_filter(cell_filter) for t in total_tallies]
total_tallies[0].add_score('total')
[t.add_score('total-y4') for t in total_tallies[1:]]
[t.add_nuclide('U-235') for t in total_tallies[1:]]
[t.add_nuclide('total') for t in total_tallies[1:]]
for t in total_tallies:
t.filters = [cell_filter]
total_tallies[0].scores = ['total']
for t in total_tallies[1:]:
t.scores = ['total-y4']
t.nuclides = ['U-235', 'total']
total_tallies[1].estimator = 'tracklength'
total_tallies[2].estimator = 'analog'
total_tallies[3].estimator = 'collision'
questionable_tally = Tally()
questionable_tally.add_score('transport')
questionable_tally.add_score('n1n')
questionable_tally.scores = ['transport', 'n1n']
all_nuclide_tallies = [Tally(), Tally()]
for t in all_nuclide_tallies:
t.add_filter(cell_filter)
t.add_nuclide('all')
t.add_score('total')
t.filters = [cell_filter]
t.nuclides = ['all']
t.scores = ['total']
all_nuclide_tallies[0].estimator = 'tracklength'
all_nuclide_tallies[0].estimator = 'collision'

View file

@ -30,13 +30,9 @@ class TallyAggregationTestHarness(PyAPITestHarness):
# Initialized the tallies
tally = openmc.Tally(name='distribcell tally')
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(u238)
tally.add_nuclide(pu239)
tally.filters = [energy_filter, distrib_filter]
tally.scores = ['nu-fission', 'total']
tally.nuclides = [u235, u238, pu239]
tallies_file.add_tally(tally)
# Export tallies to file

View file

@ -40,22 +40,15 @@ class TallyArithmeticTestHarness(PyAPITestHarness):
# 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)
tally.filters = [material_filter, energy_filter, distrib_filter]
tally.scores = ['nu-fission', 'total']
tally.nuclides = [u235, 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)
tally.filters = [energy_filter, mesh_filter]
tally.scores = ['total', 'fission']
tally.nuclides = [u238, u235]
tallies_file.add_tally(tally)
tallies_file.add_mesh(mesh)