Skip to content

Commit 9908b59

Browse files
committed
Revert "Combing for fission site sampling, and delayed neutron emission time (openmc-dev#2992)"
This reverts commit ecb0a33.
1 parent 9363104 commit 9908b59

File tree

241 files changed

+9675
-9795
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

241 files changed

+9675
-9795
lines changed

docs/source/methods/neutron_physics.rst

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -290,10 +290,7 @@ create and store fission sites for the following generation. First, the average
290290
number of prompt and delayed neutrons must be determined to decide whether the
291291
secondary neutrons will be prompt or delayed. This is important because delayed
292292
neutrons have a markedly different spectrum from prompt neutrons, one that has a
293-
lower average energy of emission. Furthermore, in simulations where tracking
294-
time of neutrons is important, we need to consider the emission time delay of
295-
the secondary neutrons, which is dependent on the decay constant of the
296-
delayed neutron precursor. The total number of neutrons emitted
293+
lower average energy of emission. The total number of neutrons emitted
297294
:math:`\nu_t` is given as a function of incident energy in the ENDF format. Two
298295
representations exist for :math:`\nu_t`. The first is a polynomial of order
299296
:math:`N` with coefficients :math:`c_0,c_1,\dots,c_N`. If :math:`\nu_t` has this
@@ -309,8 +306,8 @@ interpolation law. The number of prompt neutrons released per fission event
309306
:math:`\nu_p` is also given as a function of incident energy and can be
310307
specified in a polynomial or tabular format. The number of delayed neutrons
311308
released per fission event :math:`\nu_d` can only be specified in a tabular
312-
format. In practice, we only need to determine :math:`\nu_t` and
313-
:math:`\nu_d`. Once these have been determined, we can calculate the delayed
309+
format. In practice, we only need to determine :math:`nu_t` and
310+
:math:`nu_d`. Once these have been determined, we can calculated the delayed
314311
neutron fraction
315312

316313
.. math::
@@ -338,14 +335,8 @@ neutrons. Otherwise, we produce :math:`\lfloor \nu \rfloor + 1` neutrons. Then,
338335
for each fission site produced, we sample the outgoing angle and energy
339336
according to the algorithms given in :ref:`sample-angle` and
340337
:ref:`sample-energy` respectively. If the neutron is to be born delayed, then
341-
there is an extra step of sampling a delayed neutron precursor group to get the
342-
associated secondary energy distribution and the decay constant
343-
:math:`\lambda`, which is needed to sample the emission delay time :math:`t_d`:
344-
345-
.. math::
346-
:label: sample-delay-time
347-
348-
t_d = -\frac{\ln \xi}{\lambda}.
338+
there is an extra step of sampling a delayed neutron precursor group since they
339+
each have an associated secondary energy distribution.
349340

350341
The sampled outgoing angle and energy of fission neutrons along with the
351342
position of the collision site are stored in an array called the fission

examples/pincell_pulsed/run_pulse.py

Lines changed: 0 additions & 101 deletions
This file was deleted.

include/openmc/settings.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,6 @@ extern double source_rejection_fraction; //!< Minimum fraction of source sites
150150

151151
extern int
152152
max_history_splits; //!< maximum number of particle splits for weight windows
153-
extern int max_secondaries; //!< maximum number of secondaries in the bank
154153
extern int64_t ssw_max_particles; //!< maximum number of particles to be
155154
//!< banked on surfaces per process
156155
extern int64_t ssw_max_files; //!< maximum number of surface source files

openmc/settings.py

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,6 @@ class Settings:
128128
Maximum number of times a particle can split during a history
129129
130130
.. versionadded:: 0.13
131-
max_secondaries : int
132-
Maximum secondary bank size
133-
134-
.. versionadded:: 0.15.3
135131
max_tracks : int
136132
Maximum number of tracks written to a track file (per MPI process).
137133
@@ -435,7 +431,6 @@ def __init__(self, **kwargs):
435431
self._weight_window_checkpoints = {}
436432
self._max_history_splits = None
437433
self._max_tracks = None
438-
self._max_secondaries = None
439434
self._use_decay_photons = None
440435

441436
self._random_ray = {}
@@ -1142,16 +1137,6 @@ def max_history_splits(self, value: int):
11421137
cv.check_greater_than('max particle splits', value, 0)
11431138
self._max_history_splits = value
11441139

