Skip to content

Commit c0427dd

Browse files
GuyStenpshriwise
andauthored
Resolve conflict with weight windows and global russian roulette (#3751)
Co-authored-by: Patrick Shriwise <pshriwise@gmail.com>
1 parent 5a85bd9 commit c0427dd

13 files changed

Lines changed: 748 additions & 154 deletions

File tree

include/openmc/physics_common.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,9 @@ namespace openmc {
1313
//! \param[in] weight_survive Weight assigned to particles that survive
1414
void russian_roulette(Particle& p, double weight_survive);
1515

16+
//! \brief Performs the global russian roulette operation on a particle
17+
//! \param[in,out] p Particle object
18+
void apply_russian_roulette(Particle& p);
19+
1620
} // namespace openmc
1721
#endif // OPENMC_PHYSICS_COMMON_H

include/openmc/weight_windows.h

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,6 @@ enum class WeightWindowUpdateMethod { MAGIC, FW_CADIS };
2525

2626
constexpr double DEFAULT_WEIGHT_CUTOFF {1.0e-38}; // default low weight cutoff
2727

28-
//==============================================================================
29-
// Non-member functions
30-
//==============================================================================
31-
32-
//! Apply weight windows to a particle
33-
//! \param[in] p Particle to apply weight windows to
34-
void apply_weight_windows(Particle& p);
35-
36-
//! Free memory associated with weight windows
37-
void free_memory_weight_windows();
38-
3928
//==============================================================================
4029
// Global variables
4130
//==============================================================================
@@ -137,7 +126,7 @@ class WeightWindows {
137126

138127
//! Retrieve the weight window for a particle
139128
//! \param[in] p Particle to get weight window for
140-
WeightWindow get_weight_window(const Particle& p) const;
129+
std::pair<bool, WeightWindow> get_weight_window(const Particle& p) const;
141130

142131
std::array<int, 2> bounds_size() const;
143132

@@ -236,6 +225,26 @@ class WeightWindowsGenerator {
236225
double ratio_ {5.0}; //<! ratio of lower to upper weight window bounds
237226
};
238227

228+
//==============================================================================
229+
// Non-member functions
230+
//==============================================================================
231+
232+
//! Apply weight windows to a particle
233+
//! \param[in] p Particle to apply weight windows to
234+
void apply_weight_windows(Particle& p);
235+
236+
//! Apply weight window to a particle
237+
//! \param[in] p Particle to apply weight window to
238+
//! \param[in] weight_window WeightWindow to apply
239+
void apply_weight_window(Particle& p, WeightWindow weight_window);
240+
241+
//! Free memory associated with weight windows
242+
void free_memory_weight_windows();
243+
244+
//! Search weight window that apply to a particle
245+
//! \param[in] p Particle to search weight window for
246+
std::pair<bool, WeightWindow> search_weight_window(const Particle& p);
247+
239248
//! Finalize variance reduction objects after all inputs have been read
240249
void finalize_variance_reduction();
241250

src/physics.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,17 @@ void collision(Particle& p)
6464
fatal_error("Unsupported particle PDG for collision sampling.");
6565
}
6666

67-
if (settings::weight_window_checkpoint_collision)
68-
apply_weight_windows(p);
67+
if (settings::weight_windows_on) {
68+
auto [ww_found, ww] = search_weight_window(p);
69+
if (!ww_found && p.type() == ParticleType::neutron()) {
70+
// if the weight window is not valid, apply russian roulette for neutrons
71+
// (regardless of weight window collision checkpoint setting)
72+
apply_russian_roulette(p);
73+
} else if (settings::weight_window_checkpoint_collision) {
74+
// if collision checkpointing is on, apply weight window
75+
apply_weight_window(p, ww);
76+
}
77+
}
6978

7079
// Kill particle if energy falls below cutoff
7180
int type = p.type().transport_index();
@@ -156,18 +165,9 @@ void sample_neutron_reaction(Particle& p)
156165
advance_prn_seed(data::nuclides.size(), &p.seeds(STREAM_URR_PTABLE));
157166
}
158167

