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

openmc-dev / openmc / 13183515203

06 Feb 2025 04:36PM UTC coverage: 82.601% (-2.3%) from 84.867%
13183515203

Pull #3087

github

web-flow
Merge d68c72d5e into 6e0f156d3
Pull Request #3087: wheel building with scikit build core

107123 of 129687 relevant lines covered (82.6%)

12608333.34 hits per line

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

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

8
#include <cstdint>
9

10
namespace openmc {
11

12
//==============================================================================
13
// Global variables
14
//==============================================================================
15

16
namespace simulation {
17

18
vector<SourceSite> source_bank;
19

20
SharedArray<SourceSite> surf_source_bank;
21

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

29
// Each entry in this vector corresponds to the number of progeny produced
30
// this generation for the particle located at that index. This vector is
31
// used to efficiently sort the fission bank after each iteration.
32
vector<int64_t> progeny_per_particle;
33

34
} // namespace simulation
35

36
//==============================================================================
37
// Non-member functions
38
//==============================================================================
39

40
void free_memory_bank()
5,426✔
41
{
42
  simulation::source_bank.clear();
5,426✔
43
  simulation::surf_source_bank.clear();
5,426✔
44
  simulation::fission_bank.clear();
5,426✔
45
  simulation::progeny_per_particle.clear();
5,426✔
46
}
5,426✔
47

48
void init_fission_bank(int64_t max)
3,122✔
49
{
50
  simulation::fission_bank.reserve(max);
3,122✔
51
  simulation::progeny_per_particle.resize(simulation::work_per_rank);
3,122✔
52
}
3,122✔
53

54
// Performs an O(n) sort on the fission bank, by leveraging
55
// the parent_id and progeny_id fields of banked particles. See the following
56
// paper for more details:
57
// "Reproducibility and Monte Carlo Eigenvalue Calculations," F.B. Brown and
58
// T.M. Sutton, 1992 ANS Annual Meeting, Transactions of the American Nuclear
59
// Society, Volume 65, Page 235.
60
void sort_fission_bank()
62,440✔
61
{
62
  // Ensure we don't read off the end of the array if we ran with 0 particles
63
  if (simulation::progeny_per_particle.size() == 0) {
62,440✔
64
    return;
×
65
  }
66

67
  // Perform exclusive scan summation to determine starting indices in fission
68
  // bank for each parent particle id
69
  int64_t tmp = simulation::progeny_per_particle[0];
62,440✔
70
  simulation::progeny_per_particle[0] = 0;
62,440✔
71
  for (int64_t i = 1; i < simulation::progeny_per_particle.size(); i++) {
137,339,800✔
72
    int64_t value = simulation::progeny_per_particle[i - 1] + tmp;
137,277,360✔
73
    tmp = simulation::progeny_per_particle[i];
137,277,360✔
74
    simulation::progeny_per_particle[i] = value;
137,277,360✔
75
  }
76

77
  // TODO: C++17 introduces the exclusive_scan() function which could be
78
  // used to replace everything above this point in this function.
79

80
  // We need a scratch vector to make permutation of the fission bank into
81
  // sorted order easy. Under normal usage conditions, the fission bank is
82
  // over provisioned, so we can use that as scratch space.
83
  SourceSite* sorted_bank;
84
  vector<SourceSite> sorted_bank_holder;
62,440✔
85

86
  // If there is not enough space, allocate a temporary vector and point to it
87
  if (simulation::fission_bank.size() >
62,440✔
88
      simulation::fission_bank.capacity() / 2) {
62,440✔
89
    sorted_bank_holder.resize(simulation::fission_bank.size());
605✔
90
    sorted_bank = sorted_bank_holder.data();
605✔
91
  } else { // otherwise, point sorted_bank to unused portion of the fission bank
92
    sorted_bank = &simulation::fission_bank[simulation::fission_bank.size()];
61,835✔
93
  }
94

95
  // Use parent and progeny indices to sort fission bank
96
  for (int64_t i = 0; i < simulation::fission_bank.size(); i++) {
137,274,605✔
97
    const auto& site = simulation::fission_bank[i];
137,212,165✔
98
    int64_t offset = site.parent_id - 1 - simulation::work_index[mpi::rank];
137,212,165✔
99
    int64_t idx = simulation::progeny_per_particle[offset] + site.progeny_id;
137,212,165✔
100
    if (idx >= simulation::fission_bank.size()) {
137,212,165✔
101
      fatal_error("Mismatch detected between sum of all particle progeny and "
×
102
                  "shared fission bank size.");
103
    }
104
    sorted_bank[idx] = site;
137,212,165✔
105
  }
106

107
  // Copy sorted bank into the fission bank
108
  std::copy(sorted_bank, sorted_bank + simulation::fission_bank.size(),
62,440✔
109
    simulation::fission_bank.data());
110
}
62,440✔
111

112
//==============================================================================
113
// C API
114
//==============================================================================
115

116
extern "C" int openmc_source_bank(void** ptr, int64_t* n)
×
117
{
118
  if (!ptr || !n) {
×
119
    set_errmsg("Received null pointer.");
×
120
    return OPENMC_E_INVALID_ARGUMENT;
×
121
  }
122

123
  if (simulation::source_bank.size() == 0) {
×
124
    set_errmsg("Source bank has not been allocated.");
×
125
    return OPENMC_E_ALLOCATE;
×
126
  } else {
127
    *ptr = simulation::source_bank.data();
×
128
    *n = simulation::source_bank.size();
×
129
    return 0;
×
130
  }
131
}
132

133
extern "C" int openmc_fission_bank(void** ptr, int64_t* n)
×
134
{
135
  if (!ptr || !n) {
×
136
    set_errmsg("Received null pointer.");
×
137
    return OPENMC_E_INVALID_ARGUMENT;
×
138
  }
139

140
  if (simulation::fission_bank.size() == 0) {
×
141
    set_errmsg("Fission bank has not been allocated.");
×
142
    return OPENMC_E_ALLOCATE;
×
143
  } else {
144
    *ptr = simulation::fission_bank.data();
×
145
    *n = simulation::fission_bank.size();
×
146
    return 0;
×
147
  }
148
}
149

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