forked from openmc-dev/openmc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreaction_product.cpp
109 lines (92 loc) · 3.18 KB
/
reaction_product.cpp
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
#include "openmc/reaction_product.h"
#include <string> // for string
#include <fmt/core.h>
#include "openmc/endf.h"
#include "openmc/error.h"
#include "openmc/hdf5_interface.h"
#include "openmc/memory.h"
#include "openmc/particle.h"
#include "openmc/random_lcg.h"
#include "openmc/secondary_correlated.h"
#include "openmc/secondary_kalbach.h"
#include "openmc/secondary_nbody.h"
#include "openmc/secondary_uncorrelated.h"
namespace openmc {
//==============================================================================
// ReactionProduct implementation
//==============================================================================
ReactionProduct::ReactionProduct(hid_t group)
{
// Read particle type
std::string temp;
read_attribute(group, "particle", temp);
particle_ = str_to_particle_type(temp);
// Read emission mode and decay rate
read_attribute(group, "emission_mode", temp);
if (temp == "prompt") {
emission_mode_ = EmissionMode::prompt;
} else if (temp == "delayed") {
emission_mode_ = EmissionMode::delayed;
} else if (temp == "total") {
emission_mode_ = EmissionMode::total;
}
// Read decay rate for delayed emission
if (emission_mode_ == EmissionMode::delayed) {
if (attribute_exists(group, "decay_rate")) {
read_attribute(group, "decay_rate", decay_rate_);
} else if (particle_ == ParticleType::neutron) {
warning(fmt::format("Decay rate doesn't exist for delayed neutron "
"emission ({}).",
object_name(group)));
}
}
// Read secondary particle yield
yield_ = read_function(group, "yield");
int n;
read_attribute(group, "n_distribution", n);
for (int i = 0; i < n; ++i) {
std::string s {"distribution_"};
s.append(std::to_string(i));
hid_t dgroup = open_group(group, s.c_str());
// Read applicability
if (n > 1) {
hid_t app = open_dataset(dgroup, "applicability");
applicability_.emplace_back(app);
close_dataset(app);
}
// Determine distribution type and read data
read_attribute(dgroup, "type", temp);
if (temp == "uncorrelated") {
distribution_.push_back(make_unique<UncorrelatedAngleEnergy>(dgroup));
} else if (temp == "correlated") {
distribution_.push_back(make_unique<CorrelatedAngleEnergy>(dgroup));
} else if (temp == "nbody") {
distribution_.push_back(make_unique<NBodyPhaseSpace>(dgroup));
} else if (temp == "kalbach-mann") {
distribution_.push_back(make_unique<KalbachMann>(dgroup));
}
close_group(dgroup);
}
}
void ReactionProduct::sample(
double E_in, double& E_out, double& mu, uint64_t* seed) const
{
auto n = applicability_.size();
if (n > 1) {
double prob = 0.0;
double c = prn(seed);
for (int i = 0; i < n; ++i) {
// Determine probability that i-th energy distribution is sampled
prob += applicability_[i](E_in);
// If i-th distribution is sampled, sample energy from the distribution
if (c <= prob) {
distribution_[i]->sample(E_in, E_out, mu, seed);
break;
}
}
} else {
// If only one distribution is present, go ahead and sample it
distribution_[0]->sample(E_in, E_out, mu, seed);
}
}
} // namespace openmc