1145-
@property
1146-
def max_secondaries(self) -> int:
1147-
return self._max_secondaries
1148-
1149-
@max_secondaries.setter
1150-
def max_secondaries(self, value: int):
1151-
cv.check_type('maximum secondary bank size', value, Integral)
1152-
cv.check_greater_than('max secondary bank size', value, 0)
1153-
self._max_secondaries = value
1154-
11551140
@property
11561141
def max_tracks(self) -> int:
11571142
return self._max_tracks
@@ -1688,11 +1673,6 @@ def _create_max_history_splits_subelement(self, root):
16881673
elem = ET.SubElement(root, "max_history_splits")
16891674
elem.text = str(self._max_history_splits)
16901675

1691-
def _create_max_secondaries_subelement(self, root):
1692-
if self._max_secondaries is not None:
1693-
elem = ET.SubElement(root, "max_secondaries")
1694-
elem.text = str(self._max_secondaries)
1695-
16961676
def _create_max_tracks_subelement(self, root):
16971677
if self._max_tracks is not None:
16981678
elem = ET.SubElement(root, "max_tracks")
@@ -2093,11 +2073,6 @@ def _max_history_splits_from_xml_element(self, root):
20932073
if text is not None:
20942074
self.max_history_splits = int(text)
20952075

2096-
def _max_secondaries_from_xml_element(self, root):
2097-
text = get_text(root, 'max_secondaries')
2098-
if text is not None:
2099-
self.max_secondaries = int(text)
2100-
21012076
def _max_tracks_from_xml_element(self, root):
21022077
text = get_text(root, 'max_tracks')
21032078
if text is not None:
@@ -2219,7 +2194,6 @@ def to_xml_element(self, mesh_memo=None):
22192194
self._create_weight_window_checkpoints_subelement(element)
22202195
self._create_max_history_splits_subelement(element)
22212196
self._create_max_tracks_subelement(element)
2222-
self._create_max_secondaries_subelement(element)
22232197
self._create_random_ray_subelement(element, mesh_memo)
22242198
self._create_use_decay_photons_subelement(element)
22252199
self._create_source_rejection_fraction_subelement(element)
@@ -2328,7 +2302,6 @@ def from_xml_element(cls, elem, meshes=None):
23282302
settings._weight_window_checkpoints_from_xml_element(elem)
23292303
settings._max_history_splits_from_xml_element(elem)
23302304
settings._max_tracks_from_xml_element(elem)
2331-
settings._max_secondaries_from_xml_element(elem)
23322305
settings._random_ray_from_xml_element(elem)
23332306
settings._use_decay_photons_from_xml_element(elem)
23342307
settings._source_rejection_fraction_from_xml_element(elem)

src/eigenvalue.cpp

Lines changed: 77 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,30 @@ void synchronize_bank()
127127
"No fission sites banked on MPI rank " + std::to_string(mpi::rank));
128128
}
129129

130+
// Make sure all processors start at the same point for random sampling. Then
131+
// skip ahead in the sequence using the starting index in the 'global'
132+
// fission bank for each processor.
133+
134+
int64_t id = simulation::total_gen + overall_generation();
135+
uint64_t seed = init_seed(id, STREAM_TRACKING);
136+
advance_prn_seed(start, &seed);
137+
138+
// Determine how many fission sites we need to sample from the source bank
139+
// and the probability for selecting a site.
140+
141+
int64_t sites_needed;
142+
if (total < settings::n_particles) {
143+
sites_needed = settings::n_particles % total;
144+
} else {
145+
sites_needed = settings::n_particles;
146+
}
147+
double p_sample = static_cast<double>(sites_needed) / total;
148+
130149
simulation::time_bank_sample.start();
131150

151+
// ==========================================================================
152+
// SAMPLE N_PARTICLES FROM FISSION BANK AND PLACE IN TEMP_SITES
153+
132154
// Allocate temporary source bank -- we don't really know how many fission
133155
// sites were created, so overallocate by a factor of 3
134156
int64_t index_temp = 0;
@@ -143,38 +165,33 @@ void synchronize_bank()
143165
temp_delayed_groups, temp_lifetimes, 3 * simulation::work_per_rank);
144166
}
145167

