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

openmc-dev / openmc / 14840340664

05 May 2025 03:38PM UTC coverage: 85.195% (-0.009%) from 85.204%
14840340664

Pull #3392

github

web-flow
Merge 5bc1ec35f into 1e7d8324e
Pull Request #3392: Map Compton subshell data to atomic relaxation data

14 of 14 new or added lines in 2 files covered. (100.0%)

330 existing lines in 19 files now uncovered.

52194 of 61264 relevant lines covered (85.2%)

37398320.1 hits per line

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

25.49
/include/openmc/random_ray/source_region.h
1
#ifndef OPENMC_RANDOM_RAY_SOURCE_REGION_H
2
#define OPENMC_RANDOM_RAY_SOURCE_REGION_H
3

4
#include "openmc/openmp_interface.h"
5
#include "openmc/position.h"
6
#include "openmc/random_ray/moment_matrix.h"
7
#include "openmc/settings.h"
8

9
namespace openmc {
10

11
//----------------------------------------------------------------------------
12
// Helper Functions
13

14
// The hash_combine function is the standard hash combine function from boost
15
// that is typically used for combining multiple hash values into a single hash
16
// as is needed for larger objects being stored in a hash map. The function is
17
// taken from:
18
// https://www.boost.org/doc/libs/1_55_0/doc/html/hash/reference.html#boost.hash_combine
19
// which carries the following license:
20
//
21
// Boost Software License - Version 1.0 - August 17th, 2003
22
// Permission is hereby granted, free of charge, to any person or organization
23
// obtaining a copy of the software and accompanying documentation covered by
24
// this license (the "Software") to use, reproduce, display, distribute,
25
// execute, and transmit the Software, and to prepare derivative works of the
26
// Software, and to permit third-parties to whom the Software is furnished to
27
// do so, all subject to the following:
28
// The copyright notices in the Software and this entire statement, including
29
// the above license grant, this restriction and the following disclaimer,
30
// must be included in all copies of the Software, in whole or in part, and
31
// all derivative works of the Software, unless such copies or derivative
32
// works are solely in the form of machine-executable object code generated by
33
// a source language processor.
34
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
37
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
38
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
39
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
40
// DEALINGS IN THE SOFTWARE.
41
inline void hash_combine(size_t& seed, const size_t v)
42
{
43
  seed ^= (v + 0x9e3779b9 + (seed << 6) + (seed >> 2));
44
}
45

46
//----------------------------------------------------------------------------
47
// Helper Structs and Classes
48

49
// A mapping object that is used to map between a specific random ray
50
// source region and an OpenMC native tally bin that it should score to
51
// every iteration.
52
struct TallyTask {
53
  int tally_idx;
54
  int filter_idx;
55
  int score_idx;
56
  int score_type;
57
  TallyTask(int tally_idx, int filter_idx, int score_idx, int score_type)
58
    : tally_idx(tally_idx), filter_idx(filter_idx), score_idx(score_idx),
59
      score_type(score_type)
60
  {}
61
  TallyTask() = default;
62

63
  // Comparison and Hash operators are defined to allow usage of the
64
  // TallyTask struct as a key in an unordered_set
65
  bool operator==(const TallyTask& other) const
66
  {
67
    return tally_idx == other.tally_idx && filter_idx == other.filter_idx &&
68
           score_idx == other.score_idx && score_type == other.score_type;
69
  }
70

71
  struct HashFunctor {
72
    size_t operator()(const TallyTask& task) const
73
    {
74
      size_t seed = 0;
75
      hash_combine(seed, task.tally_idx);
76
      hash_combine(seed, task.filter_idx);
77
      hash_combine(seed, task.score_idx);
78
      hash_combine(seed, task.score_type);
79
      return seed;
80
    }
81
  };
82
};
83

84
// The SourceRegionKey combines a base source region (i.e., a material
85
// filled cell instance) with a mesh bin. This key is used as a handle
86
// for dynamically discovered source regions when subdividing source
87
// regions with meshes.
88
class SourceRegionKey {
89
public:
90
  int64_t base_source_region_id;
91
  int64_t mesh_bin;
92
  SourceRegionKey() = default;
93
  SourceRegionKey(int64_t source_region, int64_t bin)
94
    : base_source_region_id(source_region), mesh_bin(bin)
95
  {}
96

97
  // Equality operator required by the unordered_map
98
  bool operator==(const SourceRegionKey& other) const
99
  {
100
    return base_source_region_id == other.base_source_region_id &&
101
           mesh_bin == other.mesh_bin;
102
  }
103

104
  // Less than operator required by std::sort
105
  bool operator<(const SourceRegionKey& other) const
106
  {
107
    if (base_source_region_id < other.base_source_region_id) {
108
      return true;
109
    } else if (base_source_region_id > other.base_source_region_id) {
110
      return false;
111
    } else {
112
      return mesh_bin < other.mesh_bin;
113
    }
114
  }
115

116
  // Hashing functor required by the unordered_map
117
  struct HashFunctor {
118
    size_t operator()(const SourceRegionKey& key) const
119
    {
120
      size_t seed = 0;
121
      hash_combine(seed, key.base_source_region_id);
122
      hash_combine(seed, key.mesh_bin);
123
      return seed;
124
    }
125
  };
126
};
127

128
// Forward declaration of SourceRegion
129
class SourceRegion;
130

131
class SourceRegionHandle {
132
public:
133
  //----------------------------------------------------------------------------
134
  // Constructors
135
  SourceRegionHandle(SourceRegion& sr);
UNCOV
136
  SourceRegionHandle() = default;
×
137

138
  // All fields are commented/described in the SourceRegion class definition
139
  // below
140

141
  //----------------------------------------------------------------------------
142
  // Public Data members
143
  int negroups_;
144
  bool is_numerical_fp_artifact_ {false};
145
  bool is_linear_ {false};
146

147
  // Scalar fields
148
  int* material_;
149
  int* is_small_;
150
  int* n_hits_;
151
  int* birthday_;
152
  OpenMPMutex* lock_;
153
  double* volume_;
154
  double* volume_t_;
155
  double* volume_sq_;
156
  double* volume_sq_t_;
157
  double* volume_naive_;
158
  int* position_recorded_;
159
  int* external_source_present_;
160
  Position* position_;
161
  Position* centroid_;
162
  Position* centroid_iteration_;
163
  Position* centroid_t_;
164
  MomentMatrix* mom_matrix_;
165
  MomentMatrix* mom_matrix_t_;
166
  // A set of volume tally tasks. This more complicated data structure is
167
  // convenient for ensuring that volumes are only tallied once per source
168
  // region, regardless of how many energy groups are used for tallying.
169
  std::unordered_set<TallyTask, TallyTask::HashFunctor>* volume_task_;
170

171
  // Mesh that subdivides this source region
172
  int* mesh_;
173
  int64_t* parent_sr_;
174

175
  // Energy group-wise 1D arrays
176
  double* scalar_flux_old_;
177
  double* scalar_flux_new_;
178
  float* source_;
179
  float* external_source_;
180
  double* scalar_flux_final_;
181

182
  MomentArray* source_gradients_;
183
  MomentArray* flux_moments_old_;
184
  MomentArray* flux_moments_new_;
185
  MomentArray* flux_moments_t_;
186

187
  // 2D array representing values for all energy groups x tally
188
  // tasks. Each group may have a different number of tally tasks
189
  // associated with it, necessitating the use of a jagged array.
190
  vector<TallyTask>* tally_task_;
191

192
  //----------------------------------------------------------------------------
193
  // Public Accessors
194

195
  int& material() { return *material_; }
196
  const int material() const { return *material_; }
1,971,618✔
197

198
  int& is_small() { return *is_small_; }
199
  const int is_small() const { return *is_small_; }
200

201
  int& n_hits() { return *n_hits_; }
202
  const int n_hits() const { return *n_hits_; }
203

204
  void lock() { lock_->lock(); }
205
  void unlock() { lock_->unlock(); }
206

207
  double& volume() { return *volume_; }
208
  const double volume() const { return *volume_; }
209

210
  double& volume_t() { return *volume_t_; }
211
  const double volume_t() const { return *volume_t_; }
212

213
  double& volume_sq() { return *volume_sq_; }
214
  const double volume_sq() const { return *volume_sq_; }
215

216
  double& volume_sq_t() { return *volume_sq_t_; }
217
  const double volume_sq_t() const { return *volume_sq_t_; }
218

219
  double& volume_naive() { return *volume_naive_; }
220
  const double volume_naive() const { return *volume_naive_; }
221

222
  int& position_recorded() { return *position_recorded_; }
223
  const int position_recorded() const { return *position_recorded_; }
224

225
  int& external_source_present() { return *external_source_present_; }
226
  const int external_source_present() const
1,941,863✔
227
  {
228
    return *external_source_present_;
1,941,863✔
229
  }
230

231
  Position& position() { return *position_; }
232
  const Position position() const { return *position_; }
233

234
  Position& centroid() { return *centroid_; }
235
  const Position centroid() const { return *centroid_; }
236

237
  Position& centroid_iteration() { return *centroid_iteration_; }
238
  const Position centroid_iteration() const { return *centroid_iteration_; }
239

240
  Position& centroid_t() { return *centroid_t_; }
241
  const Position centroid_t() const { return *centroid_t_; }
242

243
  MomentMatrix& mom_matrix() { return *mom_matrix_; }
244
  const MomentMatrix mom_matrix() const { return *mom_matrix_; }
245

246
  MomentMatrix& mom_matrix_t() { return *mom_matrix_t_; }
247
  const MomentMatrix mom_matrix_t() const { return *mom_matrix_t_; }
248

249
  std::unordered_set<TallyTask, TallyTask::HashFunctor>& volume_task()
250
  {
251
    return *volume_task_;
252
  }
253
  const std::unordered_set<TallyTask, TallyTask::HashFunctor>& volume_task()
254
    const
255
  {
256
    return *volume_task_;
257
  }
258

259
  int& mesh() { return *mesh_; }
260
  const int mesh() const { return *mesh_; }
1,971,618✔
261

262
  int64_t& parent_sr() { return *parent_sr_; }
263
  const int64_t parent_sr() const { return *parent_sr_; }
264

265
  double& scalar_flux_old(int g) { return scalar_flux_old_[g]; }
266
  const double scalar_flux_old(int g) const { return scalar_flux_old_[g]; }
2,156,484✔
267

268
  double& scalar_flux_new(int g) { return scalar_flux_new_[g]; }
269
  const double scalar_flux_new(int g) const { return scalar_flux_new_[g]; }
270

271
  double& scalar_flux_final(int g) { return scalar_flux_final_[g]; }
272
  const double scalar_flux_final(int g) const { return scalar_flux_final_[g]; }
273

274
  float& source(int g) { return source_[g]; }
275
  const float source(int g) const { return source_[g]; }
2,156,484✔
276

277
  float& external_source(int g) { return external_source_[g]; }
278
  const float external_source(int g) const { return external_source_[g]; }
1,941,863✔
279

280
  MomentArray& source_gradients(int g) { return source_gradients_[g]; }
281
  const MomentArray source_gradients(int g) const
282
  {
283
    return source_gradients_[g];
284
  }
285

286
  MomentArray& flux_moments_old(int g) { return flux_moments_old_[g]; }
287
  const MomentArray flux_moments_old(int g) const
288
  {
289
    return flux_moments_old_[g];
290
  }
291

292
  MomentArray& flux_moments_new(int g) { return flux_moments_new_[g]; }
293
  const MomentArray flux_moments_new(int g) const
294
  {
295
    return flux_moments_new_[g];
296
  }
297

298
  MomentArray& flux_moments_t(int g) { return flux_moments_t_[g]; }
299
  const MomentArray flux_moments_t(int g) const { return flux_moments_t_[g]; }
300

301
  vector<TallyTask>& tally_task(int g) { return tally_task_[g]; }
302
  const vector<TallyTask>& tally_task(int g) const { return tally_task_[g]; }
303

304
}; // class SourceRegionHandle
305

306
class SourceRegion {
307
public:
308
  //----------------------------------------------------------------------------
309
  // Constructors
310
  SourceRegion(int negroups, bool is_linear);
311
  SourceRegion(const SourceRegionHandle& handle, int64_t parent_sr);
312
  SourceRegion() = default;
313

314
  //----------------------------------------------------------------------------
315
  // Public Data members
316

317
  //---------------------------------------
318
  // Scalar fields
319

320
  int material_ {0}; //!< Index in openmc::model::materials array
321
  OpenMPMutex lock_;
322
  double volume_ {
323
    0.0}; //!< Volume (computed from the sum of ray crossing lengths)
324
  double volume_t_ {0.0};     //!< Volume totaled over all iterations
325
  double volume_sq_ {0.0};    //!< Volume squared
326
  double volume_sq_t_ {0.0};  //!< Volume squared totaled over all iterations
327
  double volume_naive_ {0.0}; //!< Volume as integrated from this iteration only
328
  int position_recorded_ {0}; //!< Has the position been recorded yet?
329
  int external_source_present_ {
330
    0};               //!< Is an external source present in this region?
331
  int is_small_ {0};  //!< Is it "small", receiving < 1.5 hits per iteration?
332
  int n_hits_ {0};    //!< Number of total hits (ray crossings)
333
                      // Mesh that subdivides this source region
334
  int mesh_ {C_NONE}; //!< Index in openmc::model::meshes array that subdivides
335
                      //!< this source region
336
  int64_t parent_sr_ {C_NONE}; //!< Index of a parent source region
337
  Position position_ {
338
    0.0, 0.0, 0.0}; //!< A position somewhere inside the region
339
  Position centroid_ {0.0, 0.0, 0.0}; //!< The centroid
340
  Position centroid_iteration_ {
341
    0.0, 0.0, 0.0}; //!< The centroid integrated from this iteration only
342
  Position centroid_t_ {
343
    0.0, 0.0, 0.0}; //!< The centroid accumulated over all iterations
344
  MomentMatrix mom_matrix_ {
345
    0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; //!< The spatial moment matrix
346
  MomentMatrix mom_matrix_t_ {0.0, 0.0, 0.0, 0.0, 0.0,
347
    0.0}; //!< The spatial moment matrix accumulated over all iterations
348

349
  // A set of volume tally tasks. This more complicated data structure is
350
  // convenient for ensuring that volumes are only tallied once per source
351
  // region, regardless of how many energy groups are used for tallying.
352
  std::unordered_set<TallyTask, TallyTask::HashFunctor> volume_task_;
353

354
  //---------------------------------------
355
  // Energy group-wise 1D arrays
356

357
  vector<double>
358
    scalar_flux_old_; //!< The scalar flux from the previous iteration
359
  vector<double>
360
    scalar_flux_new_; //!< The scalar flux from the current iteration
361
  vector<float>
362
    source_; //!< The total source term (fission + scattering + external)
363
  vector<float> external_source_;    //!< The external source term
364
  vector<double> scalar_flux_final_; //!< The scalar flux accumulated over all
365
                                     //!< active iterations (used for plotting,
366
                                     //!< or computing adjoint sources)
367

368
  vector<MomentArray> source_gradients_; //!< The linear source gradients
369
  vector<MomentArray>
370
    flux_moments_old_; //!< The linear flux moments from the previous iteration
371
  vector<MomentArray>
372
    flux_moments_new_; //!< The linear flux moments from the current iteration
373
  vector<MomentArray>
374
    flux_moments_t_; //!< The linear flux moments accumulated over all active
375
                     //!< iterations (used for plotting)
376

377
  //---------------------------------------
378
  // 2D array representing values for all energy groups x tally
379
  // tasks. Each group may have a different number of tally tasks
380
  // associated with it, necessitating the use of a jagged array.
381
  vector<vector<TallyTask>> tally_task_;
382
}; // class SourceRegion
383

384
class SourceRegionContainer {
385
public:
386
  //----------------------------------------------------------------------------
387
  // Constructors
388
  SourceRegionContainer(int negroups, bool is_linear)
389
    : negroups_(negroups), is_linear_(is_linear)
390
  {}
391
  SourceRegionContainer() = default;
392

393
  //----------------------------------------------------------------------------
394
  // Public Accessors
UNCOV
395
  int& material(int64_t sr) { return material_[sr]; }
×
396
  const int material(int64_t sr) const { return material_[sr]; }
397

UNCOV
398
  int& is_small(int64_t sr) { return is_small_[sr]; }
×
399
  const int is_small(int64_t sr) const { return is_small_[sr]; }
400

UNCOV
401
  int& n_hits(int64_t sr) { return n_hits_[sr]; }
×
402
  const int n_hits(int64_t sr) const { return n_hits_[sr]; }
403

404
  OpenMPMutex& lock(int64_t sr) { return lock_[sr]; }
1,196,648,324✔
405
  const OpenMPMutex& lock(int64_t sr) const { return lock_[sr]; }
406

UNCOV
407
  double& volume(int64_t sr) { return volume_[sr]; }
×
408
  const double volume(int64_t sr) const { return volume_[sr]; }
409

UNCOV
410
  double& volume_t(int64_t sr) { return volume_t_[sr]; }
×
411
  const double volume_t(int64_t sr) const { return volume_t_[sr]; }
412

UNCOV
413
  double& volume_sq(int64_t sr) { return volume_sq_[sr]; }
×
414
  const double volume_sq(int64_t sr) const { return volume_sq_[sr]; }
415

UNCOV
416
  double& volume_sq_t(int64_t sr) { return volume_sq_t_[sr]; }
×
417
  const double volume_sq_t(int64_t sr) const { return volume_sq_t_[sr]; }
418

UNCOV
419
  double& volume_naive(int64_t sr) { return volume_naive_[sr]; }
×
420
  const double volume_naive(int64_t sr) const { return volume_naive_[sr]; }
421

UNCOV
422
  int& position_recorded(int64_t sr) { return position_recorded_[sr]; }
×
423
  const int position_recorded(int64_t sr) const
424
  {
425
    return position_recorded_[sr];
426
  }
427

UNCOV
428
  int& external_source_present(int64_t sr)
×
429
  {
UNCOV
430
    return external_source_present_[sr];
×
431
  }
432
  const int external_source_present(int64_t sr) const
433
  {
434
    return external_source_present_[sr];
435
  }
436

UNCOV
437
  Position& position(int64_t sr) { return position_[sr]; }
×
438
  const Position position(int64_t sr) const { return position_[sr]; }
439

UNCOV
440
  Position& centroid(int64_t sr) { return centroid_[sr]; }
×
441
  const Position centroid(int64_t sr) const { return centroid_[sr]; }
442

UNCOV
443
  Position& centroid_iteration(int64_t sr) { return centroid_iteration_[sr]; }
×
444
  const Position centroid_iteration(int64_t sr) const
445
  {
446
    return centroid_iteration_[sr];
447
  }
448

UNCOV
449
  Position& centroid_t(int64_t sr) { return centroid_t_[sr]; }
×
450
  const Position centroid_t(int64_t sr) const { return centroid_t_[sr]; }
451

UNCOV
452
  MomentMatrix& mom_matrix(int64_t sr) { return mom_matrix_[sr]; }
×
453
  const MomentMatrix mom_matrix(int64_t sr) const { return mom_matrix_[sr]; }
454

UNCOV
455
  MomentMatrix& mom_matrix_t(int64_t sr) { return mom_matrix_t_[sr]; }
×
456
  const MomentMatrix mom_matrix_t(int64_t sr) const
457
  {
458
    return mom_matrix_t_[sr];
459
  }
460

UNCOV
461
  MomentArray& source_gradients(int64_t sr, int g)
×
462
  {
UNCOV
463
    return source_gradients_[index(sr, g)];
×
464
  }
465
  const MomentArray source_gradients(int64_t sr, int g) const
466
  {
467
    return source_gradients_[index(sr, g)];
468
  }
469
  MomentArray& source_gradients(int64_t se) { return source_gradients_[se]; }
470
  const MomentArray source_gradients(int64_t se) const
471
  {
472
    return source_gradients_[se];
473
  }
474

UNCOV
475
  MomentArray& flux_moments_old(int64_t sr, int g)
×
476
  {
UNCOV
477
    return flux_moments_old_[index(sr, g)];
×
478
  }
479
  const MomentArray flux_moments_old(int64_t sr, int g) const
480
  {
481
    return flux_moments_old_[index(sr, g)];
482
  }
483
  MomentArray& flux_moments_old(int64_t se) { return flux_moments_old_[se]; }
484
  const MomentArray flux_moments_old(int64_t se) const
485
  {
486
    return flux_moments_old_[se];
487
  }
488

UNCOV
489
  MomentArray& flux_moments_new(int64_t sr, int g)
×
490
  {
UNCOV
491
    return flux_moments_new_[index(sr, g)];
×
492
  }
493
  const MomentArray flux_moments_new(int64_t sr, int g) const
494
  {
495
    return flux_moments_new_[index(sr, g)];
496
  }
497
  MomentArray& flux_moments_new(int64_t se) { return flux_moments_new_[se]; }
498
  const MomentArray flux_moments_new(int64_t se) const
499
  {
500
    return flux_moments_new_[se];
501
  }
502

503
  MomentArray& flux_moments_t(int64_t sr, int g)
602,543,431✔
504
  {
505
    return flux_moments_t_[index(sr, g)];
602,543,431✔
506
  }
507
  const MomentArray flux_moments_t(int64_t sr, int g) const
508
  {
509
    return flux_moments_t_[index(sr, g)];
510
  }
511
  MomentArray& flux_moments_t(int64_t se) { return flux_moments_t_[se]; }
512
  const MomentArray flux_moments_t(int64_t se) const
513
  {
514
    return flux_moments_t_[se];
515
  }
516

UNCOV
517
  double& scalar_flux_old(int64_t sr, int g)
×
518
  {
UNCOV
519
    return scalar_flux_old_[index(sr, g)];
×
520
  }
521
  const double scalar_flux_old(int64_t sr, int g) const
522
  {
523
    return scalar_flux_old_[index(sr, g)];
524
  }
525
  double& scalar_flux_old(int64_t se) { return scalar_flux_old_[se]; }
526
  const double scalar_flux_old(int64_t se) const
527
  {
528
    return scalar_flux_old_[se];
529
  }
530

UNCOV
531
  double& scalar_flux_new(int64_t sr, int g)
×
532
  {
UNCOV
533
    return scalar_flux_new_[index(sr, g)];
×
534
  }
535
  const double scalar_flux_new(int64_t sr, int g) const
536
  {
537
    return scalar_flux_new_[index(sr, g)];
538
  }
539
  double& scalar_flux_new(int64_t se) { return scalar_flux_new_[se]; }
540
  const double scalar_flux_new(int64_t se) const
541
  {
542
    return scalar_flux_new_[se];
543
  }
544

545
  double& scalar_flux_final(int64_t sr, int g)
1,196,648,324✔
546
  {
547
    return scalar_flux_final_[index(sr, g)];
1,196,648,324✔
548
  }
549
  const double scalar_flux_final(int64_t sr, int g) const
550
  {
551
    return scalar_flux_final_[index(sr, g)];
552
  }
553
  double& scalar_flux_final(int64_t se) { return scalar_flux_final_[se]; }
554
  const double scalar_flux_final(int64_t se) const
555
  {
556
    return scalar_flux_final_[se];
557
  }
558

UNCOV
559
  float& source(int64_t sr, int g) { return source_[index(sr, g)]; }
×
560
  const float source(int64_t sr, int g) const { return source_[index(sr, g)]; }
561
  float& source(int64_t se) { return source_[se]; }
562
  const float source(int64_t se) const { return source_[se]; }
563

UNCOV
564
  float& external_source(int64_t sr, int g)
×
565
  {
UNCOV
566
    return external_source_[index(sr, g)];
×
567
  }
568
  const float external_source(int64_t sr, int g) const
569
  {
570
    return external_source_[index(sr, g)];
571
  }
572
  float& external_source(int64_t se) { return external_source_[se]; }
573
  const float external_source(int64_t se) const { return external_source_[se]; }
574

UNCOV
575
  vector<TallyTask>& tally_task(int64_t sr, int g)
×
576
  {
UNCOV
577
    return tally_task_[index(sr, g)];
×
578
  }
579
  const vector<TallyTask>& tally_task(int64_t sr, int g) const
580
  {
581
    return tally_task_[index(sr, g)];
582
  }
583
  vector<TallyTask>& tally_task(int64_t se) { return tally_task_[se]; }
584
  const vector<TallyTask>& tally_task(int64_t se) const
585
  {
586
    return tally_task_[se];
587
  }
588

UNCOV
589
  std::unordered_set<TallyTask, TallyTask::HashFunctor>& volume_task(int64_t sr)
×
590
  {
UNCOV
591
    return volume_task_[sr];
×
592
  }
593
  const std::unordered_set<TallyTask, TallyTask::HashFunctor>& volume_task(
594
    int64_t sr) const
595
  {
596
    return volume_task_[sr];
597
  }
598

UNCOV
599
  int& mesh(int64_t sr) { return mesh_[sr]; }
×
600
  const int mesh(int64_t sr) const { return mesh_[sr]; }
601

602
  int64_t& parent_sr(int64_t sr) { return parent_sr_[sr]; }
1,196,648,324✔
603
  const int64_t parent_sr(int64_t sr) const { return parent_sr_[sr]; }
604

605
  //----------------------------------------------------------------------------
606
  // Public Methods
607

608
  void push_back(const SourceRegion& sr);
609
  void assign(int n_source_regions, const SourceRegion& source_region);
610
  void flux_swap();
611
  int64_t n_source_regions() const { return n_source_regions_; }
612
  int64_t n_source_elements() const { return n_source_regions_ * negroups_; }
UNCOV
613
  int& negroups() { return negroups_; }
×
614
  const int negroups() const { return negroups_; }
UNCOV
615
  bool& is_linear() { return is_linear_; }
×
616
  const bool is_linear() const { return is_linear_; }
617
  SourceRegionHandle get_source_region_handle(int64_t sr);
618
  void adjoint_reset();
619

620
private:
621
  //----------------------------------------------------------------------------
622
  // Private Data Members
623
  int64_t n_source_regions_ {0};
624
  int negroups_ {0};
625
  bool is_linear_ {false};
626

627
  // SoA storage for scalar fields (one item per source region)
628
  vector<int> material_;
629
  vector<int> is_small_;
630
  vector<int> n_hits_;
631
  vector<int> mesh_;
632
  vector<int64_t> parent_sr_;
633
  vector<OpenMPMutex> lock_;
634
  vector<double> volume_;
635
  vector<double> volume_t_;
636
  vector<double> volume_sq_;
637
  vector<double> volume_sq_t_;
638
  vector<double> volume_naive_;
639
  vector<int> position_recorded_;
640
  vector<int> external_source_present_;
641
  vector<Position> position_;
642
  vector<Position> centroid_;
643
  vector<Position> centroid_iteration_;
644
  vector<Position> centroid_t_;
645
  vector<MomentMatrix> mom_matrix_;
646
  vector<MomentMatrix> mom_matrix_t_;
647
  // A set of volume tally tasks. This more complicated data structure is
648
  // convenient for ensuring that volumes are only tallied once per source
649
  // region, regardless of how many energy groups are used for tallying.
650
  vector<std::unordered_set<TallyTask, TallyTask::HashFunctor>> volume_task_;
651

652
  // SoA energy group-wise 2D arrays flattened to 1D
653
  vector<double> scalar_flux_old_;
654
  vector<double> scalar_flux_new_;
655
  vector<double> scalar_flux_final_;
656
  vector<float> source_;
657
  vector<float> external_source_;
658

659
  vector<MomentArray> source_gradients_;
660
  vector<MomentArray> flux_moments_old_;
661
  vector<MomentArray> flux_moments_new_;
662
  vector<MomentArray> flux_moments_t_;
663

664
  // SoA 3D array representing values for all source regions x energy groups x
665
  // tally tasks. The outer two dimensions (source regions and energy groups)
666
  // are flattened to 1D. Each group may have a different number of tally tasks
667
  // associated with it, necessitating the use of a jagged array for the inner
668
  // dimension.
669
  vector<vector<TallyTask>> tally_task_;
670

671
  //----------------------------------------------------------------------------
672
  // Private Methods
673

674
  // Helper function for indexing
675
  inline int index(int64_t sr, int g) const { return sr * negroups_ + g; }
676
};
677

678
} // namespace openmc
679

680
#endif // OPENMC_RANDOM_RAY_SOURCE_REGION_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