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

openmc-dev / openmc / 20278515727

16 Dec 2025 06:26PM UTC coverage: 81.822% (-0.1%) from 81.92%
20278515727

Pull #3493

github

web-flow
Merge 7f36869a3 into bbfa18d72
Pull Request #3493: Implement vector fitting to replace external `vectfit` package

17013 of 23575 branches covered (72.17%)

Branch coverage included in aggregate %.

188 of 207 new or added lines in 3 files covered. (90.82%)

3101 existing lines in 56 files now uncovered.

54973 of 64404 relevant lines covered (85.36%)

41385524.25 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()
6,899✔
52
{
53
  simulation::source_bank.clear();
6,899✔
54
  simulation::surf_source_bank.clear();
6,899✔
55
  simulation::collision_track_bank.clear();
6,899✔
56
  simulation::fission_bank.clear();
6,899✔
57
  simulation::progeny_per_particle.clear();
6,899✔
58
  simulation::ifp_source_delayed_group_bank.clear();
6,899✔
59
  simulation::ifp_source_lifetime_bank.clear();
6,899✔
60
  simulation::ifp_fission_delayed_group_bank.clear();
6,899✔
61
  simulation::ifp_fission_lifetime_bank.clear();
6,899✔
62
}
6,899✔
63

64
void init_fission_bank(int64_t max)
3,450✔
65
{
66
  simulation::fission_bank.reserve(max);
3,450✔
67
  simulation::progeny_per_particle.resize(simulation::work_per_rank);
3,450✔
68
}
3,450✔
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()
72,142✔
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) {
72,142!
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(),
72,142✔
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;
72,142✔
94
  vector<vector<int>> sorted_ifp_delayed_group_bank;
72,142✔
95
  vector<vector<double>> sorted_ifp_lifetime_bank;
72,142✔
96

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

106
  if (settings::ifp_on) {
72,142✔
107
    allocate_temporary_vector_ifp(
1,360✔
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++) {
127,315,413✔
113
    const auto& site = simulation::fission_bank[i];
127,243,271✔
114
    int64_t offset = site.parent_id - 1 - simulation::work_index[mpi::rank];
127,243,271✔
115
    int64_t idx = simulation::progeny_per_particle[offset] + site.progeny_id;
127,243,271✔
116
    if (idx >= simulation::fission_bank.size()) {
127,243,271!
UNCOV
117
      fatal_error("Mismatch detected between sum of all particle progeny and "
×
118
                  "shared fission bank size.");
119
    }
120
    sorted_bank[idx] = site;
127,243,271✔
121
    if (settings::ifp_on) {
127,243,271✔
122
      copy_ifp_data_from_fission_banks(
1,229,660✔
123
        i, sorted_ifp_delayed_group_bank[idx], sorted_ifp_lifetime_bank[idx]);
1,229,660✔
124
    }
125
  }
126

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

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

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

147
  if (simulation::source_bank.size() == 0) {
10!
UNCOV
148
    set_errmsg("Source bank has not been allocated.");
×
UNCOV
149
    return OPENMC_E_ALLOCATE;
×
150
  } else {
151
    *ptr = simulation::source_bank.data();
10✔
152
    *n = simulation::source_bank.size();
10✔
153
    return 0;
10✔
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

© 2025 Coveralls, Inc