146-
// ==========================================================================
147-
// SAMPLE N_PARTICLES FROM FISSION BANK AND PLACE IN TEMP_SITES
148-
149-
// We use Uniform Combing method to exactly get the targeted particle size
150-
// [https://doi.org/10.1080/00295639.2022.2091906]
151-
152-
// Make sure all processors use the same random number seed.
153-
int64_t id = simulation::total_gen + overall_generation();
154-
uint64_t seed = init_seed(id, STREAM_TRACKING);
168+
for (int64_t i = 0; i < simulation::fission_bank.size(); i++) {
169+
const auto& site = simulation::fission_bank[i];
155170

156-
// Comb specification
157-
double teeth_distance = static_cast<double>(total) / settings::n_particles;
158-
double teeth_offset = prn(&seed) * teeth_distance;
159-
160-
// First and last hitting tooth
161-
int64_t end = start + simulation::fission_bank.size();
162-
int64_t tooth_start = std::ceil((start - teeth_offset) / teeth_distance);
163-
int64_t tooth_end = std::floor((end - teeth_offset) / teeth_distance) + 1;
164-
165-
// Locally comb particles in fission_bank
166-
double tooth = tooth_start * teeth_distance + teeth_offset;
167-
for (int64_t i = tooth_start; i < tooth_end; i++) {
168-
int64_t idx = std::floor(tooth) - start;
169-
temp_sites[index_temp] = simulation::fission_bank[idx];
170-
if (settings::ifp_on) {
171-
copy_ifp_data_from_fission_banks(
172-
idx, temp_delayed_groups[index_temp], temp_lifetimes[index_temp]);
171+
// If there are less than n_particles particles banked, automatically add
172+
// int(n_particles/total) sites to temp_sites. For example, if you need
173+
// 1000 and 300 were banked, this would add 3 source sites per banked site
174+
// and the remaining 100 would be randomly sampled.
175+
if (total < settings::n_particles) {
176+
for (int64_t j = 1; j <= settings::n_particles / total; ++j) {
177+
temp_sites[index_temp] = site;
178+
if (settings::ifp_on) {
179+
copy_ifp_data_from_fission_banks(
180+
i, temp_delayed_groups[index_temp], temp_lifetimes[index_temp]);
181+
}
182+
++index_temp;
183+
}
173184
}
174-
++index_temp;
175185

176-
// Next tooth
177-
tooth += teeth_distance;
186+
// Randomly sample sites needed
187+
if (prn(&seed) < p_sample) {
188+
temp_sites[index_temp] = site;
189+
if (settings::ifp_on) {
190+
copy_ifp_data_from_fission_banks(
191+
i, temp_delayed_groups[index_temp], temp_lifetimes[index_temp]);
192+
}
193+
++index_temp;
194+
}
178195
}
179196

180197
// At this point, the sampling of source sites is done and now we need to
@@ -200,6 +217,37 @@ void synchronize_bank()
200217
finish = index_temp;
201218
#endif
202219

220+
// Now that the sampling is complete, we need to ensure that we have exactly
221+
// n_particles source sites. The way this is done in a reproducible manner is
222+
// to adjust only the source sites on the last processor.
223+
224+
if (mpi::rank == mpi::n_procs - 1) {
225+
if (finish > settings::n_particles) {
226+
// If we have extra sites sampled, we will simply discard the extra
227+
// ones on the last processor
228+
index_temp = settings::n_particles - start;
229+
230+
} else if (finish < settings::n_particles) {
231+
// If we have too few sites, repeat sites from the very end of the
232+
// fission bank
233+
sites_needed = settings::n_particles - finish;
234+
// TODO: sites_needed > simulation::fission_bank.size() or other test to
235+
// make sure we don't need info from other proc
236+
for (int i = 0; i < sites_needed; ++i) {
237+
int i_bank = simulation::fission_bank.size() - sites_needed + i;
238+
temp_sites[index_temp] = simulation::fission_bank[i_bank];
239+
if (settings::ifp_on) {
240+
copy_ifp_data_from_fission_banks(i_bank,
241+
temp_delayed_groups[index_temp], temp_lifetimes[index_temp]);
242+
}
243+
++index_temp;
244+
}
245+
}
246+
247+
// the last processor should not be sending sites to right
248+
finish = simulation::work_index[mpi::rank + 1];
249+
}
250+
203251
simulation::time_bank_sample.stop();
204252
simulation::time_bank_sendrecv.start();
205253

src/finalize.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ int openmc_finalize()
9292
settings::max_lost_particles = 10;
9393
settings::max_order = 0;
9494
settings::max_particles_in_flight = 100000;
95-
settings::max_secondaries = 10000;
9695
settings::max_particle_events = 1'000'000;
9796
settings::max_history_splits = 10'000'000;
9897
settings::max_tracks = 1000;

0 commit comments

Comments
 (0)