159-
// Play russian roulette if survival biasing is turned on
160-
if (settings::survival_biasing) {
161-
// if survival normalization is on, use normalized weight cutoff and
162-
// normalized weight survive
163-
if (settings::survival_normalization) {
164-
if (p.wgt() < settings::weight_cutoff * p.wgt_born()) {
165-
russian_roulette(p, settings::weight_survive * p.wgt_born());
166-
}
167-
} else if (p.wgt() < settings::weight_cutoff) {
168-
russian_roulette(p, settings::weight_survive);
169-
}
170-
}
168+
// Play russian roulette if there are no weight windows
169+
if (!settings::weight_windows_on)
170+
apply_russian_roulette(p);
171171
}
172172

173173
void create_fission_sites(Particle& p, int i_nuclide, const Reaction& rx)

src/physics_common.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,20 @@ void russian_roulette(Particle& p, double weight_survive)
1818
}
1919
}
2020

21+
void apply_russian_roulette(Particle& p)
22+
{
23+
// Exit if survival biasing is turned off
24+
if (!settings::survival_biasing)
25+
return;
26+
27+
// if survival normalization is on, use normalized weight cutoff and
28+
// normalized weight survive
29+
if (settings::survival_normalization) {
30+
if (p.wgt() < settings::weight_cutoff * p.wgt_born()) {
31+
russian_roulette(p, settings::weight_survive * p.wgt_born());
32+
}
33+
} else if (p.wgt() < settings::weight_cutoff) {
34+
russian_roulette(p, settings::weight_survive);
35+
}
36+
}
2137
} // namespace openmc

src/physics_mg.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,17 @@ void collision_mg(Particle& p)
3232
// Sample the reaction type
3333
sample_reaction(p);
3434

35-
if (settings::weight_window_checkpoint_collision)
36-
apply_weight_windows(p);
35+
if (settings::weight_windows_on) {
36+
auto [ww_found, ww] = search_weight_window(p);
37+
if (!ww_found && p.type() == ParticleType::neutron()) {
38+
// if the weight window is not valid, apply russian roulette
39+
// (regardless of weight window collision checkpoint setting)
40+
apply_russian_roulette(p);
41+
} else if (settings::weight_window_checkpoint_collision) {
42+
// if collision checkpointing is on, apply weight window
43+
apply_weight_window(p, ww);
44+
}
45+
}
3746

3847
// Display information about collision
3948
if ((settings::verbosity >= 10) || p.trace()) {
@@ -67,18 +76,9 @@ void sample_reaction(Particle& p)
6776
// Sample a scattering event to determine the energy of the exiting neutron
6877
scatter(p);
6978

70-
// Play Russian roulette if survival biasing is turned on
71-
if (settings::survival_biasing) {
72-
// if survival normalization is applicable, use normalized weight cutoff and
73-
// normalized weight survive
74-
if (settings::survival_normalization) {
75-
if (p.wgt() < settings::weight_cutoff * p.wgt_born()) {
76-
russian_roulette(p, settings::weight_survive * p.wgt_born());
77-
}
78-
} else if (p.wgt() < settings::weight_cutoff) {
79-
russian_roulette(p, settings::weight_survive);
80-
}
81-
}
79+
// Play russian roulette if there are no weight windows
80+
if (!settings::weight_windows_on)
81+
apply_russian_roulette(p);
8282
}
8383

8484
void scatter(Particle& p)

src/random_ray/flat_source_domain.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ void FlatSourceDomain::output_to_vtk() const
843843
voxel_positions[z * Ny * Nx + y * Nx + x] = sample;
844844

845845
if (variance_reduction::weight_windows.size() == 1) {
846-
WeightWindow ww =
846+
auto [ww_found, ww] =
847847
variance_reduction::weight_windows[0]->get_weight_window(p);
848848
float weight = ww.lower_weight;
849849
weight_windows[z * Ny * Nx + y * Nx + x] = weight;

src/settings.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,13 @@ void read_settings_xml(pugi::xml_node root)
12661266
}
12671267
}
12681268

1269+
if (weight_windows_on) {
1270+
if (!weight_window_checkpoint_surface &&
1271+
!weight_window_checkpoint_collision)
1272+
fatal_error(
1273+
"Weight Windows are enabled but there are no valid checkpoints.");
1274+
}
1275+
12691276
if (check_for_node(root, "use_decay_photons")) {
12701277
settings::use_decay_photons =
12711278
get_node_value_bool(root, "use_decay_photons");

0 commit comments

Comments
 (0)