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

openmc-dev / openmc / 13591584831

28 Feb 2025 03:46PM UTC coverage: 85.051% (+0.3%) from 84.722%
13591584831

Pull #3067

github

web-flow
Merge 08055e996 into c26fde666
Pull Request #3067: Implement user-configurable random number stride

36 of 44 new or added lines in 8 files covered. (81.82%)

3588 existing lines in 111 files now uncovered.

51062 of 60037 relevant lines covered (85.05%)

32650986.73 hits per line

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

85.71
/src/tallies/filter.cpp
1
#include "openmc/tallies/filter.h"
2

3
#include <algorithm> // for max
4
#include <cassert>
5
#include <cstring> // for strcpy
6
#include <string>
7

8
#include <fmt/core.h>
9

10
#include "openmc/capi.h"
11
#include "openmc/constants.h" // for MAX_LINE_LEN;
12
#include "openmc/error.h"
13
#include "openmc/tallies/filter_azimuthal.h"
14
#include "openmc/tallies/filter_cell.h"
15
#include "openmc/tallies/filter_cell_instance.h"
16
#include "openmc/tallies/filter_cellborn.h"
17
#include "openmc/tallies/filter_cellfrom.h"
18
#include "openmc/tallies/filter_collision.h"
19
#include "openmc/tallies/filter_delayedgroup.h"
20
#include "openmc/tallies/filter_distribcell.h"
21
#include "openmc/tallies/filter_energy.h"
22
#include "openmc/tallies/filter_energyfunc.h"
23
#include "openmc/tallies/filter_legendre.h"
24
#include "openmc/tallies/filter_material.h"
25
#include "openmc/tallies/filter_materialfrom.h"
26
#include "openmc/tallies/filter_mesh.h"
27
#include "openmc/tallies/filter_meshborn.h"
28
#include "openmc/tallies/filter_meshsurface.h"
29
#include "openmc/tallies/filter_mu.h"
30
#include "openmc/tallies/filter_musurface.h"
31
#include "openmc/tallies/filter_parent_nuclide.h"
32
#include "openmc/tallies/filter_particle.h"
33
#include "openmc/tallies/filter_polar.h"
34
#include "openmc/tallies/filter_sph_harm.h"
35
#include "openmc/tallies/filter_sptl_legendre.h"
36
#include "openmc/tallies/filter_surface.h"
37
#include "openmc/tallies/filter_time.h"
38
#include "openmc/tallies/filter_universe.h"
39
#include "openmc/tallies/filter_zernike.h"
40
#include "openmc/xml_interface.h"
41

42
// explicit template instantiation definition
43
template class openmc::vector<openmc::FilterMatch>;
44

