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

openmc-dev / openmc / 13461947318

21 Feb 2025 05:24PM UTC coverage: 85.019% (+0.05%) from 84.969%
13461947318

Pull #3140

github

web-flow
Merge ece247ada into 2b788ea6e
Pull Request #3140: Add Versioning Support from `version.txt`

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

1293 existing lines in 43 files now uncovered.

50627 of 59548 relevant lines covered (85.02%)

35584918.67 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()
2,031✔
60
{
61
  return model::tally_filters.size();
2,031✔
62
}
63

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

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

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

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

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

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

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

100
Filter* Filter::create(const std::string& type, int32_t id)
101
{
7,594✔
102
  if (type == "azimuthal") {
103
    return Filter::create<AzimuthalFilter>(id);
104
  } else if (type == "cell") {
7,594✔
105
    return Filter::create<CellFilter>(id);
7,594✔
106
  } else if (type == "cellborn") {
7,594✔
107
    return Filter::create<CellBornFilter>(id);
108
  } else if (type == "cellfrom") {
9,797✔
109
    return Filter::create<CellFromFilter>(id);
110
  } else if (type == "cellinstance") {
9,797✔
111
    return Filter::create<CellInstanceFilter>(id);
34✔
112
  } else if (type == "distribcell") {
9,763✔
113
    return Filter::create<DistribcellFilter>(id);
788✔
114
  } else if (type == "delayedgroup") {
8,975✔
115
    return Filter::create<DelayedGroupFilter>(id);
17✔
116
  } else if (type == "energyfunction") {
8,958✔
117
    return Filter::create<EnergyFunctionFilter>(id);
86✔
118
  } else if (type == "energy") {
8,872✔
119
    return Filter::create<EnergyFilter>(id);
36✔
120
  } else if (type == "collision") {
8,836✔
121
    return Filter::create<CollisionFilter>(id);
189✔
122
  } else if (type == "energyout") {
8,647✔
123
    return Filter::create<EnergyoutFilter>(id);
102✔
124
  } else if (type == "legendre") {
8,545✔
125
    return Filter::create<LegendreFilter>(id);
220✔
126
  } else if (type == "material") {
8,325✔
127
    return Filter::create<MaterialFilter>(id);
1,226✔
128
  } else if (type == "materialfrom") {
7,099✔
129
    return Filter::create<MaterialFromFilter>(id);
17✔
130
  } else if (type == "mesh") {
7,082✔
131
    return Filter::create<MeshFilter>(id);
396✔
132
  } else if (type == "meshborn") {
6,686✔
133
    return Filter::create<MeshBornFilter>(id);
740✔
134
  } else if (type == "meshsurface") {
5,946✔
135
    return Filter::create<MeshSurfaceFilter>(id);
1,877✔
136
  } else if (type == "mu") {
4,069✔
137
    return Filter::create<MuFilter>(id);
17✔
138
  } else if (type == "musurface") {
4,052✔
139
    return Filter::create<MuSurfaceFilter>(id);
2,621✔
140
  } else if (type == "particle") {
1,431✔
141
    return Filter::create<ParticleFilter>(id);
29✔
142
  } else if (type == "polar") {
1,402✔
143
    return Filter::create<PolarFilter>(id);
623✔
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,845✔
173

174
  // Make sure no other filter has same ID
9,743✔
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,845✔
178
  }
2,031✔
179

2,031✔
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,845✔
184
      id = std::max(id, f->id_);
×
UNCOV
185
    }
×
186
    ++id;
187
  }
188

189
  // Update ID and entry in filter map
11,845✔
190
  id_ = id;
2,220✔
191
  model::filter_map[id] = index_;
10,297✔
192
}
8,077✔
193

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

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

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

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

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

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

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

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

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

7,692✔
239
  *n_bins = model::tally_filters[index]->n_bins();
7,692✔
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