• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

openmc-dev / openmc / 13399118471

18 Feb 2025 08:03PM UTC coverage: 85.031% (+0.06%) from 84.969%
13399118471

Pull #3299

github

web-flow
Merge f8e8fbd3c into 81b738862
Pull Request #3299: Random Ray Explicit Void Treatment

132 of 159 new or added lines in 5 files covered. (83.02%)

272 existing lines in 9 files now uncovered.

50569 of 59471 relevant lines covered (85.03%)

34980588.94 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

20.83
/include/openmc/particle_data.h
1
#ifndef OPENMC_PARTICLE_DATA_H
2
#define OPENMC_PARTICLE_DATA_H
3

4
#include "openmc/array.h"
5
#include "openmc/constants.h"
6
#include "openmc/position.h"
7
#include "openmc/random_lcg.h"
8
#include "openmc/tallies/filter_match.h"
9
#include "openmc/vector.h"
10

11
#ifdef DAGMC
12
#include "DagMC.hpp"
13
#endif
14

15
namespace openmc {
16

17
//==============================================================================
18
// Constants
19
//==============================================================================
20

21
// Since cross section libraries come with different numbers of delayed groups
22
// (e.g. ENDF/B-VII.1 has 6 and JEFF 3.1.1 has 8 delayed groups) and we don't
23
// yet know what cross section library is being used when the tallies.xml file
24
// is read in, we want to have an upper bound on the size of the array we
25
// use to store the bins for delayed group tallies.
26
constexpr int MAX_DELAYED_GROUPS {8};
27

28
constexpr double CACHE_INVALID {-1.0};
29

30
//==========================================================================
31
// Aliases and type definitions
32

33
//! Particle types
34
enum class ParticleType { neutron, photon, electron, positron };
35

36
//! Saved ("banked") state of a particle
37
//! NOTE: This structure's MPI type is built in initialize_mpi() of
38
//! initialize.cpp. Any changes made to the struct here must also be
39
//! made when building the Bank MPI type in initialize_mpi().
40
//! NOTE: This structure is also used on the python side, and is defined
41
//! in lib/core.py. Changes made to the type here must also be made to the
42
//! python defintion.
43
struct SourceSite {
44
  Position r;
45
  Direction u;
46
  double E;
47
  double time {0.0};
48
  double wgt {1.0};
49
  int delayed_group {0};
50
  int surf_id {0};
51
  ParticleType particle;
52
  int64_t parent_id;
53
  int64_t progeny_id;
54
};
55

56
//! State of a particle used for particle track files
57
struct TrackState {
58
  Position r;           //!< Position in [cm]
59
  Direction u;          //!< Direction
60
  double E;             //!< Energy in [eV]
61
  double time {0.0};    //!< Time in [s]
62
  double wgt {1.0};     //!< Weight
63
  int cell_id;          //!< Cell ID
64
  int cell_instance;    //!< Cell instance
65
  int material_id {-1}; //!< Material ID (default value indicates void)
66
};
67

68
//! Full history of a single particle's track states
69
struct TrackStateHistory {
70
  ParticleType particle;
71
  std::vector<TrackState> states;
72
};
73

74
//! Saved ("banked") state of a particle, for nu-fission tallying
75
struct NuBank {
76
  double E;          //!< particle energy
77
  double wgt;        //!< particle weight
78
  int delayed_group; //!< particle delayed group
79
};
80

81
class LocalCoord {
82
public:
83
  void rotate(const vector<double>& rotation);
84

85
  //! clear data from a single coordinate level
86
  void reset();
87

88
  Position r;  //!< particle position
89
  Direction u; //!< particle direction
90
  int cell {-1};
91
  int universe {-1};
92
  int lattice {-1};
93
  array<int, 3> lattice_i {{-1, -1, -1}};
94
  bool rotated {false}; //!< Is the level rotated?
95
};
96

97
//==============================================================================
98
//! Cached microscopic cross sections for a particular nuclide at the current
99
//! energy
100
//==============================================================================
101

102
struct NuclideMicroXS {
103
  // Microscopic cross sections in barns
104
  double total;      //!< total cross section
105
  double absorption; //!< absorption (disappearance)
106
  double fission;    //!< fission
107
  double nu_fission; //!< neutron production from fission
108

109
  double elastic;         //!< If sab_frac is not 1 or 0, then this value is
110
                          //!<   averaged over bound and non-bound nuclei
111
  double thermal;         //!< Bound thermal elastic & inelastic scattering
112
  double thermal_elastic; //!< Bound thermal elastic scattering
113
  double photon_prod;     //!< microscopic photon production xs
114

115
  // Cross sections for depletion reactions (note that these are not stored in
116
  // macroscopic cache)
117
  double reaction[DEPLETION_RX.size()];
118

119
  // Indicies and factors needed to compute cross sections from the data tables
120
  int index_grid;       //!< Index on nuclide energy grid
121
  int index_temp;       //!< Temperature index for nuclide
122
  double interp_factor; //!< Interpolation factor on nuc. energy grid
123
  int index_sab {-1};   //!< Index in sab_tables
124
  int index_temp_sab;   //!< Temperature index for sab_tables
125
  double sab_frac;      //!< Fraction of atoms affected by S(a,b)
126
  bool use_ptable;      //!< In URR range with probability tables?
127

128
  // Energy and temperature last used to evaluate these cross sections.  If
129
  // these values have changed, then the cross sections must be re-evaluated.
130
  double last_E {0.0};      //!< Last evaluated energy
131
  double last_sqrtkT {0.0}; //!< Last temperature in sqrt(Boltzmann constant
132
                            //!< * temperature (eV))
133
};
134

135
//==============================================================================
136
//! Cached microscopic photon cross sections for a particular element at the
137
//! current energy
138
//==============================================================================
139

140
struct ElementMicroXS {
141
  int index_grid;         //!< index on element energy grid
142
  double last_E {0.0};    //!< last evaluated energy in [eV]
143
  double interp_factor;   //!< interpolation factor on energy grid
144
  double total;           //!< microscopic total photon xs
145
  double coherent;        //!< microscopic coherent xs
146
  double incoherent;      //!< microscopic incoherent xs
147
  double photoelectric;   //!< microscopic photoelectric xs
148
  double pair_production; //!< microscopic pair production xs
149
};
150

151
//==============================================================================
152
// MacroXS contains cached macroscopic cross sections for the material a
153
// particle is traveling through
154
//==============================================================================
155

156
struct MacroXS {
157
  double total;       //!< macroscopic total xs
158
  double absorption;  //!< macroscopic absorption xs
159
  double fission;     //!< macroscopic fission xs
160
  double nu_fission;  //!< macroscopic production xs
161
  double photon_prod; //!< macroscopic photon production xs
162

163
  // Photon cross sections
164
  double coherent;        //!< macroscopic coherent xs
165
  double incoherent;      //!< macroscopic incoherent xs
166
  double photoelectric;   //!< macroscopic photoelectric xs
167
  double pair_production; //!< macroscopic pair production xs
168
};
169

170
//==============================================================================
171
// Cache contains the cached data for an MGXS object
172
//==============================================================================
173

174
struct CacheDataMG {
175
  int material {-1}; //!< material index
176
  double sqrtkT;     //!< last temperature corresponding to t
177
  int t {0};         //!< temperature index
178
  int a {0};         //!< angle index
179
  Direction u;       //!< angle that corresponds to a
180
};
181

182
//==============================================================================
183
// Information about nearest boundary crossing
184
//==============================================================================
185

186
struct BoundaryInfo {
187
  double distance {INFINITY}; //!< distance to nearest boundary
188
  int surface {
189
    SURFACE_NONE}; //!< surface token, non-zero if boundary is surface
190
  int coord_level; //!< coordinate level after crossing boundary
191
  array<int, 3>
192
    lattice_translation {}; //!< which way lattice indices will change
193

194
  void reset()
195
  {
196
    distance = INFINITY;
197
    surface = SURFACE_NONE;
198
    coord_level = 0;
199
    lattice_translation = {0, 0, 0};
200
  }
201
  // TODO: off-by-one
202
  int surface_index() const { return std::abs(surface) - 1; }
203
};
204

205
/*
206
 * Contains all geometry state information for a particle.
207
 */
208
class GeometryState {
209
public:
210
  GeometryState();
211

212
  /*
213
   * GeometryState does not store any ID info, so give some reasonable behavior
214
   * here. The Particle class redefines this. This is only here for the error
215
   * reporting behavior that occurs in geometry.cpp. The explanation for
216
   * mark_as_lost is the same.
217
   */
218
  virtual void mark_as_lost(const char* message);
219
  void mark_as_lost(const std::string& message);
220
  void mark_as_lost(const std::stringstream& message);
221

222
  // resets all coordinate levels for the particle
223
  void clear()
224
  {
225
    for (auto& level : coord_) {
226
      level.reset();
227
    }
228
    n_coord_ = 1;
229

230
    for (auto& cell : cell_last_) {
231
      cell = C_NONE;
232
    }
233
    n_coord_last_ = 1;
234
  }
235

236
  //! moves the particle by the specified distance to its next location
237
  //! \param distance the distance the particle is moved
238
  void move_distance(double distance);
239

240
  void advance_to_boundary_from_void();
241

242
  // Initialize all internal state from position and direction
243
  void init_from_r_u(Position r_a, Direction u_a)
244
  {
245
    clear();
246
    surface() = SURFACE_NONE;
247
    material() = C_NONE;
248
    r() = r_a;
249
    u() = u_a;
250
    r_last_current() = r_a;
251
    r_last() = r_a;
252
    u_last() = u_a;
253
  }
254

255
  // Unique ID. This is not geometric info, but the
256
  // error reporting in geometry.cpp requires this.
257
  // We could save this to implement it in Particle,
258
  // but that would require virtuals.
UNCOV
259
  int64_t& id() { return id_; }
×
260
  const int64_t& id() const { return id_; }
261

262
  // Number of current coordinate levels
263
  int& n_coord() { return n_coord_; }
×
264
  const int& n_coord() const { return n_coord_; }
265

266
  // Offset for distributed properties
UNCOV
267
  int& cell_instance() { return cell_instance_; }
×
268
  const int& cell_instance() const { return cell_instance_; }
269

270
  // Coordinates for all nesting levels
UNCOV
271
  LocalCoord& coord(int i) { return coord_[i]; }
×
272
  const LocalCoord& coord(int i) const { return coord_[i]; }
273
  const vector<LocalCoord>& coord() const { return coord_; }
274

275
  // Innermost universe nesting coordinates
UNCOV
276
  LocalCoord& lowest_coord() { return coord_[n_coord_ - 1]; }
×
277
  const LocalCoord& lowest_coord() const { return coord_[n_coord_ - 1]; }
278

279
  // Last coordinates on all nesting levels, before crossing a surface
280
  int& n_coord_last() { return n_coord_last_; }
281
  const int& n_coord_last() const { return n_coord_last_; }
282
  int& cell_last(int i) { return cell_last_[i]; }
283
  const int& cell_last(int i) const { return cell_last_[i]; }
284

285
  // Coordinates at birth
286
  Position& r_born() { return r_born_; }
287
  const Position& r_born() const { return r_born_; }
288

289
  // Coordinates of last collision or reflective/periodic surface
290
  // crossing for current tallies
291
  Position& r_last_current() { return r_last_current_; }
292
  const Position& r_last_current() const { return r_last_current_; }
293

294
  // Previous direction and spatial coordinates before a collision
295
  Position& r_last() { return r_last_; }
296
  const Position& r_last() const { return r_last_; }
297
  Position& u_last() { return u_last_; }
298
  const Position& u_last() const { return u_last_; }
299

300
  // Accessors for position in global coordinates
UNCOV
301
  Position& r() { return coord_[0].r; }
×
302
  const Position& r() const { return coord_[0].r; }
303

304
  // Accessors for position in local coordinates
305
  Position& r_local() { return coord_[n_coord_ - 1].r; }
306
  const Position& r_local() const { return coord_[n_coord_ - 1].r; }
307

308
  // Accessors for direction in global coordinates
UNCOV
309
  Direction& u() { return coord_[0].u; }
×
310
  const Direction& u() const { return coord_[0].u; }
311

312
  // Accessors for direction in local coordinates
313
  Direction& u_local() { return coord_[n_coord_ - 1].u; }
314
  const Direction& u_local() const { return coord_[n_coord_ - 1].u; }
315

316
  // Surface token for the surface that the particle is currently on
317
  int& surface() { return surface_; }
318
  const int& surface() const { return surface_; }
319

320
  // Surface index based on the current value of the surface_ attribute
321
  int surface_index() const
322
  {
323
    // TODO: off-by-one
324
    return std::abs(surface_) - 1;
325
  }
326

327
  // Boundary information
UNCOV
328
  BoundaryInfo& boundary() { return boundary_; }
×
329

330
#ifdef DAGMC
331
  // DagMC state variables
332
  moab::DagMC::RayHistory& history() { return history_; }
333
  Direction& last_dir() { return last_dir_; }
334
#endif
335

336
  // material of current and last cell
UNCOV
337
  int& material() { return material_; }
×
338
  const int& material() const { return material_; }
339
  int& material_last() { return material_last_; }
340
  const int& material_last() const { return material_last_; }
341

342
  // temperature of current and last cell
343
  double& sqrtkT() { return sqrtkT_; }
344
  const double& sqrtkT() const { return sqrtkT_; }
345
  double& sqrtkT_last() { return sqrtkT_last_; }
346

347
private:
348
  int64_t id_ {-1}; //!< Unique ID
349

350
  int n_coord_ {1};          //!< number of current coordinate levels
351
  int cell_instance_;        //!< offset for distributed properties
352
  vector<LocalCoord> coord_; //!< coordinates for all levels
353

354
  int n_coord_last_ {1};  //!< number of current coordinates
355
  vector<int> cell_last_; //!< coordinates for all levels
356

357
  Position r_born_;         //!< coordinates at birth
358
  Position r_last_current_; //!< coordinates of the last collision or
359
                            //!< reflective/periodic surface crossing for
360
                            //!< current tallies
361
  Position r_last_;         //!< previous coordinates
362
  Direction u_last_;        //!< previous direction coordinates
363

364
  int surface_ {
365
    SURFACE_NONE}; //!< surface token for surface the particle is currently on
366

367
  BoundaryInfo boundary_; //!< Info about the next intersection
368

369
  int material_ {-1};      //!< index for current material
370
  int material_last_ {-1}; //!< index for last material
371

372
  double sqrtkT_ {-1.0};     //!< sqrt(k_Boltzmann * temperature) in eV
373
  double sqrtkT_last_ {0.0}; //!< last temperature
374

375
#ifdef DAGMC
376
  moab::DagMC::RayHistory history_;
377
  Direction last_dir_;
378
#endif
379
};
380

381
//============================================================================
382
//! Defines how particle data is laid out in memory
383
//============================================================================
384

385
/*
386
 * This class was added in order to separate the layout and access of particle
387
 * data from particle physics operations during a development effort to get
388
 * OpenMC running on GPUs. In the event-based Monte Carlo method, one creates
389
 * an array of particles on which actions like cross section lookup and surface
390
 * crossing are done en masse, which works best on vector computers of yore and
391
 * modern GPUs. It has been shown in the below publication [1] that arranging
392
 * particle data into a structure of arrays rather than an array of structures
393
 * enhances performance on GPUs. For instance, rather than having an
394
 * std::vector<Particle> where consecutive particle energies would be separated
395
 * by about 400 bytes, one would create a structure which has a single
396
 * std::vector<double> of energies.  The motivation here is that more coalesced
397
 * memory accesses occur, in the parlance of GPU programming.
398
 *
399
 * So, this class enables switching between the array-of-structures and
400
 * structure- of-array data layout at compile time. In GPU branches of the
401
 * code, our Particle class inherits from a class that provides an array of
402
 * particle energies, and can access them using the E() method (defined below).
403
 * In the CPU code, we inherit from this class which gives the conventional
404
 * layout of particle data, useful for history-based tracking.
405
 *
406
 * As a result, we always use the E(), r_last(), etc. methods to access
407
 * particle data in order to keep a unified interface between
408
 * structure-of-array and array-of-structure code on either CPU or GPU code
409
 * while sharing the same physics code on each codebase.
410
 *
411
 * [1] Hamilton, Steven P., Stuart R. Slattery, and Thomas M. Evans.
412
 *   “Multigroup Monte Carlo on GPUs: Comparison of History- and Event-Based
413
 *   Algorithms.” Annals of Nuclear Energy 113 (March 2018): 506–18.
414
 *   https://doi.org/10.1016/j.anucene.2017.11.032.
415
 */
416
class ParticleData : public GeometryState {
417
private:
418
  //==========================================================================
419
  // Data members -- see public: below for descriptions
420

421
  vector<NuclideMicroXS> neutron_xs_;
422
  vector<ElementMicroXS> photon_xs_;
423
  MacroXS macro_xs_;
424
  CacheDataMG mg_xs_cache_;
425

426
  ParticleType type_ {ParticleType::neutron};
427

428
  double E_;
429
  double E_last_;
430
  int g_ {0};
431
  int g_last_;
432

433
  double wgt_ {1.0};
434
  double mu_;
435
  double time_ {0.0};
436
  double time_last_ {0.0};
437
  double wgt_last_ {1.0};
438

439
  bool fission_ {false};
440
  TallyEvent event_;
441
  int event_nuclide_;
442
  int event_mt_;
443
  int delayed_group_ {0};
444

445
  int n_bank_ {0};
446
  double bank_second_E_ {0.0};
447
  double wgt_bank_ {0.0};
448
  int n_delayed_bank_[MAX_DELAYED_GROUPS];
449

450
  int cell_born_ {-1};
451

452
  int n_collision_ {0};
453

454
  bool write_track_ {false};
455

456
  uint64_t seeds_[N_STREAMS];
457
  int stream_;
458

459
  vector<SourceSite> secondary_bank_;
460

461
  int64_t current_work_;
462

463
  vector<double> flux_derivs_;
464

465
  vector<FilterMatch> filter_matches_;
466

467
  vector<TrackStateHistory> tracks_;
468

469
  vector<NuBank> nu_bank_;
470

471
  vector<double> pht_storage_;
472

473
  double keff_tally_absorption_ {0.0};
474
  double keff_tally_collision_ {0.0};
475
  double keff_tally_tracklength_ {0.0};
476
  double keff_tally_leakage_ {0.0};
477

478
  bool trace_ {false};
479

480
  double collision_distance_;
481

482
  int n_event_ {0};
483

484
  int n_split_ {0};
485
  double ww_factor_ {0.0};
486

487
  int64_t n_progeny_ {0};
488

489
public:
490
  //----------------------------------------------------------------------------
491
  // Constructors
492
  ParticleData();
493

494
  //==========================================================================
495
  // Methods and accessors
496

497
  // Cross section caches
498
  NuclideMicroXS& neutron_xs(int i)
2,147,483,647✔
499
  {
500
    return neutron_xs_[i];
2,147,483,647✔
501
  } // Microscopic neutron cross sections
502
  const NuclideMicroXS& neutron_xs(int i) const { return neutron_xs_[i]; }
503

504
  // Microscopic photon cross sections
505
  ElementMicroXS& photon_xs(int i) { return photon_xs_[i]; }
172,700,638✔
506

507
  // Macroscopic cross sections
508
  MacroXS& macro_xs() { return macro_xs_; }
2,147,483,647✔
509
  const MacroXS& macro_xs() const { return macro_xs_; }
510

511
  // Multigroup macroscopic cross sections
512
  CacheDataMG& mg_xs_cache() { return mg_xs_cache_; }
513
  const CacheDataMG& mg_xs_cache() const { return mg_xs_cache_; }
514

515
  // Particle type (n, p, e, gamma, etc)
UNCOV
516
  ParticleType& type() { return type_; }
×
517
  const ParticleType& type() const { return type_; }
518

519
  // Current particle energy, energy before collision,
520
  // and corresponding multigroup group indices. Energy
521
  // units are eV.
UNCOV
522
  double& E() { return E_; }
×
523
  const double& E() const { return E_; }
524
  double& E_last() { return E_last_; }
525
  const double& E_last() const { return E_last_; }
526
  int& g() { return g_; }
527
  const int& g() const { return g_; }
528
  int& g_last() { return g_last_; }
529
  const int& g_last() const { return g_last_; }
530

531
  // Statistic weight of particle. Setting to zero
532
  // indicates that the particle is dead.
533
  double& wgt() { return wgt_; }
×
534
  double wgt() const { return wgt_; }
535
  double& wgt_last() { return wgt_last_; }
536
  const double& wgt_last() const { return wgt_last_; }
UNCOV
537
  bool alive() const { return wgt_ != 0.0; }
×
538

539
  // Polar scattering angle after a collision
540
  double& mu() { return mu_; }
541
  const double& mu() const { return mu_; }
542

543
  // Tracks the time of a particle as it traverses the problem.
544
  // Units are seconds.
545
  double& time() { return time_; }
UNCOV
546
  const double& time() const { return time_; }
×
547
  double& time_last() { return time_last_; }
548
  const double& time_last() const { return time_last_; }
2,109,276✔
549

550
  // What event took place, described in greater detail below
551
  TallyEvent& event() { return event_; }
552
  const TallyEvent& event() const { return event_; }
553
  bool& fission() { return fission_; }            // true if implicit fission
554
  int& event_nuclide() { return event_nuclide_; } // index of collision nuclide
555
  const int& event_nuclide() const { return event_nuclide_; }
556
  int& event_mt() { return event_mt_; }           // MT number of collision
557
  int& delayed_group() { return delayed_group_; } // delayed group
558

559
  // Post-collision data
560
  double& bank_second_E()
561
  {
562
    return bank_second_E_;
563
  } // energy of last reaction secondaries
564
  const double& bank_second_E() const { return bank_second_E_; }
565

566
  int& n_bank() { return n_bank_; }        // number of banked fission sites
567
  double& wgt_bank() { return wgt_bank_; } // weight of banked fission sites
568
  int* n_delayed_bank()
569
  {
570
    return n_delayed_bank_;
571
  } // number of delayed fission sites
572
  int& n_delayed_bank(int i)
573
  {
574
    return n_delayed_bank_[i];
575
  } // number of delayed fission sites
576

577
  // Index of cell particle is born in
578
  int& cell_born() { return cell_born_; }
×
579
  const int& cell_born() const { return cell_born_; }
580

581
  // Total number of collisions suffered by particle
582
  int& n_collision() { return n_collision_; }
583
  const int& n_collision() const { return n_collision_; }
584

585
  // whether this track is to be written
586
  bool& write_track() { return write_track_; }
587

588
  // RNG state
589
  uint64_t& seeds(int i) { return seeds_[i]; }
UNCOV
590
  uint64_t* seeds() { return seeds_; }
×
UNCOV
591
  int& stream() { return stream_; }
×
592

593
  // secondary particle bank
594
  SourceSite& secondary_bank(int i) { return secondary_bank_[i]; }
595
  decltype(secondary_bank_)& secondary_bank() { return secondary_bank_; }
596

597
  // Current simulation work index
598
  int64_t& current_work() { return current_work_; }
599
  const int64_t& current_work() const { return current_work_; }
600

601
  // Used in tally derivatives
602
  double& flux_derivs(int i) { return flux_derivs_[i]; }
603
  const double& flux_derivs(int i) const { return flux_derivs_[i]; }
604

605
  // Matches of tallies
606
  decltype(filter_matches_)& filter_matches() { return filter_matches_; }
607
  FilterMatch& filter_matches(int i) { return filter_matches_[i]; }
608

609
  // Tracks to output to file
610
  decltype(tracks_)& tracks() { return tracks_; }
611

612
  // Bank of recently fissioned particles
613
  decltype(nu_bank_)& nu_bank() { return nu_bank_; }
614
  NuBank& nu_bank(int i) { return nu_bank_[i]; }
615

616
  // Interim pulse height tally storage
617
  vector<double>& pht_storage() { return pht_storage_; }
618

619
  // Global tally accumulators
620
  double& keff_tally_absorption() { return keff_tally_absorption_; }
621
  double& keff_tally_collision() { return keff_tally_collision_; }
622
  double& keff_tally_tracklength() { return keff_tally_tracklength_; }
623
  double& keff_tally_leakage() { return keff_tally_leakage_; }
624

625
  // Shows debug info
626
  bool& trace() { return trace_; }
627

628
  // Distance to the next collision
629
  double& collision_distance() { return collision_distance_; }
630

631
  // Number of events particle has undergone
UNCOV
632
  int& n_event() { return n_event_; }
×
633

634
  // Number of times variance reduction has caused a particle split
635
  int n_split() const { return n_split_; }
636
  int& n_split() { return n_split_; }
637

638
  // Particle-specific factor for on-the-fly weight window adjustment
639
  double ww_factor() const { return ww_factor_; }
640
  double& ww_factor() { return ww_factor_; }
641

642
  // Number of progeny produced by this particle
643
  int64_t& n_progeny() { return n_progeny_; }
644

645
  //! Gets the pointer to the particle's current PRN seed
UNCOV
646
  uint64_t* current_seed() { return seeds_ + stream_; }
×
647
  const uint64_t* current_seed() const { return seeds_ + stream_; }
648

649
  //! Force recalculation of neutron xs by setting last energy to zero
650
  void invalidate_neutron_xs()
651
  {
652
    for (auto& micro : neutron_xs_)
653
      micro.last_E = 0.0;
654
  }
655

656
  //! Get track information based on particle's current state
657
  TrackState get_track_state() const;
658

659
  void zero_delayed_bank()
660
  {
661
    for (int& n : n_delayed_bank_) {
662
      n = 0;
663
    }
664
  }
665

666
  void zero_flux_derivs()
667
  {
668
    for (double& d : flux_derivs_) {
669
      d = 0;
670
    }
671
  }
672
};
673

674
} // namespace openmc
675

676
#endif // OPENMC_PARTICLE_DATA_H
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc