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

openmc-dev / openmc / 19851502091

02 Dec 2025 08:05AM UTC coverage: 82.016% (+0.1%) from 81.872%
19851502091

Pull #3413

github

web-flow
Merge d7a168452 into ef22558f4
Pull Request #3413: More interpolation types in Tabular.

16946 of 23531 branches covered (72.02%)

Branch coverage included in aggregate %.

68 of 107 new or added lines in 3 files covered. (63.55%)

1391 existing lines in 31 files now uncovered.

54939 of 64116 relevant lines covered (85.69%)

42115001.1 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

11
namespace openmc {
12

13
//==============================================================================
14
// Global variables
15
//==============================================================================
16

17
namespace simulation {
18

19
vector<SourceSite> source_bank;
20

21
SharedArray<SourceSite> surf_source_bank;
22

23
SharedArray<CollisionTrackSite> collision_track_bank;
24

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

32
vector<vector<int>> ifp_source_delayed_group_bank;
33

34
vector<vector<double>> ifp_source_lifetime_bank;
35

36
vector<vector<int>> ifp_fission_delayed_group_bank;
37

38
vector<vector<double>> ifp_fission_lifetime_bank;
39

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

45
} // namespace simulation
46

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

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

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

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

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

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

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

106
  if (settings::ifp_on) {
83,193✔
107
    allocate_temporary_vector_ifp(
1,520✔
108
      sorted_ifp_delayed_group_bank, sorted_ifp_lifetime_bank);
109
  }
110

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

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

136
//==============================================================================
137
// C API
138
//==============================================================================
139

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

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

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

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

174
} // 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