diff --git a/docs/source/io_formats/tallies.rst b/docs/source/io_formats/tallies.rst index 3cde6fc85..8594bb11c 100644 --- a/docs/source/io_formats/tallies.rst +++ b/docs/source/io_formats/tallies.rst @@ -40,15 +40,15 @@ The ```` element accepts the following sub-elements: :nuclides: If specified, the scores listed will be for particular nuclides, not the - summation of reactions from all nuclides. The format for nuclides should be - [Atomic symbol]-[Mass number], e.g. "U-235". The reaction rate for all + summation of reactions from all nuclides. Nuclides are expressed using the + GNDS naming convention, e.g. "U235" or "Am242_m1". The reaction rate for all nuclides can be obtained with "total". For example, to obtain the reaction - rates for U-235, Pu-239, and all nuclides in a material, this element should + rates for U235, Pu239, and all nuclides in a material, this element should be: .. code-block:: xml - U-235 Pu-239 total + U235 Pu239 total *Default*: total diff --git a/include/openmc/tallies/tally.h b/include/openmc/tallies/tally.h index 13b8317ee..73618a3da 100644 --- a/include/openmc/tallies/tally.h +++ b/include/openmc/tallies/tally.h @@ -104,9 +104,6 @@ public: //! Index of each nuclide to be tallied. -1 indicates total material. vector nuclides_ {-1}; - //! True if this tally has a bin for every nuclide in the problem - bool all_nuclides_ {false}; - //! Results for each bin -- the first dimension of the array is for the //! combination of filters (e.g. specific cell, specific energy group, etc.) //! and the second dimension of the array is for scores (e.g. flux, total diff --git a/openmc/mgxs/mdgxs.py b/openmc/mgxs/mdgxs.py index 7a139c7f8..13aa924a1 100644 --- a/openmc/mgxs/mdgxs.py +++ b/openmc/mgxs/mdgxs.py @@ -110,7 +110,7 @@ class MDGXS(MGXS): being tracked. This is unity if the by_nuclide attribute is False. nuclides : Iterable of str or 'sum' The optional user-specified nuclides for which to compute cross - sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + sections (e.g., 'U238', 'O16'). If by_nuclide is True but nuclides are not specified by the user, all nuclides in the spatial domain are included. This attribute is 'sum' if by_nuclide is false. sparse : bool @@ -303,7 +303,7 @@ class MDGXS(MGXS): subdomains : Iterable of Integral or 'all' Subdomain IDs of interest. Defaults to 'all'. nuclides : Iterable of str or 'all' or 'sum' - A list of nuclide name strings (e.g., ['U-235', 'U-238']). The + A list of nuclide name strings (e.g., ['U235', 'U238']). The special string 'all' will return the cross sections for all nuclides in the spatial domain. The special string 'sum' will return the cross section summed over all nuclides. Defaults to 'all'. @@ -453,7 +453,7 @@ class MDGXS(MGXS): ---------- nuclides : list of str A list of nuclide name strings - (e.g., ['U-235', 'U-238']; default is []) + (e.g., ['U235', 'U238']; default is []) groups : list of int A list of energy group indices starting at 1 for the high energies (e.g., [1, 2, 3]; default is []) @@ -565,7 +565,7 @@ class MDGXS(MGXS): Defaults to 'all'. nuclides : Iterable of str or 'all' or 'sum' The nuclides of the cross-sections to include in the report. This - may be a list of nuclide name strings (e.g., ['U-235', 'U-238']). + may be a list of nuclide name strings (e.g., ['U235', 'U238']). The special string 'all' will report the cross sections for all nuclides in the spatial domain. The special string 'sum' will report the cross sections summed over all nuclides. Defaults to 'all'. @@ -782,7 +782,7 @@ class MDGXS(MGXS): Energy groups of interest. Defaults to 'all'. nuclides : Iterable of str or 'all' or 'sum' The nuclides of the cross-sections to include in the dataframe. This - may be a list of nuclide name strings (e.g., ['U-235', 'U-238']). + may be a list of nuclide name strings (e.g., ['U235', 'U238']). The special string 'all' will include the cross sections for all nuclides in the spatial domain. The special string 'sum' will include the cross sections summed over all nuclides. Defaults @@ -990,7 +990,7 @@ class ChiDelayed(MDGXS): being tracked. This is unity if the by_nuclide attribute is False. nuclides : Iterable of str or 'sum' The optional user-specified nuclides for which to compute cross - sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + sections (e.g., 'U238', 'O16'). If by_nuclide is True but nuclides are not specified by the user, all nuclides in the spatial domain are included. This attribute is 'sum' if by_nuclide is false. sparse : bool @@ -1006,8 +1006,8 @@ class ChiDelayed(MDGXS): """ # Store whether or not the number density should be removed for microscopic - # values of this data; since this chi data is normalized to 1.0, the - # data should not be divided by the number density + # values of this data; since this chi data is normalized to 1.0, the + # data should not be divided by the number density _divide_by_density = False def __init__(self, domain=None, domain_type=None, energy_groups=None, @@ -1107,7 +1107,7 @@ class ChiDelayed(MDGXS): ---------- nuclides : list of str A list of nuclide name strings - (e.g., ['U-235', 'U-238']; default is []) + (e.g., ['U235', 'U238']; default is []) groups : list of Integral A list of energy group indices starting at 1 for the high energies (e.g., [1, 2, 3]; default is []) @@ -1241,7 +1241,7 @@ class ChiDelayed(MDGXS): subdomains : Iterable of Integral or 'all' Subdomain IDs of interest. Defaults to 'all'. nuclides : Iterable of str or 'all' or 'sum' - A list of nuclide name strings (e.g., ['U-235', 'U-238']). The + A list of nuclide name strings (e.g., ['U235', 'U238']). The special string 'all' will return the cross sections for all nuclides in the spatial domain. The special string 'sum' will return the cross section summed over all nuclides. Defaults to 'all'. @@ -1506,7 +1506,7 @@ class DelayedNuFissionXS(MDGXS): being tracked. This is unity if the by_nuclide attribute is False. nuclides : Iterable of str or 'sum' The optional user-specified nuclides for which to compute cross - sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + sections (e.g., 'U238', 'O16'). If by_nuclide is True but nuclides are not specified by the user, all nuclides in the spatial domain are included. This attribute is 'sum' if by_nuclide is false. sparse : bool @@ -1642,7 +1642,7 @@ class Beta(MDGXS): being tracked. This is unity if the by_nuclide attribute is False. nuclides : Iterable of str or 'sum' The optional user-specified nuclides for which to compute cross - sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + sections (e.g., 'U238', 'O16'). If by_nuclide is True but nuclides are not specified by the user, all nuclides in the spatial domain are included. This attribute is 'sum' if by_nuclide is false. sparse : bool @@ -1832,7 +1832,7 @@ class DecayRate(MDGXS): being tracked. This is unity if the by_nuclide attribute is False. nuclides : Iterable of str or 'sum' The optional user-specified nuclides for which to compute cross - sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + sections (e.g., 'U238', 'O16'). If by_nuclide is True but nuclides are not specified by the user, all nuclides in the spatial domain are included. This attribute is 'sum' if by_nuclide is false. sparse : bool @@ -1935,7 +1935,7 @@ class DecayRate(MDGXS): subdomains : Iterable of Integral or 'all' Subdomain IDs of interest. Defaults to 'all'. nuclides : Iterable of str or 'all' or 'sum' - A list of nuclide name strings (e.g., ['U-235', 'U-238']). The + A list of nuclide name strings (e.g., ['U235', 'U238']). The special string 'all' will return the cross sections for all nuclides in the spatial domain. The special string 'sum' will return the cross section summed over all nuclides. Defaults to 'all'. @@ -2738,7 +2738,7 @@ class DelayedNuFissionMatrixXS(MatrixMDGXS): being tracked. This is unity if the by_nuclide attribute is False. nuclides : Iterable of str or 'sum' The optional user-specified nuclides for which to compute cross - sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + sections (e.g., 'U238', 'O16'). If by_nuclide is True but nuclides are not specified by the user, all nuclides in the spatial domain are included. This attribute is 'sum' if by_nuclide is false. sparse : bool diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index ff739fe85..fe8883135 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -6455,7 +6455,7 @@ class InverseVelocity(MGXS): being tracked. This is unity if the by_nuclide attribute is False. nuclides : Iterable of str or 'sum' The optional user-specified nuclides for which to compute cross - sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + sections (e.g., 'U238', 'O16'). If by_nuclide is True but nuclides are not specified by the user, all nuclides in the spatial domain are included. This attribute is 'sum' if by_nuclide is false. sparse : bool diff --git a/src/tallies/tally.cpp b/src/tallies/tally.cpp index 2d673d7bc..c0fedd973 100644 --- a/src/tallies/tally.cpp +++ b/src/tallies/tally.cpp @@ -542,22 +542,10 @@ void Tally::set_nuclides(pugi::xml_node node) return; } - if (get_node_value(node, "nuclides") == "all") { - // This tally should bin every nuclide in the problem. It should also bin - // the total material rates. To achieve this, set the nuclides_ vector to - // 0, 1, 2, ..., -1. - nuclides_.reserve(data::nuclides.size() + 1); - for (auto i = 0; i < data::nuclides.size(); ++i) - nuclides_.push_back(i); - nuclides_.push_back(-1); - all_nuclides_ = true; - - } else { - // The user provided specifics nuclides. Parse it as an array with either - // "total" or a nuclide name like "U-235" in each position. - auto words = get_node_array(node, "nuclides"); - this->set_nuclides(words); - } + // The user provided specifics nuclides. Parse it as an array with either + // "total" or a nuclide name like "U235" in each position. + auto words = get_node_array(node, "nuclides"); + this->set_nuclides(words); } void Tally::set_nuclides(const vector& nuclides) diff --git a/src/tallies/tally_scoring.cpp b/src/tallies/tally_scoring.cpp index b06570b99..e3104f59a 100644 --- a/src/tallies/tally_scoring.cpp +++ b/src/tallies/tally_scoring.cpp @@ -2095,43 +2095,6 @@ void score_general_mg(Particle& p, int i_tally, int start_index, } } -//! Tally rates for when the user requests a tally on all nuclides. - -void score_all_nuclides( - Particle& p, int i_tally, double flux, int filter_index, double filter_weight) -{ - const Tally& tally {*model::tallies[i_tally]}; - const Material& material {*model::materials[p.material()]}; - - // Score all individual nuclide reaction rates. - for (auto i = 0; i < material.nuclide_.size(); ++i) { - auto i_nuclide = material.nuclide_[i]; - auto atom_density = material.atom_density_(i); - - // TODO: consider replacing this "if" with pointers or templates - if (settings::run_CE) { - score_general_ce(p, i_tally, i_nuclide * tally.scores_.size(), - filter_index, filter_weight, i_nuclide, atom_density, flux); - } else { - score_general_mg(p, i_tally, i_nuclide * tally.scores_.size(), - filter_index, filter_weight, i_nuclide, atom_density, flux); - } - } - - // Score total material reaction rates. - int i_nuclide = -1; - double atom_density = 0.; - auto n_nuclides = data::nuclides.size(); - // TODO: consider replacing this "if" with pointers or templates - if (settings::run_CE) { - score_general_ce(p, i_tally, n_nuclides * tally.scores_.size(), - filter_index, filter_weight, i_nuclide, atom_density, flux); - } else { - score_general_mg(p, i_tally, n_nuclides * tally.scores_.size(), - filter_index, filter_weight, i_nuclide, atom_density, flux); - } -} - void score_analog_tally_ce(Particle& p) { // Since electrons/positrons are not transported, we assign a flux of zero. @@ -2159,30 +2122,15 @@ void score_analog_tally_ce(Particle& p) auto filter_weight = filter_iter.weight_; // Loop over nuclide bins. - if (!tally.all_nuclides_) { - for (auto i = 0; i < tally.nuclides_.size(); ++i) { - auto i_nuclide = tally.nuclides_[i]; + for (auto i = 0; i < tally.nuclides_.size(); ++i) { + auto i_nuclide = tally.nuclides_[i]; - // Tally this event in the present nuclide bin if that bin represents - // the event nuclide or the total material. Note that the atomic - // density argument for score_general is not used for analog tallies. - if (i_nuclide == p.event_nuclide() || i_nuclide == -1) - score_general_ce(p, i_tally, i * tally.scores_.size(), filter_index, - filter_weight, i_nuclide, -1.0, flux); - } - - } else { - // In the case that the user has requested to tally all nuclides, we - // can take advantage of the fact that we know exactly how nuclide - // bins correspond to nuclide indices. First, tally the nuclide. - auto i = p.event_nuclide(); - score_general_ce(p, i_tally, i * tally.scores_.size(), filter_index, - filter_weight, -1, -1.0, flux); - - // Now tally the total material. - i = tally.nuclides_.size(); - score_general_ce(p, i_tally, i * tally.scores_.size(), filter_index, - filter_weight, -1, -1.0, flux); + // Tally this event in the present nuclide bin if that bin represents + // the event nuclide or the total material. Note that the atomic + // density argument for score_general is not used for analog tallies. + if (i_nuclide == p.event_nuclide() || i_nuclide == -1) + score_general_ce(p, i_tally, i * tally.scores_.size(), filter_index, + filter_weight, i_nuclide, -1.0, flux); } } @@ -2270,34 +2218,27 @@ void score_tracklength_tally(Particle& p, double distance) auto filter_weight = filter_iter.weight_; // Loop over nuclide bins. - if (tally.all_nuclides_) { - if (p.material() != MATERIAL_VOID) - score_all_nuclides( - p, i_tally, flux * filter_weight, filter_index, filter_weight); + for (auto i = 0; i < tally.nuclides_.size(); ++i) { + auto i_nuclide = tally.nuclides_[i]; - } else { - for (auto i = 0; i < tally.nuclides_.size(); ++i) { - auto i_nuclide = tally.nuclides_[i]; - - double atom_density = 0.; - if (i_nuclide >= 0) { - if (p.material() != MATERIAL_VOID) { - auto j = - model::materials[p.material()]->mat_nuclide_index_[i_nuclide]; - if (j == C_NONE) - continue; - atom_density = model::materials[p.material()]->atom_density_(j); - } + double atom_density = 0.; + if (i_nuclide >= 0) { + if (p.material() != MATERIAL_VOID) { + auto j = + model::materials[p.material()]->mat_nuclide_index_[i_nuclide]; + if (j == C_NONE) + continue; + atom_density = model::materials[p.material()]->atom_density_(j); } + } - // TODO: consider replacing this "if" with pointers or templates - if (settings::run_CE) { - score_general_ce(p, i_tally, i * tally.scores_.size(), filter_index, - filter_weight, i_nuclide, atom_density, flux); - } else { - score_general_mg(p, i_tally, i * tally.scores_.size(), filter_index, - filter_weight, i_nuclide, atom_density, flux); - } + // TODO: consider replacing this "if" with pointers or templates + if (settings::run_CE) { + score_general_ce(p, i_tally, i * tally.scores_.size(), filter_index, + filter_weight, i_nuclide, atom_density, flux); + } else { + score_general_mg(p, i_tally, i * tally.scores_.size(), filter_index, + filter_weight, i_nuclide, atom_density, flux); } } } @@ -2340,31 +2281,25 @@ void score_collision_tally(Particle& p) auto filter_weight = filter_iter.weight_; // Loop over nuclide bins. - if (tally.all_nuclides_) { - score_all_nuclides( - p, i_tally, flux * filter_weight, filter_index, filter_weight); + for (auto i = 0; i < tally.nuclides_.size(); ++i) { + auto i_nuclide = tally.nuclides_[i]; - } else { - for (auto i = 0; i < tally.nuclides_.size(); ++i) { - auto i_nuclide = tally.nuclides_[i]; + double atom_density = 0.; + if (i_nuclide >= 0) { + auto j = + model::materials[p.material()]->mat_nuclide_index_[i_nuclide]; + if (j == C_NONE) + continue; + atom_density = model::materials[p.material()]->atom_density_(j); + } - double atom_density = 0.; - if (i_nuclide >= 0) { - auto j = - model::materials[p.material()]->mat_nuclide_index_[i_nuclide]; - if (j == C_NONE) - continue; - atom_density = model::materials[p.material()]->atom_density_(j); - } - - // TODO: consider replacing this "if" with pointers or templates - if (settings::run_CE) { - score_general_ce(p, i_tally, i * tally.scores_.size(), filter_index, - filter_weight, i_nuclide, atom_density, flux); - } else { - score_general_mg(p, i_tally, i * tally.scores_.size(), filter_index, - filter_weight, i_nuclide, atom_density, flux); - } + // TODO: consider replacing this "if" with pointers or templates + if (settings::run_CE) { + score_general_ce(p, i_tally, i * tally.scores_.size(), filter_index, + filter_weight, i_nuclide, atom_density, flux); + } else { + score_general_mg(p, i_tally, i * tally.scores_.size(), filter_index, + filter_weight, i_nuclide, atom_density, flux); } } } diff --git a/tests/regression_tests/tallies/inputs_true.dat b/tests/regression_tests/tallies/inputs_true.dat index bc9efe97e..61daba0d4 100644 --- a/tests/regression_tests/tallies/inputs_true.dat +++ b/tests/regression_tests/tallies/inputs_true.dat @@ -446,7 +446,7 @@ 12 total - + 15 scatter @@ -499,30 +499,6 @@ collision - 13 - all - total - tracklength - - - 13 - all - total - collision - - - 2 - all - total - tracklength - - - 2 - U235 - total - tracklength - - H1-production H2-production H3-production He3-production He4-production heating damage-energy diff --git a/tests/regression_tests/tallies/results_true.dat b/tests/regression_tests/tallies/results_true.dat index 6ff900331..6739f5348 100644 --- a/tests/regression_tests/tallies/results_true.dat +++ b/tests/regression_tests/tallies/results_true.dat @@ -1 +1 @@ -683a82a10c4254c7e503f9c86e192070224c0d19c1817e51da7acd74b9529a475020a6cbd658644f7cd18b244cc477d1810521aa720c4fa9354cb6955bce13f6 \ No newline at end of file +ad28e723270c25dc46f27f1482052e381c802cb111ea8224368d4ea3d903eeaba1a3dce541957f24ec0634ed2ada6f20f97c0270c269b9bcae4b34a1b317a165 \ No newline at end of file diff --git a/tests/regression_tests/tallies/test.py b/tests/regression_tests/tallies/test.py index 7746a4e24..3e1c6e7ba 100644 --- a/tests/regression_tests/tallies/test.py +++ b/tests/regression_tests/tallies/test.py @@ -154,17 +154,6 @@ def test_tallies(): flux_tallies[1].estimator = 'analog' flux_tallies[2].estimator = 'collision' - all_nuclide_tallies = [Tally() for i in range(4)] - for t in all_nuclide_tallies: - t.filters = [cell_filter] - t.estimator = 'tracklength' - t.nuclides = ['all'] - t.scores = ['total'] - all_nuclide_tallies[1].estimator = 'collision' - all_nuclide_tallies[2].filters = [mesh_filter] - all_nuclide_tallies[3].filters = [mesh_filter] - all_nuclide_tallies[3].nuclides = ['U235'] - fusion_tally = Tally() fusion_tally.scores = ['H1-production', 'H2-production', 'H3-production', 'He3-production', 'He4-production', 'heating', 'damage-energy'] @@ -180,11 +169,10 @@ def test_tallies(): cellborn_tally, dg_tally, energy_tally, energyout_tally, transfer_tally, material_tally, mu_tally1, mu_tally2, polar_tally1, polar_tally2, polar_tally3, legendre_tally, - harmonics_tally, harmonics_tally2, harmonics_tally3, + harmonics_tally, harmonics_tally2, harmonics_tally3, universe_tally, collision_tally] model.tallies += score_tallies model.tallies += flux_tallies - model.tallies += all_nuclide_tallies model.tallies.append(fusion_tally) harness.main() diff --git a/tests/regression_tests/tally_nuclides/tallies.xml b/tests/regression_tests/tally_nuclides/tallies.xml index 3440dbf21..ea25596a4 100644 --- a/tests/regression_tests/tally_nuclides/tallies.xml +++ b/tests/regression_tests/tally_nuclides/tallies.xml @@ -2,7 +2,7 @@ - all + Pu239 total total absorption fission scatter diff --git a/tests/regression_tests/trigger_batch_interval/tallies.xml b/tests/regression_tests/trigger_batch_interval/tallies.xml index 3440dbf21..ea25596a4 100644 --- a/tests/regression_tests/trigger_batch_interval/tallies.xml +++ b/tests/regression_tests/trigger_batch_interval/tallies.xml @@ -2,7 +2,7 @@ - all + Pu239 total total absorption fission scatter diff --git a/tests/regression_tests/trigger_no_batch_interval/tallies.xml b/tests/regression_tests/trigger_no_batch_interval/tallies.xml index 3440dbf21..ea25596a4 100644 --- a/tests/regression_tests/trigger_no_batch_interval/tallies.xml +++ b/tests/regression_tests/trigger_no_batch_interval/tallies.xml @@ -2,7 +2,7 @@ - all + Pu239 total total absorption fission scatter diff --git a/tests/regression_tests/trigger_no_status/tallies.xml b/tests/regression_tests/trigger_no_status/tallies.xml index 3440dbf21..ea25596a4 100644 --- a/tests/regression_tests/trigger_no_status/tallies.xml +++ b/tests/regression_tests/trigger_no_status/tallies.xml @@ -2,7 +2,7 @@ - all + Pu239 total total absorption fission scatter diff --git a/tests/regression_tests/trigger_tallies/tallies.xml b/tests/regression_tests/trigger_tallies/tallies.xml index 0d66e1538..ffe8a1a9e 100644 --- a/tests/regression_tests/trigger_tallies/tallies.xml +++ b/tests/regression_tests/trigger_tallies/tallies.xml @@ -2,7 +2,7 @@ - all + Pu239 total total absorption fission scatter