Merge pull request #1979 from paulromano/remove-all-nuclides

Remove option to specify "all" for tally nuclides
This commit is contained in:
John Tramm 2022-02-24 09:33:09 -06:00 committed by GitHub
commit 37fbf7c243
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 75 additions and 191 deletions

View file

@ -40,15 +40,15 @@ The ``<tally>`` 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
<nuclides>U-235 Pu-239 total</nuclides>
<nuclides>U235 Pu239 total</nuclides>
*Default*: total

View file

@ -104,9 +104,6 @@ public:
//! Index of each nuclide to be tallied. -1 indicates total material.
vector<int> 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

View file

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

View file

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

View file

@ -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<std::string>(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<std::string>(node, "nuclides");
this->set_nuclides(words);
}
void Tally::set_nuclides(const vector<std::string>& nuclides)

View file

@ -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);
}
}
}

View file

@ -446,7 +446,7 @@
<filters>12</filters>
<scores>total</scores>
</tally>
<tally id="34">
<tally id="30">
<filters>15</filters>
<scores>scatter</scores>
</tally>
@ -499,30 +499,6 @@
<estimator>collision</estimator>
</tally>
<tally id="29">
<filters>13</filters>
<nuclides>all</nuclides>
<scores>total</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="30">
<filters>13</filters>
<nuclides>all</nuclides>
<scores>total</scores>
<estimator>collision</estimator>
</tally>
<tally id="31">
<filters>2</filters>
<nuclides>all</nuclides>
<scores>total</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="32">
<filters>2</filters>
<nuclides>U235</nuclides>
<scores>total</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="33">
<scores>H1-production H2-production H3-production He3-production He4-production heating damage-energy</scores>
</tally>
</tallies>

View file

@ -1 +1 @@
683a82a10c4254c7e503f9c86e192070224c0d19c1817e51da7acd74b9529a475020a6cbd658644f7cd18b244cc477d1810521aa720c4fa9354cb6955bce13f6
ad28e723270c25dc46f27f1482052e381c802cb111ea8224368d4ea3d903eeaba1a3dce541957f24ec0634ed2ada6f20f97c0270c269b9bcae4b34a1b317a165

View file

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

View file

@ -2,7 +2,7 @@
<tallies>
<tally id="1">
<nuclides>all</nuclides>
<nuclides>Pu239 total</nuclides>
<scores>total absorption fission scatter</scores>
</tally>

View file

@ -2,7 +2,7 @@
<tallies>
<tally id="1">
<nuclides>all</nuclides>
<nuclides>Pu239 total</nuclides>
<scores>total absorption fission scatter</scores>
</tally>

View file

@ -2,7 +2,7 @@
<tallies>
<tally id="1">
<nuclides>all</nuclides>
<nuclides>Pu239 total</nuclides>
<scores>total absorption fission scatter</scores>
</tally>

View file

@ -2,7 +2,7 @@
<tallies>
<tally id="1">
<nuclides>all</nuclides>
<nuclides>Pu239 total</nuclides>
<scores>total absorption fission scatter</scores>
</tally>

View file

@ -2,7 +2,7 @@
<tallies>
<tally id="1">
<nuclides>all</nuclides>
<nuclides>Pu239 total</nuclides>
<scores>total absorption fission scatter</scores>
</tally>