-
Notifications
You must be signed in to change notification settings - Fork 503
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding methods to automatically apply results to existing Tally objects. #2671
base: develop
Are you sure you want to change the base?
Changes from all commits
a364244
481dd48
d58c811
6322a30
0f9d35c
a761b42
41841f1
495eec2
df3469a
5734b75
165b340
0f69c6f
bf0d60c
e8fcebf
d39c4a5
38b1467
5af1eea
5e46acf
fa4d976
03d80eb
7699d48
3ac0ca3
2fb7e3d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -161,6 +161,9 @@ def __enter__(self): | |
def __exit__(self, *exc): | ||
self.close() | ||
|
||
def __del__(self): | ||
self.close() | ||
|
||
@property | ||
def cmfd_on(self): | ||
return self._f.attrs['cmfd_on'] > 0 | ||
|
@@ -392,6 +395,7 @@ def tallies(self): | |
if self.tallies_present and not self._tallies_read: | ||
# Read the number of tallies | ||
tallies_group = self._f['tallies'] | ||
|
||
n_tallies = tallies_group.attrs['n_tallies'] | ||
|
||
# Read a list of the IDs for each Tally | ||
|
@@ -407,64 +411,77 @@ def tallies(self): | |
|
||
# Iterate over all tallies | ||
for tally_id in tally_ids: | ||
group = tallies_group[f'tally {tally_id}'] | ||
|
||
# Check if tally is internal and therefore has no data | ||
Comment on lines
-410
to
-412
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to have moved to |
||
if group.attrs.get("internal"): | ||
continue | ||
|
||
# Create Tally object and assign basic properties | ||
tally = openmc.Tally(tally_id) | ||
tally._sp_filename = self._f.filename | ||
tally.name = group['name'][()].decode() if 'name' in group else '' | ||
|
||
# Check if tally has multiply_density attribute | ||
if "multiply_density" in group.attrs: | ||
tally.multiply_density = group.attrs["multiply_density"].item() > 0 | ||
|
||
# Read the number of realizations | ||
n_realizations = group['n_realizations'][()] | ||
|
||
tally.estimator = group['estimator'][()].decode() | ||
tally.num_realizations = n_realizations | ||
|
||
# Read derivative information. | ||
if 'derivative' in group: | ||
deriv_id = group['derivative'][()] | ||
tally.derivative = self.tally_derivatives[deriv_id] | ||
|
||
# Read all filters | ||
n_filters = group['n_filters'][()] | ||
if n_filters > 0: | ||
filter_ids = group['filters'][()] | ||
filters_group = self._f['tallies/filters'] | ||
for filter_id in filter_ids: | ||
filter_group = filters_group[f'filter {filter_id}'] | ||
new_filter = openmc.Filter.from_hdf5( | ||
filter_group, meshes=self.meshes) | ||
tally.filters.append(new_filter) | ||
|
||
# Read nuclide bins | ||
nuclide_names = group['nuclides'][()] | ||
|
||
# Add all nuclides to the Tally | ||
for name in nuclide_names: | ||
nuclide = openmc.Nuclide(name.decode().strip()) | ||
tally.nuclides.append(nuclide) | ||
|
||
# Add the scores to the Tally | ||
scores = group['score_bins'][()] | ||
for score in scores: | ||
tally.scores.append(score.decode()) | ||
|
||
# Add Tally to the global dictionary of all Tallies | ||
tally.sparse = self.sparse | ||
self._tallies[tally_id] = tally | ||
tally = self._read_tally(tally_id) | ||
if tally is not None: | ||
self._tallies[tally_id] = tally | ||
|
||
self._tallies_read = True | ||
|
||
return self._tallies | ||
|
||
def _read_tally(self, tally_id): | ||
if self._f['tallies'][f'tally {tally_id}'].attrs.get('internal'): | ||
return | ||
tally = openmc.Tally(tally_id) | ||
self._populate_tally(tally) | ||
return tally | ||
|
||
def _populate_tally(self, tally): | ||
group = self._f['tallies'][f'tally {tally.id}'] | ||
|
||
# Check if tally is internal and therefore has no data | ||
if group.attrs.get('internal'): | ||
return | ||
|
||
tally._sp_filename = self._f.filename | ||
tally.name = group['name'][()].decode() if 'name' in group else '' | ||
|
||
# Check if tally has multiply_density attribute | ||
if "multiply_density" in group.attrs: | ||
tally.multiply_density = group.attrs["multiply_density"].item() > 0 | ||
|
||
# Read the number of realizations | ||
n_realizations = group['n_realizations'][()] | ||
|
||
# accept the estimator set during execution of OpenMC | ||
estimator = group['estimator'][()].decode() | ||
if tally.estimator is not None and tally.estimator != estimator: | ||
warnings.warn(f"Estimator for Tally {tally.id} changed from " | ||
f"{tally.estimator} to {estimator} in OpenMC execution") | ||
tally.estimator = estimator | ||
|
||
tally.num_realizations = n_realizations | ||
|
||
# Read derivative information. | ||
if 'derivative' in group: | ||
deriv_id = group['derivative'][()] | ||
tally.derivative = self.tally_derivatives[deriv_id] | ||
|
||
# Read all filters | ||
n_filters = group['n_filters'][()] | ||
if n_filters > 0: | ||
filter_ids = group['filters'][()] | ||
filters_group = self._f['tallies/filters'] | ||
tally.filters = [] | ||
for filter_id in filter_ids: | ||
filter_group = filters_group[f'filter {filter_id}'] | ||
new_filter = openmc.Filter.from_hdf5( | ||
filter_group, meshes=self.meshes) | ||
tally.filters.append(new_filter) | ||
|
||
# Read nuclide bins | ||
nuclide_names = group['nuclides'][()] | ||
|
||
# Add all nuclides to the Tally | ||
tally.nuclides = [openmc.Nuclide(name.decode().strip()) for name in nuclide_names] | ||
|
||
# Add the scores to the Tally | ||
scores = group['score_bins'][()] | ||
tally.scores = [score.decode() for score in scores] | ||
|
||
# Add Tally to the global dictionary of all Tallies | ||
tally.sparse = self.sparse | ||
|
||
@property | ||
def tallies_present(self): | ||
return self._f.attrs['tallies_present'] > 0 | ||
|
@@ -524,9 +541,39 @@ def add_volume_information(self, volume_calc): | |
if self.summary is not None: | ||
self.summary.add_volume_information(volume_calc) | ||
|
||
def match_tally(self, tally): | ||
""" | ||
Find a tally with an exact specification match. | ||
|
||
.. versionadded:: 0.15.1 | ||
|
||
Parameters | ||
---------- | ||
tally : openmc.Tally instance | ||
The Tally object to match. | ||
|
||
Returns | ||
------- | ||
None or openmc.Tally | ||
""" | ||
sp_tally = self.get_tally(tally.scores, | ||
tally.filters, | ||
tally.nuclides, | ||
tally.name, | ||
tally.id, | ||
tally.estimator, | ||
exact_filters=True, | ||
exact_nuclides=True, | ||
exact_scores=True, | ||
multiply_density=True, | ||
derivative=tally.derivative) | ||
Comment on lines
+559
to
+569
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't feel PEP8. With such a long arguments list keyword arguments should be used to avoid off-by-1 errors. |
||
|
||
return sp_tally | ||
|
||
def get_tally(self, scores=[], filters=[], nuclides=[], | ||
name=None, id=None, estimator=None, exact_filters=False, | ||
exact_nuclides=False, exact_scores=False): | ||
exact_nuclides=False, exact_scores=False, | ||
multiply_density=None, derivative=None): | ||
"""Finds and returns a Tally object with certain properties. | ||
|
||
This routine searches the list of Tallies and returns the first Tally | ||
|
@@ -564,6 +611,12 @@ def get_tally(self, scores=[], filters=[], nuclides=[], | |
If True, the number of scores in the parameters must be identical | ||
to those in the matching Tally. If False (default), the scores | ||
in the parameters may be a subset of those in the matching Tally. | ||
Default is None (no check). | ||
multiply_density : bool, optional | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This feels more like an |
||
If True, the Tally must have the multiply by density flag set to | ||
the same value as the input parameter. Default is True. | ||
derivative : openmc.TallyDerivative, optional | ||
TallyDerivative object to match. Default is None. | ||
|
||
Returns | ||
------- | ||
|
@@ -591,17 +644,25 @@ def get_tally(self, scores=[], filters=[], nuclides=[], | |
if id and id != test_tally.id: | ||
continue | ||
|
||
# Determine if Tally has queried estimator | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a bit out of scope, but why iterate over |
||
if estimator and estimator != test_tally.estimator: | ||
# Determine if Tally has queried estimator, only move on to next tally | ||
# if the estimator is both specified and the tally estimtor does not | ||
# match | ||
if estimator is not None and estimator != test_tally.estimator: | ||
continue | ||
|
||
# The number of filters, nuclides and scores must exactly match | ||
if exact_scores and len(scores) != test_tally.num_scores: | ||
continue | ||
if exact_nuclides and len(nuclides) != test_tally.num_nuclides: | ||
if exact_nuclides and nuclides and len(nuclides) != test_tally.num_nuclides: | ||
continue | ||
if exact_nuclides and not nuclides and test_tally.nuclides != ['total']: | ||
continue | ||
if exact_filters and len(filters) != test_tally.num_filters: | ||
continue | ||
if derivative is not None and derivative != sp_tally.derivative: | ||
continue | ||
if multiply_density is not None and multiply_density != sp_tally.multiply_density: | ||
continue | ||
|
||
# Determine if Tally has the queried score(s) | ||
if scores: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tjlaboss would say: