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

openmc-dev / openmc / 12954288577

24 Jan 2025 05:13PM UTC coverage: 84.833% (-0.1%) from 84.928%
12954288577

Pull #2671

github

web-flow
Merge d2ca87df5 into 560bd22bc
Pull Request #2671: Adding methods to automatically apply results to existing Tally objects.

53 of 65 new or added lines in 7 files covered. (81.54%)

59 existing lines in 20 files now uncovered.

50089 of 59044 relevant lines covered (84.83%)

34992387.74 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
  // TODO: off-by-one
195
  int surface_index() const { return std::abs(surface) - 1; }
196
};
197

198
/*
199
 * Contains all geometry state information for a particle.
200
 */
201
class GeometryState {
202
public:
203
  GeometryState();
204

205
  /*
206
   * GeometryState does not store any ID info, so give some reasonable behavior
207
   * here. The Particle class redefines this. This is only here for the error
208
   * reporting behavior that occurs in geometry.cpp. The explanation for
209
   * mark_as_lost is the same.
210
   */
211
  virtual void mark_as_lost(const char* message);
212
  void mark_as_lost(const std::string& message);
213
  void mark_as_lost(const std::stringstream& message);
214

215
  // resets all coordinate levels for the particle
216
  void clear()
217
  {
218
    for (auto& level : coord_) {
219
      level.reset();
220
    }
221
    n_coord_ = 1;
222

223
    for (auto& cell : cell_last_) {
224
      cell = C_NONE;
225
    }
226
    n_coord_last_ = 1;
227
  }
228

229
  // Initialize all internal state from position and direction
230
  void init_from_r_u(Position r_a, Direction u_a)
231
  {
232
    clear();
233
    surface() = SURFACE_NONE;
234
    material() = C_NONE;
235
    r() = r_a;
236
    u() = u_a;
237
    r_last_current() = r_a;
238
    r_last() = r_a;
239
    u_last() = u_a;
240
  }
241

242
  // Unique ID. This is not geometric info, but the
243
  // error reporting in geometry.cpp requires this.
244
  // We could save this to implement it in Particle,
245
  // but that would require virtuals.
UNCOV
246
  int64_t& id() { return id_; }
×
247
  const int64_t& id() const { return id_; }
248

249
  // Number of current coordinate levels
UNCOV
250
  int& n_coord() { return n_coord_; }
×
251
  const int& n_coord() const { return n_coord_; }
252

253
  // Offset for distributed properties
UNCOV
254
  int& cell_instance() { return cell_instance_; }
×
255
  const int& cell_instance() const { return cell_instance_; }
256

257
  // Coordinates for all nesting levels
UNCOV
258
  LocalCoord& coord(int i) { return coord_[i]; }
×
259
  const LocalCoord& coord(int i) const { return coord_[i]; }
260
  const vector<LocalCoord>& coord() const { return coord_; }
261

262
  // Innermost universe nesting coordinates
UNCOV
263
  LocalCoord& lowest_coord() { return coord_[n_coord_ - 1]; }
×
264
  const LocalCoord& lowest_coord() const { return coord_[n_coord_ - 1]; }
265

266
  // Last coordinates on all nesting levels, before crossing a surface
267
  int& n_coord_last() { return n_coord_last_; }
268
  const int& n_coord_last() const { return n_coord_last_; }
269
  int& cell_last(int i) { return cell_last_[i]; }
270
  const int& cell_last(int i) const { return cell_last_[i]; }
271

272
  // Coordinates at birth
273
  Position& r_born() { return r_born_; }
274
  const Position& r_born() const { return r_born_; }
275

276
  // Coordinates of last collision or reflective/periodic surface
277
  // crossing for current tallies
278
  Position& r_last_current() { return r_last_current_; }
279
  const Position& r_last_current() const { return r_last_current_; }
280

281
  // Previous direction and spatial coordinates before a collision
282
  Position& r_last() { return r_last_; }
283
  const Position& r_last() const { return r_last_; }
284
  Position& u_last() { return u_last_; }
285
  const Position& u_last() const { return u_last_; }
286

287
  // Accessors for position in global coordinates
UNCOV
288
  Position& r() { return coord_[0].r; }
×
289
  const Position& r() const { return coord_[0].r; }
290

291
  // Accessors for position in local coordinates
292
  Position& r_local() { return coord_[n_coord_ - 1].r; }
293
  const Position& r_local() const { return coord_[n_coord_ - 1].r; }
294

295
  // Accessors for direction in global coordinates
UNCOV
296
  Direction& u() { return coord_[0].u; }
×
297
  const Direction& u() const { return coord_[0].u; }
298

299
  // Accessors for direction in local coordinates
300
  Direction& u_local() { return coord_[n_coord_ - 1].u; }
301
  const Direction& u_local() const { return coord_[n_coord_ - 1].u; }
302

303
  // Surface token for the surface that the particle is currently on
304
  int& surface() { return surface_; }
305
  const int& surface() const { return surface_; }
306

307
  // Surface index based on the current value of the surface_ attribute
308
  int surface_index() const
309
  {
310
    // TODO: off-by-one
311
    return std::abs(surface_) - 1;
312
  }
313

314
  // Boundary information
UNCOV
315
  BoundaryInfo& boundary() { return boundary_; }
×
316

317
#ifdef DAGMC
318
  // DagMC state variables
319
  moab::DagMC::RayHistory& history() { return history_; }
320
  Direction& last_dir() { return last_dir_; }
321
#endif
322

323
  // material of current and last cell
UNCOV
324
  int& material() { return material_; }
×
325
  const int& material() const { return material_; }
326
  int& material_last() { return material_last_; }
327
  const int& material_last() const { return material_last_; }
328

329
  // temperature of current and last cell
330
  double& sqrtkT() { return sqrtkT_; }
331
  const double& sqrtkT() const { return sqrtkT_; }
332
  double& sqrtkT_last() { return sqrtkT_last_; }
333

334
private:
335
  int64_t id_ {-1}; //!< Unique ID
336

337
  int n_coord_ {1};          //!< number of current coordinate levels
338
  int cell_instance_;        //!< offset for distributed properties
339
  vector<LocalCoord> coord_; //!< coordinates for all levels
340

341
  int n_coord_last_ {1};  //!< number of current coordinates
342
  vector<int> cell_last_; //!< coordinates for all levels
343

344
  Position r_born_;         //!< coordinates at birth
345
  Position r_last_current_; //!< coordinates of the last collision or
346
                            //!< reflective/periodic surface crossing for
347
                            //!< current tallies
348
  Position r_last_;         //!< previous coordinates
349
  Direction u_last_;        //!< previous direction coordinates
350

351
  int surface_ {
352
    SURFACE_NONE}; //!< surface token for surface the particle is currently on
353

354
  BoundaryInfo boundary_; //!< Info about the next intersection
355

356
  int material_ {-1};      //!< index for current material
357
  int material_last_ {-1}; //!< index for last material
358

359
  double sqrtkT_ {-1.0};     //!< sqrt(k_Boltzmann * temperature) in eV
360
  double sqrtkT_last_ {0.0}; //!< last temperature
361

362
#ifdef DAGMC
363
  moab::DagMC::RayHistory history_;
364
  Direction last_dir_;
365
#endif
366
};
367

368
//============================================================================
369
//! Defines how particle data is laid out in memory
370
//============================================================================
371

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

408
  vector<NuclideMicroXS> neutron_xs_;
409
  vector<ElementMicroXS> photon_xs_;
410
  MacroXS macro_xs_;
411
  CacheDataMG mg_xs_cache_;
412

413
  ParticleType type_ {ParticleType::neutron};
414

415
  double E_;
416
  double E_last_;
417
  int g_ {0};
418
  int g_last_;
419

420
  double wgt_ {1.0};
421
  double mu_;
422
  double time_ {0.0};
423
  double time_last_ {0.0};
424
  double wgt_last_ {1.0};
425

426
  bool fission_ {false};
427
  TallyEvent event_;
428
  int event_nuclide_;
429
  int event_mt_;
430
  int delayed_group_ {0};
431

432
  int n_bank_ {0};
433
  int n_bank_second_ {0};
434
  double wgt_bank_ {0.0};
435
  int n_delayed_bank_[MAX_DELAYED_GROUPS];
436

437
  int cell_born_ {-1};
438

439
  int n_collision_ {0};
440

441
  bool write_track_ {false};
442

443
  uint64_t seeds_[N_STREAMS];
444
  int stream_;
445

446
  vector<SourceSite> secondary_bank_;
