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

openmc-dev / openmc / 13443476914

20 Feb 2025 07:49PM UTC coverage: 85.022% (+0.05%) from 84.969%
13443476914

Pull #3140

github

web-flow
Merge 8ddcb065a into 7638661fa
Pull Request #3140: Add Versioning Support from `version.txt`

8 of 8 new or added lines in 2 files covered. (100.0%)

1242 existing lines in 42 files now uncovered.

50634 of 59554 relevant lines covered (85.02%)

35434881.25 hits per line

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

85.51
/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_particle.h"
32
#include "openmc/tallies/filter_polar.h"
33
#include "openmc/tallies/filter_sph_harm.h"
34
#include "openmc/tallies/filter_sptl_legendre.h"
35
#include "openmc/tallies/filter_surface.h"
36
#include "openmc/tallies/filter_time.h"
37
#include "openmc/tallies/filter_universe.h"
38
#include "openmc/tallies/filter_zernike.h"
39
#include "openmc/xml_interface.h"
40

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

44
namespace openmc {
45

46
//==============================================================================
47
// Global variables
48
//==============================================================================
49

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

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

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

64
//==============================================================================
65
// Filter implementation
66
//==============================================================================
67

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

73
Filter::~Filter()
9,735✔
74
{
75
  model::filter_map.erase(id_);
9,735✔
76
}
9,735✔
UNCOV
77

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

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

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

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

100
Filter* Filter::create(const std::string& type, int32_t id)
101
{
7,579✔
102
  if (type == "azimuthal") {
103
    return Filter::create<AzimuthalFilter>(id);
104
  } else if (type == "cell") {
7,579✔
105
    return Filter::create<CellFilter>(id);
7,579✔
106
  } else if (type == "cellborn") {
7,579✔
107
    return Filter::create<CellBornFilter>(id);
108
  } else if (type == "cellfrom") {
9,718✔
109
    return Filter::create<CellFromFilter>(id);
110
  } else if (type == "cellinstance") {
9,718✔
111
    return Filter::create<CellInstanceFilter>(id);
34✔
112
  } else if (type == "distribcell") {
9,684✔
113
    return Filter::create<DistribcellFilter>(id);
788✔
114
  } else if (type == "delayedgroup") {
8,896✔
115
    return Filter::create<DelayedGroupFilter>(id);
17✔
116
  } else if (type == "energyfunction") {
8,879✔
117
    return Filter::create<EnergyFunctionFilter>(id);
86✔
118
  } else if (type == "energy") {
8,793✔
119
    return Filter::create<EnergyFilter>(id);
36✔
120
  } else if (type == "collision") {
8,757✔
121
    return Filter::create<CollisionFilter>(id);
189✔
122
  } else if (type == "energyout") {
8,568✔
123
    return Filter::create<EnergyoutFilter>(id);
102✔
124
  } else if (type == "legendre") {
8,466✔
125
    return Filter::create<LegendreFilter>(id);
220✔
126
  } else if (type == "material") {
8,246✔
127
    return Filter::create<MaterialFilter>(id);
1,224✔
128
  } else if (type == "materialfrom") {
7,022✔
129
    return Filter::create<MaterialFromFilter>(id);
17✔
130
  } else if (type == "mesh") {
7,005✔
131
    return Filter::create<MeshFilter>(id);
394✔
132
  } else if (type == "meshborn") {
6,611✔
133
    return Filter::create<MeshBornFilter>(id);
725✔
134
  } else if (type == "meshsurface") {
5,886✔
135
    return Filter::create<MeshSurfaceFilter>(id);
1,862✔
136
  } else if (type == "mu") {
4,024✔
137
    return Filter::create<MuFilter>(id);
17✔
138
  } else if (type == "musurface") {
4,007✔
139
    return Filter::create<MuSurfaceFilter>(id);
2,591✔
140
  } else if (type == "particle") {
1,416✔
141
    return Filter::create<ParticleFilter>(id);
29✔
142
  } else if (type == "polar") {
1,387✔
143
    return Filter::create<PolarFilter>(id);
608✔
144
  } else if (type == "surface") {
779✔
145
    return Filter::create<SurfaceFilter>(id);
34✔
146
  } else if (type == "spatiallegendre") {
745✔
147
    return Filter::create<SpatialLegendreFilter>(id);
29✔
148
  } else if (type == "sphericalharmonics") {
716✔
149
    return Filter::create<SphericalHarmonicsFilter>(id);
347✔
150
  } else if (type == "time") {
369✔
151
    return Filter::create<TimeFilter>(id);
35✔
152
  } else if (type == "universe") {
334✔
153
    return Filter::create<UniverseFilter>(id);
139✔
154
  } else if (type == "zernike") {
195✔
155
    return Filter::create<ZernikeFilter>(id);
12✔
156
  } else if (type == "zernikeradial") {
183✔
157
    return Filter::create<ZernikeRadialFilter>(id);
41✔
158
  } else {
142✔
159
    throw std::runtime_error {fmt::format("Unknown filter type: {}", type)};
77✔
160
  }
65✔
161
  return nullptr;
17✔
162
}
48✔
163

48✔
164
void Filter::set_id(int32_t id)
×
UNCOV
165
{
×
166
  assert(id >= 0 || id == C_NONE);
UNCOV
167

×
168
  // Clear entry in filter map if an ID was already assigned before
169
  if (id_ != C_NONE) {
170
    model::filter_map.erase(id_);
171
    id_ = C_NONE;
172
  }
11,702✔
173

174
  // Make sure no other filter has same ID
9,858✔
175
  if (model::filter_map.find(id) != model::filter_map.end()) {
176
    throw std::runtime_error {
177
      "Two filters have the same ID: " + std::to_string(id)};
11,702✔
178
  }
1,967✔
179

1,967✔
180
  // If no ID specified, auto-assign next ID in sequence
181
  if (id == C_NONE) {
182
    id = 0;
183
    for (const auto& f : model::tally_filters) {
11,702✔
184
      id = std::max(id, f->id_);
×
UNCOV
185
    }
×
186
    ++id;
187
  }
188

189
  // Update ID and entry in filter map
11,702✔
190
  id_ = id;
2,156✔
191
  model::filter_map[id] = index_;
10,061✔
192
}
7,905✔
193

194
//==============================================================================
2,156✔
195
// C API functions
196
//==============================================================================
197

198
int verify_filter(int32_t index)
11,702✔
199
{
11,702✔
200
  if (index < 0 || index >= model::tally_filters.size()) {
11,702✔
201
    set_errmsg("Filter index is out of bounds.");
202
    return OPENMC_E_OUT_OF_BOUNDS;
203
  }
204
  return 0;
205
}
206

28,489✔
207
extern "C" int openmc_filter_get_id(int32_t index, int32_t* id)
208
{
28,489✔
209
  if (int err = verify_filter(index))
×
UNCOV
210
    return err;
×
211

212
  *id = model::tally_filters[index]->id();
28,489✔
213
  return 0;
214
}
215

14,879✔
216
extern "C" int openmc_filter_set_id(int32_t index, int32_t id)
217
{
14,879✔
UNCOV
218
  if (int err = verify_filter(index))
×
219
    return err;
220

14,879✔
221
  model::tally_filters[index]->set_id(id);
14,879✔
222
  return 0;
223
}
224

1,967✔
225
extern "C" int openmc_filter_get_type(int32_t index, char* type)
226
{
1,967✔
UNCOV
227
  if (int err = verify_filter(index))
×
228
    return err;
229

1,967✔
230
  std::strcpy(type, model::tally_filters[index]->type_str().c_str());
1,967✔
231
  return 0;
232
}
233

7,584✔
234
extern "C" int openmc_filter_get_num_bins(int32_t index, int* n_bins)
235
{
7,584✔
UNCOV
236
  if (int err = verify_filter(index))
×
237
    return err;
238

7,584✔
239
  *n_bins = model::tally_filters[index]->n_bins();
7,584✔
240
  return 0;
241
}
242

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

251
  *index = it->second;
12✔
252
  return 0;
253
}
12✔
254

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

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

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