45
namespace openmc {
46

47
//==============================================================================
48
// Global variables
49
//==============================================================================
50

51
namespace model {
52
std::unordered_map<int, int> filter_map;
53
vector<unique_ptr<Filter>> tally_filters;
54
} // namespace model
55

56
//==============================================================================
57
// Non-member functions
58
//==============================================================================
59

60
extern "C" size_t tally_filters_size()
1,233✔
61
{
62
  return model::tally_filters.size();
1,233✔
63
}
64

65
//==============================================================================
66
// Filter implementation
67
//==============================================================================
68

69
Filter::Filter()
8,914✔
70
{
71
  index_ = model::tally_filters.size(); // Avoids warning about narrowing
8,914✔
72
}
8,914✔
73

74
Filter::~Filter()
8,914✔
75
{
76
  model::filter_map.erase(id_);
8,914✔
77
}
8,914✔
UNCOV
78

×
79
Filter* Filter::create(pugi::xml_node node)
80
{
81
  // Copy filter id
82
  if (!check_for_node(node, "id")) {
8,914✔
83
    fatal_error("Must specify id for filter in tally XML file.");
84
  }
8,914✔
85
  int filter_id = std::stoi(get_node_value(node, "id"));
8,914✔
86

87
  // Convert filter type to lower case
7,492✔
88
  std::string s;
89
  if (check_for_node(node, "type")) {
90
    s = get_node_value(node, "type", true);
7,492✔
UNCOV
91
  }
×
92

93
  // Allocate according to the filter type
7,492✔
94
  auto f = Filter::create(s, filter_id);
95

96
  // Read filter data from XML
7,492✔
97
  f->from_xml(node);
7,492✔
98
  return f;
7,492✔
99
}
100

101
Filter* Filter::create(const std::string& type, int32_t id)
102
{
7,492✔
103
  if (type == "azimuthal") {
104
    return Filter::create<AzimuthalFilter>(id);
105
  } else if (type == "cell") {
7,492✔
106
    return Filter::create<CellFilter>(id);
7,492✔
107
  } else if (type == "cellborn") {
7,492✔
108
    return Filter::create<CellBornFilter>(id);
109
  } else if (type == "cellfrom") {
8,897✔
110
    return Filter::create<CellFromFilter>(id);
111
  } else if (type == "cellinstance") {
8,897✔
112
    return Filter::create<CellInstanceFilter>(id);
34✔
113
  } else if (type == "distribcell") {
8,863✔
114
    return Filter::create<DistribcellFilter>(id);
788✔
115
  } else if (type == "delayedgroup") {
8,075✔
116
    return Filter::create<DelayedGroupFilter>(id);
17✔
117
  } else if (type == "energyfunction") {
8,058✔
118
    return Filter::create<EnergyFunctionFilter>(id);
86✔
119
  } else if (type == "energy") {
7,972✔
120
    return Filter::create<EnergyFilter>(id);
36✔
121
  } else if (type == "collision") {
7,936✔
122
    return Filter::create<CollisionFilter>(id);
189✔
123
  } else if (type == "energyout") {
7,747✔
124
    return Filter::create<EnergyoutFilter>(id);
102✔
125
  } else if (type == "legendre") {
7,645✔
126
    return Filter::create<LegendreFilter>(id);
220✔
127
  } else if (type == "material") {
7,425✔
128
    return Filter::create<MaterialFilter>(id);
1,210✔
129
  } else if (type == "materialfrom") {
6,215✔
130
    return Filter::create<MaterialFromFilter>(id);
17✔
131
  } else if (type == "mesh") {
6,198✔
132
    return Filter::create<MeshFilter>(id);
368✔
133
  } else if (type == "meshborn") {
5,830✔
134
    return Filter::create<MeshBornFilter>(id);
530✔
135
  } else if (type == "meshsurface") {
5,300✔
136
    return Filter::create<MeshSurfaceFilter>(id);
1,765✔
137
  } else if (type == "mu") {
3,535✔
138
    return Filter::create<MuFilter>(id);
17✔
139
  } else if (type == "musurface") {
3,518✔
140
    return Filter::create<MuSurfaceFilter>(id);
2,273✔
141
  } else if (type == "parentnuclide") {
1,245✔
142
    return Filter::create<ParentNuclideFilter>(id);
29✔
143
  } else if (type == "particle") {
1,216✔
144
    return Filter::create<ParticleFilter>(id);
413✔
145
  } else if (type == "polar") {
803✔
146
    return Filter::create<PolarFilter>(id);
34✔
147
  } else if (type == "surface") {
769✔
148
    return Filter::create<SurfaceFilter>(id);
29✔
149
  } else if (type == "spatiallegendre") {
740✔
150
    return Filter::create<SpatialLegendreFilter>(id);
12✔
151
  } else if (type == "sphericalharmonics") {
728✔
152
    return Filter::create<SphericalHarmonicsFilter>(id);
359✔
153
  } else if (type == "time") {
369✔
154
    return Filter::create<TimeFilter>(id);
35✔
155
  } else if (type == "universe") {
334✔
156
    return Filter::create<UniverseFilter>(id);
139✔
157
  } else if (type == "zernike") {
195✔
158
    return Filter::create<ZernikeFilter>(id);
12✔
159
  } else if (type == "zernikeradial") {
183✔
160
    return Filter::create<ZernikeRadialFilter>(id);
41✔
161
  } else {
142✔
162
    throw std::runtime_error {fmt::format("Unknown filter type: {}", type)};
77✔
163
  }
65✔
164
  return nullptr;
17✔
165
}
48✔
166

48✔
UNCOV
167
void Filter::set_id(int32_t id)
×
UNCOV
168
{
×
169
  assert(id >= 0 || id == C_NONE);
UNCOV
170

×
171
  // Clear entry in filter map if an ID was already assigned before
172
  if (id_ != C_NONE) {
173
    model::filter_map.erase(id_);
174
    id_ = C_NONE;
175
  }
10,147✔
176

177
  // Make sure no other filter has same ID
8,285✔
178
  if (model::filter_map.find(id) != model::filter_map.end()) {
179
    throw std::runtime_error {
180
      "Two filters have the same ID: " + std::to_string(id)};
10,147✔
181
  }
1,233✔
182

1,233✔
183
  // If no ID specified, auto-assign next ID in sequence
184
  if (id == C_NONE) {
185
    id = 0;
186
    for (const auto& f : model::tally_filters) {
10,147✔
UNCOV
187
      id = std::max(id, f->id_);
×
UNCOV
188
    }
×
189
    ++id;
190
  }
191

192
  // Update ID and entry in filter map
10,147✔
193
  id_ = id;
1,422✔
194
  model::filter_map[id] = index_;
7,189✔
195
}
5,767✔
196

197
//==============================================================================
1,422✔
198
// C API functions
199
//==============================================================================
200

201
int verify_filter(int32_t index)
10,147✔
202
{
10,147✔
203
  if (index < 0 || index >= model::tally_filters.size()) {
10,147✔
204
    set_errmsg("Filter index is out of bounds.");
205
    return OPENMC_E_OUT_OF_BOUNDS;
206
  }
207
  return 0;
208
}
209

22,060✔
210
extern "C" int openmc_filter_get_id(int32_t index, int32_t* id)
211
{
22,060✔
UNCOV
212
  if (int err = verify_filter(index))
×
UNCOV
213
    return err;
×
214

215
  *id = model::tally_filters[index]->id();
22,060✔
216
  return 0;
217
}
218

11,397✔
219
extern "C" int openmc_filter_set_id(int32_t index, int32_t id)
220
{
11,397✔
UNCOV
221
  if (int err = verify_filter(index))
×
222
    return err;
223

11,397✔
224
  model::tally_filters[index]->set_id(id);
11,397✔
225
  return 0;
226
}
227

1,233✔
228
extern "C" int openmc_filter_get_type(int32_t index, char* type)
229
{
1,233✔
UNCOV
230
  if (int err = verify_filter(index))
×
231
    return err;
232

1,233✔
233
  std::strcpy(type, model::tally_filters[index]->type_str().c_str());
1,233✔
234
  return 0;
235
}
236

6,240✔
237
extern "C" int openmc_filter_get_num_bins(int32_t index, int* n_bins)
238
{
6,240✔
UNCOV
239
  if (int err = verify_filter(index))
×
240
    return err;
241

6,240✔
242
  *n_bins = model::tally_filters[index]->n_bins();
6,240✔
243
  return 0;
244
}
245

144✔
246
extern "C" int openmc_get_filter_index(int32_t id, int32_t* index)
247
{
144✔
UNCOV
248
  auto it = model::filter_map.find(id);
×
249
  if (it == model::filter_map.end()) {
250
    set_errmsg("No filter exists with ID=" + std::to_string(id) + ".");
144✔
251
    return OPENMC_E_INVALID_ID;
144✔
252
  }
253

254
  *index = it->second;
12✔
255
  return 0;
256
}
12✔
257

12✔
UNCOV
258
extern "C" void openmc_get_filter_next_id(int32_t* id)
×
259
{
×
260
  int32_t largest_filter_id = 0;
261
  for (const auto& t : model::tally_filters) {
262
    largest_filter_id = std::max(largest_filter_id, t->id());
12✔
263
  }
12✔
264
  *id = largest_filter_id + 1;
265
}
UNCOV
266

×
267
extern "C" int openmc_new_filter(const char* type, int32_t* index)
UNCOV
268
{
×
UNCOV
269
  *index = model::tally_filters.size();
×
UNCOV
270
  Filter::create(type);
×
271
  return 0;
UNCOV
272
}
×
273

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