447

448
  int64_t current_work_;
449

450
  vector<double> flux_derivs_;
451

452
  vector<FilterMatch> filter_matches_;
453

454
  vector<TrackStateHistory> tracks_;
455

456
  vector<NuBank> nu_bank_;
457

458
  vector<double> pht_storage_;
459

460
  double keff_tally_absorption_ {0.0};
461
  double keff_tally_collision_ {0.0};
462
  double keff_tally_tracklength_ {0.0};
463
  double keff_tally_leakage_ {0.0};
464

465
  bool trace_ {false};
466

467
  double collision_distance_;
468

469
  int n_event_ {0};
470

471
  int n_split_ {0};
472
  double ww_factor_ {0.0};
473

474
  int64_t n_progeny_ {0};
475

476
public:
477
  //----------------------------------------------------------------------------
478
  // Constructors
479
  ParticleData();
480

481
  //==========================================================================
482
  // Methods and accessors
483

484
  // Cross section caches
485
  NuclideMicroXS& neutron_xs(int i)
2,147,483,647✔
486
  {
487
    return neutron_xs_[i];
2,147,483,647✔
488
  } // Microscopic neutron cross sections
489
  const NuclideMicroXS& neutron_xs(int i) const { return neutron_xs_[i]; }
490

491
  // Microscopic photon cross sections
492
  ElementMicroXS& photon_xs(int i) { return photon_xs_[i]; }
149,342,276✔
493

494
  // Macroscopic cross sections
495
  MacroXS& macro_xs() { return macro_xs_; }
2,147,483,647✔
496
  const MacroXS& macro_xs() const { return macro_xs_; }
497

498
  // Multigroup macroscopic cross sections
499
  CacheDataMG& mg_xs_cache() { return mg_xs_cache_; }
500
  const CacheDataMG& mg_xs_cache() const { return mg_xs_cache_; }
501

502
  // Particle type (n, p, e, gamma, etc)
UNCOV
503
  ParticleType& type() { return type_; }
×
504
  const ParticleType& type() const { return type_; }
505

506
  // Current particle energy, energy before collision,
507
  // and corresponding multigroup group indices. Energy
508
  // units are eV.
UNCOV
509
  double& E() { return E_; }
×
510
  const double& E() const { return E_; }
511
  double& E_last() { return E_last_; }
512
  const double& E_last() const { return E_last_; }
513
  int& g() { return g_; }
514
  const int& g() const { return g_; }
515
  int& g_last() { return g_last_; }
516
  const int& g_last() const { return g_last_; }
517

518
  // Statistic weight of particle. Setting to zero
519
  // indicates that the particle is dead.
520
  double& wgt() { return wgt_; }
×
521
  double wgt() const { return wgt_; }
522
  double& wgt_last() { return wgt_last_; }
523
  const double& wgt_last() const { return wgt_last_; }
UNCOV
524
  bool alive() const { return wgt_ != 0.0; }
×
525

526
  // Polar scattering angle after a collision
527
  double& mu() { return mu_; }
528
  const double& mu() const { return mu_; }
529

530
  // Tracks the time of a particle as it traverses the problem.
531
  // Units are seconds.
532
  double& time() { return time_; }
UNCOV
533
  const double& time() const { return time_; }
×
534
  double& time_last() { return time_last_; }
535
  const double& time_last() const { return time_last_; }
2,109,276✔
536

537
  // What event took place, described in greater detail below
538
  TallyEvent& event() { return event_; }
539
  const TallyEvent& event() const { return event_; }
540
  bool& fission() { return fission_; }            // true if implicit fission
541
  int& event_nuclide() { return event_nuclide_; } // index of collision nuclide
542
  const int& event_nuclide() const { return event_nuclide_; }
543
  int& event_mt() { return event_mt_; }           // MT number of collision
544
  int& delayed_group() { return delayed_group_; } // delayed group
545

546
  // Post-collision data
547
  int& n_bank() { return n_bank_; } // number of banked fission sites
548
  int& n_bank_second()
549
  {
550
    return n_bank_second_;
551
  }                                        // number of secondaries banked
552
  double& wgt_bank() { return wgt_bank_; } // weight of banked fission sites
553
  int* n_delayed_bank()
554
  {
555
    return n_delayed_bank_;
556
  } // number of delayed fission sites
557
  int& n_delayed_bank(int i)
558
  {
559
    return n_delayed_bank_[i];
560
  } // number of delayed fission sites
561

562
  // Index of cell particle is born in
UNCOV
563
  int& cell_born() { return cell_born_; }
×
564
  const int& cell_born() const { return cell_born_; }
565

566
  // index of the current and last material
567
  // Total number of collisions suffered by particle
568
  int& n_collision() { return n_collision_; }
569
  const int& n_collision() const { return n_collision_; }
570

571
  // whether this track is to be written
572
  bool& write_track() { return write_track_; }
573

574
  // RNG state
575
  uint64_t& seeds(int i) { return seeds_[i]; }
UNCOV
576
  uint64_t* seeds() { return seeds_; }
×
UNCOV
577
  int& stream() { return stream_; }
×
578

579
  // secondary particle bank
580
  SourceSite& secondary_bank(int i) { return secondary_bank_[i]; }
581
  decltype(secondary_bank_)& secondary_bank() { return secondary_bank_; }
582

583
  // Current simulation work index
584
  int64_t& current_work() { return current_work_; }
585
  const int64_t& current_work() const { return current_work_; }
586

587
  // Used in tally derivatives
588
  double& flux_derivs(int i) { return flux_derivs_[i]; }
589
  const double& flux_derivs(int i) const { return flux_derivs_[i]; }
590

591
  // Matches of tallies
592
  decltype(filter_matches_)& filter_matches() { return filter_matches_; }
593
  FilterMatch& filter_matches(int i) { return filter_matches_[i]; }
594

595
  // Tracks to output to file
596
  decltype(tracks_)& tracks() { return tracks_; }
597

598
  // Bank of recently fissioned particles
599
  decltype(nu_bank_)& nu_bank() { return nu_bank_; }
600
  NuBank& nu_bank(int i) { return nu_bank_[i]; }
601

602
  // Interim pulse height tally storage
603
  vector<double>& pht_storage() { return pht_storage_; }
604

605
  // Global tally accumulators
606
  double& keff_tally_absorption() { return keff_tally_absorption_; }
607
  double& keff_tally_collision() { return keff_tally_collision_; }
608
  double& keff_tally_tracklength() { return keff_tally_tracklength_; }
609
  double& keff_tally_leakage() { return keff_tally_leakage_; }
610

611
  // Shows debug info
612
  bool& trace() { return trace_; }
613

614
  // Distance to the next collision
615
  double& collision_distance() { return collision_distance_; }
616

617
  // Number of events particle has undergone
UNCOV
618
  int& n_event() { return n_event_; }
×
619

620
  // Number of times variance reduction has caused a particle split
621
  int n_split() const { return n_split_; }
622
  int& n_split() { return n_split_; }
623

624
  // Particle-specific factor for on-the-fly weight window adjustment
625
  double ww_factor() const { return ww_factor_; }
626
  double& ww_factor() { return ww_factor_; }
627

628
  // Number of progeny produced by this particle
629
  int64_t& n_progeny() { return n_progeny_; }
630

631
  //! Gets the pointer to the particle's current PRN seed
632
  uint64_t* current_seed() { return seeds_ + stream_; }
×
633
  const uint64_t* current_seed() const { return seeds_ + stream_; }
634

635
  //! Force recalculation of neutron xs by setting last energy to zero
636
  void invalidate_neutron_xs()
637
  {
638
    for (auto& micro : neutron_xs_)
639
      micro.last_E = 0.0;
640
  }
641

642
  //! Get track information based on particle's current state
643
  TrackState get_track_state() const;
644

645
  void zero_delayed_bank()
646
  {
647
    for (int& n : n_delayed_bank_) {
648
      n = 0;
649
    }
650
  }
651

652
  void zero_flux_derivs()
653
  {
654
    for (double& d : flux_derivs_) {
655
      d = 0;
656
    }
657
  }
658
};
659

660
} // namespace openmc
661

662
#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