diff --git a/openmc/arithmetic.py b/openmc/arithmetic.py index bbb303b14..4ddf3b1f9 100644 --- a/openmc/arithmetic.py +++ b/openmc/arithmetic.py @@ -797,7 +797,7 @@ class AggregateFilter(object): @bins.setter def bins(self, bins): cv.check_iterable_type('bins', bins, Iterable) - self._bins = map(tuple, bins) + self._bins = list(map(tuple, bins)) @aggregate_op.setter def aggregate_op(self, aggregate_op): diff --git a/tests/test_tally_slice_merge/inputs_true.dat b/tests/test_tally_slice_merge/inputs_true.dat new file mode 100644 index 000000000..29f0f1d82 --- /dev/null +++ b/tests/test_tally_slice_merge/inputs_true.dat @@ -0,0 +1 @@ +8d1ab9e4add51b99045e990ac9c3dad9447e9720d811bc430d4bfdd7c2c035424bcb7750e4a4d0ec0460ea1ef4be46ac58372ed01d55f5d8cfeebbce75559066 \ No newline at end of file diff --git a/tests/test_tally_slice_merge/results_true.dat b/tests/test_tally_slice_merge/results_true.dat new file mode 100644 index 000000000..6aeb5735a --- /dev/null +++ b/tests/test_tally_slice_merge/results_true.dat @@ -0,0 +1,49 @@ + energy [MeV] cell nuclide score mean std. dev. +0 (0.0e+00 - 6.3e-07) 21 U-235 fission 0.098638 0.009195 energy [MeV] cell nuclide score mean std. dev. +0 (0.0e+00 - 6.3e-07) 21 U-235 nu-fission 0.240351 0.022405 energy [MeV] cell nuclide score mean std. dev. +0 (0.0e+00 - 6.3e-07) 21 U-238 fission 1.371663e-07 1.284884e-08 energy [MeV] cell nuclide score mean std. dev. +0 (0.0e+00 - 6.3e-07) 21 U-238 nu-fission 3.418304e-07 3.202044e-08 energy [MeV] cell nuclide score mean std. dev. +0 (6.3e-07 - 2.0e+01) 21 U-235 fission 0.027879 0.000602 energy [MeV] cell nuclide score mean std. dev. +0 (6.3e-07 - 2.0e+01) 21 U-235 nu-fission 0.068241 0.001458 energy [MeV] cell nuclide score mean std. dev. +0 (6.3e-07 - 2.0e+01) 21 U-238 fission 0.016638 0.001146 energy [MeV] cell nuclide score mean std. dev. +0 (6.3e-07 - 2.0e+01) 21 U-238 nu-fission 0.045776 0.003342 energy [MeV] cell nuclide score mean std. dev. +0 (0.0e+00 - 6.3e-07) 27 U-235 fission 0.057752 0.004818 energy [MeV] cell nuclide score mean std. dev. +0 (0.0e+00 - 6.3e-07) 27 U-235 nu-fission 0.140724 0.011739 energy [MeV] cell nuclide score mean std. dev. +0 (0.0e+00 - 6.3e-07) 27 U-238 fission 8.177167e-08 7.061683e-09 energy [MeV] cell nuclide score mean std. dev. +0 (0.0e+00 - 6.3e-07) 27 U-238 nu-fission 2.037822e-07 1.759834e-08 energy [MeV] cell nuclide score mean std. dev. +0 (6.3e-07 - 2.0e+01) 27 U-235 fission 0.01763 0.001937 energy [MeV] cell nuclide score mean std. dev. +0 (6.3e-07 - 2.0e+01) 27 U-235 nu-fission 0.04314 0.004737 energy [MeV] cell nuclide score mean std. dev. +0 (6.3e-07 - 2.0e+01) 27 U-238 fission 0.009883 0.001934 energy [MeV] cell nuclide score mean std. dev. +0 (6.3e-07 - 2.0e+01) 27 U-238 nu-fission 0.027068 0.005207 energy [MeV] cell nuclide score mean std. dev. +0 (0.0e+00 - 6.3e-07) 21 U-235 fission 9.863775e-02 9.194846e-03 +1 (0.0e+00 - 6.3e-07) 21 U-235 nu-fission 2.403506e-01 2.240508e-02 +2 (0.0e+00 - 6.3e-07) 21 U-238 fission 1.371663e-07 1.284884e-08 +3 (0.0e+00 - 6.3e-07) 21 U-238 nu-fission 3.418304e-07 3.202044e-08 +4 (0.0e+00 - 6.3e-07) 27 U-235 fission 5.775195e-02 4.817512e-03 +5 (0.0e+00 - 6.3e-07) 27 U-235 nu-fission 1.407242e-01 1.173883e-02 +6 (0.0e+00 - 6.3e-07) 27 U-238 fission 8.177167e-08 7.061683e-09 +7 (0.0e+00 - 6.3e-07) 27 U-238 nu-fission 2.037822e-07 1.759834e-08 +8 (6.3e-07 - 2.0e+01) 21 U-235 fission 2.787911e-02 6.020399e-04 +9 (6.3e-07 - 2.0e+01) 21 U-235 nu-fission 6.824140e-02 1.457590e-03 +10 (6.3e-07 - 2.0e+01) 21 U-238 fission 1.663756e-02 1.145703e-03 +11 (6.3e-07 - 2.0e+01) 21 U-238 nu-fission 4.577562e-02 3.342394e-03 +12 (6.3e-07 - 2.0e+01) 27 U-235 fission 1.763014e-02 1.937151e-03 +13 (6.3e-07 - 2.0e+01) 27 U-235 nu-fission 4.313951e-02 4.737423e-03 +14 (6.3e-07 - 2.0e+01) 27 U-238 fission 9.883451e-03 1.933519e-03 +15 (6.3e-07 - 2.0e+01) 27 U-238 nu-fission 2.706776e-02 5.206818e-03 sum(distribcell) energy [MeV] nuclide score mean std. dev. +0 (0, 100, 2000, 30000) (0.0e+00 - 6.3e-07) U-235 fission 0 0 +1 (0, 100, 2000, 30000) (0.0e+00 - 6.3e-07) U-235 nu-fission 0 0 +2 (0, 100, 2000, 30000) (0.0e+00 - 6.3e-07) U-238 fission 0 0 +3 (0, 100, 2000, 30000) (0.0e+00 - 6.3e-07) U-238 nu-fission 0 0 +4 (0, 100, 2000, 30000) (6.3e-07 - 2.0e+01) U-235 fission 0 0 +5 (0, 100, 2000, 30000) (6.3e-07 - 2.0e+01) U-235 nu-fission 0 0 +6 (0, 100, 2000, 30000) (6.3e-07 - 2.0e+01) U-238 fission 0 0 +7 (0, 100, 2000, 30000) (6.3e-07 - 2.0e+01) U-238 nu-fission 0 0 +8 (500, 5000, 50000) (0.0e+00 - 6.3e-07) U-235 fission 0 0 +9 (500, 5000, 50000) (0.0e+00 - 6.3e-07) U-235 nu-fission 0 0 +10 (500, 5000, 50000) (0.0e+00 - 6.3e-07) U-238 fission 0 0 +11 (500, 5000, 50000) (0.0e+00 - 6.3e-07) U-238 nu-fission 0 0 +12 (500, 5000, 50000) (6.3e-07 - 2.0e+01) U-235 fission 0 0 +13 (500, 5000, 50000) (6.3e-07 - 2.0e+01) U-235 nu-fission 0 0 +14 (500, 5000, 50000) (6.3e-07 - 2.0e+01) U-238 fission 0 0 +15 (500, 5000, 50000) (6.3e-07 - 2.0e+01) U-238 nu-fission 0 0 \ No newline at end of file diff --git a/tests/test_tally_slice_merge/test_tally_slice_merge.py b/tests/test_tally_slice_merge/test_tally_slice_merge.py new file mode 100644 index 000000000..403f1827d --- /dev/null +++ b/tests/test_tally_slice_merge/test_tally_slice_merge.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python + +import os +import sys +import glob +import hashlib +import itertools +sys.path.insert(0, os.pardir) +from testing_harness import PyAPITestHarness +import openmc + + +class TallySliceMergeTestHarness(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() + + # Define nuclides and scores to add to both tallies + self.nuclides = ['U-235', 'U-238'] + self.scores = ['fission', 'nu-fission'] + + # Define filters for energy and spatial domain + + low_energy = openmc.Filter(type='energy', bins=[0., 0.625e-6]) + high_energy = openmc.Filter(type='energy', bins=[0.625e-6, 20.]) + merged_energies = low_energy.merge(high_energy) + + cell_21 = openmc.Filter(type='cell', bins=[21]) + cell_27 = openmc.Filter(type='cell', bins=[27]) + distribcell_filter = openmc.Filter(type='distribcell', bins=[21]) + + self.cell_filters = [cell_21, cell_27] + self.energy_filters = [low_energy, high_energy] + + # Initialize cell tallies with filters, nuclides and scores + tallies = [] + for cell_filter in self.energy_filters: + for energy_filter in self.cell_filters: + for nuclide in self.nuclides: + for score in self.scores: + tally = openmc.Tally() + tally.estimator = 'tracklength' + tally.add_score(score) + tally.add_nuclide(nuclide) + tally.add_filter(cell_filter) + tally.add_filter(energy_filter) + tallies.append(tally) + + # Merge all cell tallies together + while len(tallies) != 1: + halfway = int(len(tallies) / 2) + zip_split = zip(tallies[:halfway], tallies[halfway:]) + tallies = list(map(lambda xy: xy[0].merge(xy[1]), zip_split)) + + # Specify a name for the tally + tallies[0].name = 'cell tally' + + # Initialize a distribcell tally + distribcell_tally = openmc.Tally(name='distribcell tally') + distribcell_tally.estimator = 'tracklength' + distribcell_tally.add_filter(distribcell_filter) + distribcell_tally.add_filter(merged_energies) + for score in self.scores: + distribcell_tally.add_score(score) + for nuclide in self.nuclides: + distribcell_tally.add_nuclide(nuclide) + + # Add tallies to a TalliesFile + tallies_file = openmc.TalliesFile() + tallies_file.add_tally(tallies[0]) + tallies_file.add_tally(distribcell_tally) + + # Export tallies to file + self._input_set.tallies = tallies_file + super(TallySliceMergeTestHarness, self)._build_inputs() + + def _get_results(self, hash_output=False): + """Digest info in the statepoint and return as a string.""" + + # Read the statepoint file. + statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] + sp = openmc.StatePoint(statepoint) + + # Read the summary file. + summary = glob.glob(os.path.join(os.getcwd(), 'summary.h5'))[0] + su = openmc.Summary(summary) + sp.link_with_summary(su) + + # Extract the cell tally + tallies = [sp.get_tally(name='cell tally')] + + # Slice the tallies by cell filter bins + cell_filter_prod = itertools.product(tallies, self.cell_filters) + tallies = map(lambda tf: tf[0].get_slice(filters=[tf[1].type], + filter_bins=[tf[1].get_bin(0)]), cell_filter_prod) + + # Slice the tallies by energy filter bins + energy_filter_prod = itertools.product(tallies, self.energy_filters) + tallies = map(lambda tf: tf[0].get_slice(filters=[tf[1].type], + filter_bins=[(tf[1].get_bin(0),)]), energy_filter_prod) + + # Slice the tallies by nuclide + nuclide_prod = itertools.product(tallies, self.nuclides) + tallies = map(lambda tn: tn[0].get_slice(nuclides=[tn[1]]), nuclide_prod) + + # Slice the tallies by score + score_prod = itertools.product(tallies, self.scores) + tallies = map(lambda ts: ts[0].get_slice(scores=[ts[1]]), score_prod) + + # Initialize an output string + outstr = '' + + # Append sliced Tally Pandas DataFrames to output string + for tally in tallies: + df = tally.get_pandas_dataframe() + outstr += df.to_string() + + # Merge all tallies together + while len(list(tallies)) != 1: + tallies = list(tallies) + halfway = int(len(tallies) / 2) + zip_split = zip(tallies[:halfway], tallies[halfway:]) + tallies = map(lambda xy: xy[0].merge(xy[1]), zip_split) + + # Append merged Tally Pandas DataFrame to output string + df = tallies[0].get_pandas_dataframe() + outstr += df.to_string() + + # Extract the distribcell tally + distribcell_tally = sp.get_tally(name='distribcell tally') + + # Sum up a few subdomains from the distribcell tally + sum1 = distribcell_tally.summation(filter_type='distribcell', + filter_bins=[0,100,2000,30000]) + # Sum up a few subdomains from the distribcell tally + sum2 = distribcell_tally.summation(filter_type='distribcell', + filter_bins=[500,5000,50000]) + + # Merge the distribcell tally slices + merge_tally = sum1.merge(sum2) + + # Append merged Tally Pandas DataFrame to output string + df = merge_tally.get_pandas_dataframe() + outstr += df.to_string() + + # Hash the results if necessary + if hash_output: + sha512 = hashlib.sha512() + sha512.update(outstr.encode('utf-8')) + outstr = sha512.hexdigest() + + return outstr + + def _cleanup(self): + super(TallySliceMergeTestHarness, self)._cleanup() + f = os.path.join(os.getcwd(), 'tallies.xml') + if os.path.exists(f): os.remove(f) + +if __name__ == '__main__': + harness = TallySliceMergeTestHarness('statepoint.10.h5', True) + harness.main()