Make sure all reaction names are recognized as valid tally scores

This commit is contained in:
Paul Romano 2020-08-27 10:28:11 -05:00
parent bf34c4bcad
commit 70d463d46c
3 changed files with 151 additions and 209 deletions

View file

@ -44,8 +44,18 @@ public:
// Non-member functions
//==============================================================================
//! Return reaction name given an ENDF MT value
//
//! \param[in] mt ENDF MT value
//! \return Name of the corresponding reaction
std::string reaction_name(int mt);
//! Return reaction type (MT value) given a reaction name
//
//! \param[in] name Reaction name
//! \return Corresponding reaction type (MT value)
int reaction_type(std::string name);
} // namespace openmc
#endif // OPENMC_REACTION_H

View file

@ -87,7 +87,7 @@ Reaction::Reaction(hid_t group, const std::vector<int>& temperatures)
// Non-member functions
//==============================================================================
const std::unordered_map<int, std::string> REACTION_NAME_MAP {
std::unordered_map<int, std::string> REACTION_NAME_MAP {
{SCORE_FLUX, "flux"},
{SCORE_TOTAL, "total"},
{SCORE_SCATTER, "scatter"},
@ -150,6 +150,55 @@ const std::unordered_map<int, std::string> REACTION_NAME_MAP {
{N_PD, "(n,pd)"},
{N_PT, "(n,pt)"},
{N_DA, "(n,da)"},
{N_5N, "(n,5n)"},
{N_6N, "(n,6n)"},
{N_2NT, "(n,2nt)"},
{N_TA, "(n,ta)"},
{N_4NP, "(n,4np)"},
{N_3ND, "(n,3nd)"},
{N_NDA, "(n,nda)"},
{N_2NPA, "(n,2npa)"},
{N_7N, "(n,7n)"},
{N_8N, "(n,8n)"},
{N_5NP, "(n,5np)"},
{N_6NP, "(n,6np)"},
{N_7NP, "(n,7np)"},
{N_4NA, "(n,4na)"},
{N_5NA, "(n,5na)"},
{N_6NA, "(n,6na)"},
{N_7NA, "(n,7na)"},
{N_4ND, "(n,4nd)"},
{N_5ND, "(n,5nd)"},
{N_6ND, "(n,6nd)"},
{N_3NT, "(n,3nt)"},
{N_4NT, "(n,4nt)"},
{N_5NT, "(n,5nt)"},
{N_6NT, "(n,6nt)"},
{N_2N3HE, "(n,2n3He)"},
{N_3N3HE, "(n,3n3He)"},
{N_4N3HE, "(n,4n3He)"},
{N_3N2P, "(n,3n2p)"},
{N_3N3A, "(n,3n3a)"},
{N_3NPA, "(n,3npa)"},
{N_DT, "(n,dt)"},
{N_NPD, "(n,npd)"},
{N_NPT, "(n,npt)"},
{N_NDT, "(n,ndt)"},
{N_NP3HE, "(n,np3He)"},
{N_ND3HE, "(n,nd3He)"},
{N_NT3HE, "(n,nt3He)"},
{N_NTA, "(n,nta)"},
{N_2N2P, "(n,2n2p)"},
{N_P3HE, "(n,p3He)"},
{N_D3HE, "(n,d3He)"},
{N_3HEA, "(n,3Hea)"},
{N_4N2P, "(n,4n2p)"},
{N_4N2A, "(n,4n2a)"},
{N_4NPA, "(n,4npa)"},
{N_3P, "(n,3p)"},
{N_N3P, "(n,n3p)"},
{N_3N2PA, "(n,3n2pa)"},
{N_5N2P, "(n,5n2p)"},
{201, "(n,Xn)"},
{202, "(n,Xgamma)"},
{N_XP, "(n,Xp)"},
@ -174,32 +223,98 @@ const std::unordered_map<int, std::string> REACTION_NAME_MAP {
{HEATING_LOCAL, "heating-local"},
};
std::string reaction_name(int mt)
std::unordered_map<std::string, int> REACTION_TYPE_MAP;
void initialize_maps()
{
if (N_N1 <= mt && mt <= N_N40) {
return fmt::format("(n,n{})", mt - 50);
} else if (534 <= mt && mt <= 572) {
return fmt::format("photoelectric, {} subshell", SUBSHELLS[mt - 534]);
} else if (N_P0 <= mt && mt < N_PC) {
return fmt::format("(n,p{})", mt - N_P0);
} else if (N_D0 <= mt && mt < N_DC) {
return fmt::format("(n,d{})", mt - N_D0);
} else if (N_T0 <= mt && mt < N_TC) {
return fmt::format("(n,t{})", mt - N_T0);
} else if (N_3HE0 <= mt && mt < N_3HEC) {
return fmt::format("(n,3He{})", mt - N_3HE0);
} else if (N_A0 <= mt && mt < N_AC) {
return fmt::format("(n,a{})", mt - N_A0);
} else if (N_2N0 <= mt && mt < N_2NC) {
return fmt::format("(n,2n{})", mt - N_2N0);
} else {
auto it = REACTION_NAME_MAP.find(mt);
if (it != REACTION_NAME_MAP.end()) {
return it->second;
} else {
return fmt::format("MT={}", mt);
// Add level reactions to name map
for (int level = 0; level <= 48; ++level) {
if (level >= 1 && level <= 40) {
REACTION_NAME_MAP[50 + level] = fmt::format("(n,n{})", level);
}
REACTION_NAME_MAP[600 + level] = fmt::format("(n,p{})", level);
REACTION_NAME_MAP[650 + level] = fmt::format("(n,d{})", level);
REACTION_NAME_MAP[700 + level] = fmt::format("(n,t{})", level);
REACTION_NAME_MAP[750 + level] = fmt::format("(n,3He{})", level);
REACTION_NAME_MAP[800 + level] = fmt::format("(n,a{})", level);
if (level <= 15) {
REACTION_NAME_MAP[875 + level] = fmt::format("(n,a{})", level);
}
}
// Create photoelectric subshells
for (int mt = 534; mt <= 572; ++mt) {
REACTION_NAME_MAP[mt] = fmt::format("photoelectric, {} subshell",
SUBSHELLS[mt - 534]);
}
// Invert name map to create type map
for (const auto& kv : REACTION_NAME_MAP) {
REACTION_TYPE_MAP[kv.second] = kv.first;
}
}
std::string reaction_name(int mt)
{
// Initialize remainder of name map and all of type map
if (REACTION_TYPE_MAP.empty()) initialize_maps();
// Get reaction name from map
auto it = REACTION_NAME_MAP.find(mt);
if (it != REACTION_NAME_MAP.end()) {
return it->second;
} else {
return fmt::format("MT={}", mt);
}
}
int reaction_type(std::string name)
{
// Initialize remainder of name map and all of type map
if (REACTION_TYPE_MAP.empty()) initialize_maps();
// Check if type map has an entry for this reaction name
auto it = REACTION_TYPE_MAP.find(name);
if (it != REACTION_TYPE_MAP.end()) {
return it->second;
}
// Alternate names for several reactions
if (name == "(n,total)") {
return SCORE_TOTAL;
} else if (name == "elastic") {
return ELASTIC;
} else if (name == "n2n") {
return N_2N;
} else if (name == "n3n") {
return N_3N;
} else if (name == "n4n") {
return N_4N;
} else if (name == "H1-production") {
return N_XP;
} else if (name == "H2-production") {
return N_XD;
} else if (name == "H3-production") {
return N_XT;
} else if (name == "He3-production") {
return N_X3HE;
} else if (name == "He4-production") {
return N_XA;
}
// Assume the given string is a reaction MT number. Make sure it's a natural
// number then return.
int MT = 0;
try {
MT = std::stoi(name);
} catch (const std::invalid_argument& ex) {
throw std::invalid_argument("Invalid tally score \"" + name + "\". See the docs "
"for details: https://docs.openmc.org/en/stable/usersguide/tallies.html#scores");
}
if (MT < 1)
throw std::invalid_argument("Invalid tally score \"" + name + "\". See the docs "
"for details: https://docs.openmc.org/en/stable/usersguide/tallies.html#scores");
return MT;
}
} // namespace openmc

View file

@ -65,190 +65,6 @@ double global_tally_collision;
double global_tally_tracklength;
double global_tally_leakage;
int
score_str_to_int(std::string score_str)
{
if (score_str == "flux")
return SCORE_FLUX;
if (score_str == "total" || score_str == "(n,total)")
return SCORE_TOTAL;
if (score_str == "scatter")
return SCORE_SCATTER;
if (score_str == "nu-scatter")
return SCORE_NU_SCATTER;
if (score_str == "absorption")
return SCORE_ABSORPTION;
if (score_str == "fission" || score_str == "18")
return SCORE_FISSION;
if (score_str == "nu-fission")
return SCORE_NU_FISSION;
if (score_str == "decay-rate")
return SCORE_DECAY_RATE;
if (score_str == "delayed-nu-fission")
return SCORE_DELAYED_NU_FISSION;
if (score_str == "prompt-nu-fission")
return SCORE_PROMPT_NU_FISSION;
if (score_str == "kappa-fission")
return SCORE_KAPPA_FISSION;
if (score_str == "inverse-velocity")
return SCORE_INVERSE_VELOCITY;
if (score_str == "fission-q-prompt")
return SCORE_FISS_Q_PROMPT;
if (score_str == "fission-q-recoverable")
return SCORE_FISS_Q_RECOV;
if (score_str == "heating")
return HEATING;
if (score_str == "heating-local")
return HEATING_LOCAL;
if (score_str == "current")
return SCORE_CURRENT;
if (score_str == "events")
return SCORE_EVENTS;
if (score_str == "elastic" || score_str == "(n,elastic)")
return ELASTIC;
if (score_str == "n2n" || score_str == "(n,2n)")
return N_2N;
if (score_str == "n3n" || score_str == "(n,3n)")
return N_3N;
if (score_str == "n4n" || score_str == "(n,4n)")
return N_4N;
if (score_str == "(n,2nd)")
return N_2ND;
if (score_str == "(n,na)")
return N_2NA;
if (score_str == "(n,n3a)")
return N_N3A;
if (score_str == "(n,2na)")
return N_2NA;
if (score_str == "(n,3na)")
return N_3NA;
if (score_str == "(n,np)")
return N_NP;
if (score_str == "(n,n2a)")
return N_N2A;
if (score_str == "(n,2n2a)")
return N_2N2A;
if (score_str == "(n,nd)")
return N_ND;
if (score_str == "(n,nt)")
return N_NT;
if (score_str == "(n,n3He)")
return N_N3HE;
if (score_str == "(n,nd2a)")
return N_ND2A;
if (score_str == "(n,nt2a)")
return N_NT2A;
if (score_str == "(n,3nf)")
return N_3NF;
if (score_str == "(n,2np)")
return N_2NP;
if (score_str == "(n,3np)")
return N_3NP;
if (score_str == "(n,n2p)")
return N_N2P;
if (score_str == "(n,npa)")
return N_NPA;
if (score_str == "(n,n1)")
return N_N1;
if (score_str == "(n,nc)")
return N_NC;
if (score_str == "(n,gamma)")
return N_GAMMA;
if (score_str == "(n,p)")
return N_P;
if (score_str == "(n,d)")
return N_D;
if (score_str == "(n,t)")
return N_T;
if (score_str == "(n,3He)")
return N_3HE;
if (score_str == "(n,a)")
return N_A;
if (score_str == "(n,2a)")
return N_2A;
if (score_str == "(n,3a)")
return N_3A;
if (score_str == "(n,2p)")
return N_2P;
if (score_str == "(n,pa)")
return N_PA;
if (score_str == "(n,t2a)")
return N_T2A;
if (score_str == "(n,d2a)")
return N_D2A;
if (score_str == "(n,pd)")
return N_PD;
if (score_str == "(n,pt)")
return N_PT;
if (score_str == "(n,da)")
return N_DA;
if (score_str == "(n,Xp)" || score_str == "H1-production")
return N_XP;
if (score_str == "(n,Xd)" || score_str == "H2-production")
return N_XD;
if (score_str == "(n,Xt)" || score_str == "H3-production")
return N_XT;
if (score_str == "(n,X3He)" || score_str == "He3-production")
return N_X3HE;
if (score_str == "(n,Xa)" || score_str == "He4-production")
return N_XA;
if (score_str == "damage-energy")
return DAMAGE_ENERGY;
if (score_str == "coherent-scatter")
return COHERENT;
if (score_str == "incoherent-scatter")
return INCOHERENT;
if (score_str == "pair-production")
return PAIR_PROD;
if (score_str == "photoelectric")
return PHOTOELECTRIC;
// So far we have not identified this score string. Check to see if it is a
// deprecated score.
if (score_str.rfind("scatter-", 0) == 0
|| score_str.rfind("nu-scatter-", 0) == 0
|| score_str.rfind("total-y", 0) == 0
|| score_str.rfind("flux-y", 0) == 0)
fatal_error(score_str + " is no longer an available score");
// Assume the given string is a reaction MT number. Make sure it's a natural
// number then return.
int MT;
try {
MT = std::stoi(score_str);
} catch (const std::invalid_argument& ex) {
throw std::invalid_argument("Invalid tally score \"" + score_str + "\". See the docs "
"for details: https://docs.openmc.org/en/stable/usersguide/tallies.html#scores");
}
if (MT < 1)
throw std::invalid_argument("Invalid tally score \"" + score_str + "\". See the docs "
"for details: https://docs.openmc.org/en/stable/usersguide/tallies.html#scores");
return MT;
}
//==============================================================================
// Tally object implementation
//==============================================================================
@ -594,7 +410,8 @@ Tally::set_scores(const std::vector<std::string>& scores)
fatal_error("Cannot tally " + score_str + "with a delayedgroup filter");
}
auto score = score_str_to_int(score_str);
// Determine integer code for score
int score = reaction_type(score_str);
switch (score) {
case SCORE_FLUX: