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

openmc-dev / openmc / 22110756672

17 Feb 2026 06:31PM UTC coverage: 81.831% (+0.1%) from 81.721%
22110756672

Pull #3813

github

web-flow
Merge 47dc7194f into 977ade79a
Pull Request #3813: Check for positive radii

17268 of 24298 branches covered (71.07%)

Branch coverage included in aggregate %.

16 of 16 new or added lines in 1 file covered. (100.0%)

1065 existing lines in 28 files now uncovered.

57520 of 67095 relevant lines covered (85.73%)

45595325.95 hits per line

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

72.45
/src/bank.cpp
1
#include "openmc/bank.h"
2
#include "openmc/capi.h"
3
#include "openmc/error.h"
4
#include "openmc/ifp.h"
5
#include "openmc/message_passing.h"
6
#include "openmc/simulation.h"
7
#include "openmc/vector.h"
8

9
#include <cstdint>
10
#include <numeric>
11

12
namespace openmc {
13

14
//==============================================================================
15
// Global variables
16
//==============================================================================
17

18
namespace simulation {
19

20
vector<SourceSite> source_bank;
21

22
SharedArray<SourceSite> surf_source_bank;
23

24
SharedArray<CollisionTrackSite> collision_track_bank;
25

26
// The fission bank is allocated as a SharedArray, rather than a vector, as it
27
// will be shared by all threads in the simulation. It will be allocated to a
28
// fixed maximum capacity in the init_fission_bank() function. Then, Elements
29
// will be added to it by using SharedArray's special thread_safe_append()
30
// function.
31
SharedArray<SourceSite> fission_bank;
32

33
vector<vector<int>> ifp_source_delayed_group_bank;
34

35
vector<vector<double>> ifp_source_lifetime_bank;
36

37
vector<vector<int>> ifp_fission_delayed_group_bank;
38

39
vector<vector<double>> ifp_fission_lifetime_bank;
40

41
// Each entry in this vector corresponds to the number of progeny produced
42
// this generation for the particle located at that index. This vector is
43
// used to efficiently sort the fission bank after each iteration.
44
vector<int64_t> progeny_per_particle;
45

46
} // namespace simulation
47

48
//==============================================================================
49
// Non-member functions
50
//==============================================================================
51

52
void free_memory_bank()
7,505✔
53
{
54
  simulation::source_bank.clear();
7,505✔
55
  simulation::surf_source_bank.clear();
7,505✔
56
  simulation::collision_track_bank.clear();
7,505✔
57
  simulation::fission_bank.clear();
7,505✔
58
  simulation::progeny_per_particle.clear();
7,505✔
59
  simulation::ifp_source_delayed_group_bank.clear();
7,505✔
60
  simulation::ifp_source_lifetime_bank.clear();
7,505✔
61
  simulation::ifp_fission_delayed_group_bank.clear();
7,505✔
62
  simulation::ifp_fission_lifetime_bank.clear();
7,505✔
63
}
7,505✔
64

65
void init_fission_bank(int64_t max)
3,588✔
66
{
67
  simulation::fission_bank.reserve(max);
3,588✔
68
  simulation::progeny_per_particle.resize(simulation::work_per_rank);
3,588✔
69
}
3,588✔
70

71
// Performs an O(n) sort on the fission bank, by leveraging
72
// the parent_id and progeny_id fields of banked particles. See the following
73
// paper for more details:
74
// "Reproducibility and Monte Carlo Eigenvalue Calculations," F.B. Brown and
75
// T.M. Sutton, 1992 ANS Annual Meeting, Transactions of the American Nuclear
76
// Society, Volume 65, Page 235.
77
void sort_fission_bank()
78,880✔
78
{
79
  // Ensure we don't read off the end of the array if we ran with 0 particles
80
  if (simulation::progeny_per_particle.size() == 0) {
78,880!
UNCOV
81
    return;
×
82
  }
83

84
  // Perform exclusive scan summation to determine starting indices in fission
85
  // bank for each parent particle id
86
  std::exclusive_scan(simulation::progeny_per_particle.begin(),
78,880✔
87
    simulation::progeny_per_particle.end(),
88
    simulation::progeny_per_particle.begin(), 0);
89

90
  // We need a scratch vector to make permutation of the fission bank into
91
  // sorted order easy. Under normal usage conditions, the fission bank is
92
  // over provisioned, so we can use that as scratch space.
93
  SourceSite* sorted_bank;
94
  vector<SourceSite> sorted_bank_holder;
78,880✔
95
  vector<vector<int>> sorted_ifp_delayed_group_bank;
78,880✔
96
  vector<vector<double>> sorted_ifp_lifetime_bank;
78,880✔
97

98
  // If there is not enough space, allocate a temporary vector and point to it
99
  if (simulation::fission_bank.size() >
78,880✔
100
      simulation::fission_bank.capacity() / 2) {
78,880✔
101
    sorted_bank_holder.resize(simulation::fission_bank.size());
1,016✔
102
    sorted_bank = sorted_bank_holder.data();
1,016✔
103
  } else { // otherwise, point sorted_bank to unused portion of the fission bank
104
    sorted_bank = &simulation::fission_bank[simulation::fission_bank.size()];
77,864✔
105
  }
106

107
  if (settings::ifp_on) {
78,880✔
108
    allocate_temporary_vector_ifp(
1,360✔
109
      sorted_ifp_delayed_group_bank, sorted_ifp_lifetime_bank);
110
  }
111

112
  // Use parent and progeny indices to sort fission bank
113
  for (int64_t i = 0; i < simulation::fission_bank.size(); i++) {
128,562,714✔
114
    const auto& site = simulation::fission_bank[i];
128,483,834✔
115
    int64_t offset = site.parent_id - 1 - simulation::work_index[mpi::rank];
128,483,834✔
116
    int64_t idx = simulation::progeny_per_particle[offset] + site.progeny_id;
128,483,834✔
117
    if (idx >= simulation::fission_bank.size()) {
128,483,834!
UNCOV
118
      fatal_error("Mismatch detected between sum of all particle progeny and "
×
119
                  "shared fission bank size.");
120
    }
121
    sorted_bank[idx] = site;
128,483,834✔
122
    if (settings::ifp_on) {
128,483,834✔
123
      copy_ifp_data_from_fission_banks(
1,229,660✔
124
        i, sorted_ifp_delayed_group_bank[idx], sorted_ifp_lifetime_bank[idx]);
1,229,660✔
125
    }
126
  }
127

128
  // Copy sorted bank into the fission bank
129
  std::copy(sorted_bank, sorted_bank + simulation::fission_bank.size(),
78,880✔
130
    simulation::fission_bank.data());
131
  if (settings::ifp_on) {
78,880✔
132
    copy_ifp_data_to_fission_banks(
1,360✔
133
      sorted_ifp_delayed_group_bank.data(), sorted_ifp_lifetime_bank.data());
1,360✔
134
  }
135
}
78,880✔
136

137
//==============================================================================
138
// C API
139
//==============================================================================
140

141
extern "C" int openmc_source_bank(void** ptr, int64_t* n)
10✔
142
{
143
  if (!ptr || !n) {
10!
144
    set_errmsg("Received null pointer.");
×
UNCOV
145
    return OPENMC_E_INVALID_ARGUMENT;
×
146
  }
147

148
  if (simulation::source_bank.size() == 0) {
10!
149
    set_errmsg("Source bank has not been allocated.");
×
UNCOV
150
    return OPENMC_E_ALLOCATE;
×
151
  } else {
152
    *ptr = simulation::source_bank.data();
10✔
153
    *n = simulation::source_bank.size();
10✔
154
    return 0;
10✔
155
  }
156
}
157

UNCOV
158
extern "C" int openmc_fission_bank(void** ptr, int64_t* n)
×
159
{
160
  if (!ptr || !n) {
×
161
    set_errmsg("Received null pointer.");
×
UNCOV
162
    return OPENMC_E_INVALID_ARGUMENT;
×
163
  }
164

165
  if (simulation::fission_bank.size() == 0) {
×
166
    set_errmsg("Fission bank has not been allocated.");
×
UNCOV
167
    return OPENMC_E_ALLOCATE;
×
168
  } else {
169
    *ptr = simulation::fission_bank.data();
×
170
    *n = simulation::fission_bank.size();
×
UNCOV
171
    return 0;
×
172
  }
173
}
174

175
} // namespace openmc
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