Repository navigation
Expand file tree
/
Copy pathchain.cpp
More file actions
116 lines (92 loc) · 3.41 KB
/
Copy pathchain.cpp
File metadata and controls
116 lines (92 loc) · 3.41 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
//! \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;
}
//==============================================================================
// 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()
{
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));
}
}
} // namespace openmc