-
Notifications
You must be signed in to change notification settings - Fork 650
Expand file tree
/
Copy pathchain.cpp
More file actions
135 lines (107 loc) · 3.83 KB
/
chain.cpp
File metadata and controls
135 lines (107 loc) · 3.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//! \file chain.cpp
//! \brief Depletion chain and associated information
#include "openmc/chain.h"
#include <cstdlib> // for getenv
#include <memory> // for make_unique
#include <string> // for stod
#include <fmt/core.h>
#include <pugixml.hpp>
#include "openmc/distribution.h" // for distribution_from_xml
#include "openmc/error.h"
#include "openmc/reaction.h"
#include "openmc/xml_interface.h" // for get_node_value
namespace openmc {
//==============================================================================
// ChainNuclide implementation
//==============================================================================
ChainNuclide::ChainNuclide(pugi::xml_node node)
{
name_ = get_node_value(node, "name");
if (check_for_node(node, "half_life")) {
half_life_ = std::stod(get_node_value(node, "half_life"));
}
if (check_for_node(node, "decay_energy")) {
decay_energy_ = std::stod(get_node_value(node, "decay_energy"));
}
// Read reactions to store MT -> product map
for (pugi::xml_node reaction_node : node.children("reaction")) {
std::string rx_name = get_node_value(reaction_node, "type");
if (!reaction_node.attribute("target"))
continue;
std::string rx_target = get_node_value(reaction_node, "target");
double branching_ratio = 1.0;
if (reaction_node.attribute("branching_ratio")) {
branching_ratio =
std::stod(get_node_value(reaction_node, "branching_ratio"));
}
int mt = reaction_mt(rx_name);
reaction_products_[mt].push_back({rx_target, branching_ratio});
}
for (pugi::xml_node source_node : node.children("source")) {
auto particle = get_node_value(source_node, "particle");
if (particle == "photon") {
photon_energy_ = distribution_from_xml(source_node);
break;
}
}
// Set entry in mapping
data::chain_nuclide_map[name_] = data::chain_nuclides.size();
}
ChainNuclide::~ChainNuclide()
{
data::chain_nuclide_map.erase(name_);
}
//==============================================================================
// DecayPhotonAngleEnergy implementation
//==============================================================================
void DecayPhotonAngleEnergy::sample(
double E_in, double& E_out, double& mu, uint64_t* seed) const
{
E_out = photon_energy_->sample(seed).first;
mu = Uniform(-1., 1.).sample(seed).first;
}
double DecayPhotonAngleEnergy::sample_energy_and_pdf(double E_in, double mu,
double& E_out, uint64_t* seed, bool is_com, double awr) const
{
if (is_com)
fatal_error(
"DecayPhotonAngleEnergy distribution must be in lab coordinates");
E_out = photon_energy_->sample(seed).first;
return 0.5;
}
//==============================================================================
// Global variables
//==============================================================================
namespace data {
std::unordered_map<std::string, int> chain_nuclide_map;
vector<unique_ptr<ChainNuclide>> chain_nuclides;
} // namespace data
//==============================================================================
// Non-member functions
//==============================================================================
void read_chain_file_xml()
{
free_memory_chain();
char* chain_file_path = std::getenv("OPENMC_CHAIN_FILE");
if (!chain_file_path) {
return;
}
write_message(5, "Reading chain file: {}...", chain_file_path);
pugi::xml_document doc;
auto result = doc.load_file(chain_file_path);
if (!result) {
fatal_error(
fmt::format("Error processing chain file: {}", chain_file_path));
}
// Get root element
pugi::xml_node root = doc.document_element();
for (auto node : root.children("nuclide")) {
data::chain_nuclides.push_back(std::make_unique<ChainNuclide>(node));
}
}
void free_memory_chain()
{
data::chain_nuclides.clear();
data::chain_nuclide_map.clear();
}
} // namespace openmc