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

openmc-dev / openmc / 8705531778

16 Apr 2024 12:23PM UTC coverage: 84.842% (+0.2%) from 84.639%
8705531778

Pull #2693

github

web-flow
Merge 75ca1f251 into 2974d53b3
Pull Request #2693: Add reactivity control to coupled transport-depletion analyses

328 of 389 new or added lines in 5 files covered. (84.32%)

815 existing lines in 28 files now uncovered.

48199 of 56810 relevant lines covered (84.84%)

43871786.95 hits per line

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

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

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

7
#include <fmt/core.h>
8

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

39
// explicit template instantiation definition
40
template class openmc::vector<openmc::FilterMatch>;
41

42
namespace openmc {
43

44
//==============================================================================
45
// Global variables
46
//==============================================================================
47

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

53
//==============================================================================
54
// Non-member functions
55
//==============================================================================
56

57
extern "C" size_t tally_filters_size()
1,888✔
58
{
59
  return model::tally_filters.size();
1,888✔
60
}
61

62
//==============================================================================
63
// Filter implementation
64
//==============================================================================
65

66
Filter::Filter()
8,861✔
67
{
68
  index_ = model::tally_filters.size(); // Avoids warning about narrowing
8,861✔
69
}
8,861✔
70

71
Filter::~Filter()
8,861✔
72
{
73
  model::filter_map.erase(id_);
8,861✔
74
}
8,861✔
UNCOV
75

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

84
  // Convert filter type to lower case
6,841✔
85
  std::string s;
86
  if (check_for_node(node, "type")) {
87
    s = get_node_value(node, "type", true);
6,841✔
UNCOV
88
  }
×
89

90
  // Allocate according to the filter type
6,841✔
91
  auto f = Filter::create(s, filter_id);
92

93
  // Read filter data from XML
6,841✔
94
  f->from_xml(node);
6,841✔
95
  return f;
6,841✔
96
}
97

98
Filter* Filter::create(const std::string& type, int32_t id)
99
{
6,841✔
100
  if (type == "azimuthal") {
101
    return Filter::create<AzimuthalFilter>(id);
102
  } else if (type == "cell") {
6,841✔
103
    return Filter::create<CellFilter>(id);
6,841✔
104
  } else if (type == "cellborn") {
6,841✔
105
    return Filter::create<CellBornFilter>(id);
106
  } else if (type == "cellfrom") {
8,842✔
107
    return Filter::create<CellFromFilter>(id);
108
  } else if (type == "cellinstance") {
8,842✔
109
    return Filter::create<CellInstanceFilter>(id);
38✔
110
  } else if (type == "distribcell") {
8,804✔
111
    return Filter::create<DistribcellFilter>(id);
698✔
112
  } else if (type == "delayedgroup") {
8,106✔
113
    return Filter::create<DelayedGroupFilter>(id);
19✔
114
  } else if (type == "energyfunction") {
8,087✔
115
    return Filter::create<EnergyFunctionFilter>(id);
20✔
116
  } else if (type == "energy") {
8,067✔
117
    return Filter::create<EnergyFilter>(id);
38✔
118
  } else if (type == "collision") {
8,029✔
119
    return Filter::create<CollisionFilter>(id);
185✔
120
  } else if (type == "energyout") {
7,844✔
121
    return Filter::create<EnergyoutFilter>(id);
114✔
122
  } else if (type == "legendre") {
7,730✔
123
    return Filter::create<LegendreFilter>(id);
250✔
124
  } else if (type == "material") {
7,480✔
125
    return Filter::create<MaterialFilter>(id);
1,182✔
126
  } else if (type == "materialfrom") {
6,298✔
127
    return Filter::create<MaterialFromFilter>(id);
19✔
128
  } else if (type == "mesh") {
6,279✔
129
    return Filter::create<MeshFilter>(id);
426✔
130
  } else if (type == "meshborn") {
5,853✔
131
    return Filter::create<MeshBornFilter>(id);
705✔
132
  } else if (type == "meshsurface") {
5,148✔
133
    return Filter::create<MeshSurfaceFilter>(id);
1,258✔
134
  } else if (type == "mu") {
3,890✔
135
    return Filter::create<MuFilter>(id);
19✔
136
  } else if (type == "particle") {
3,871✔
137
    return Filter::create<ParticleFilter>(id);
2,484✔
138
  } else if (type == "polar") {
1,387✔
139
    return Filter::create<PolarFilter>(id);
33✔
140
  } else if (type == "surface") {
1,354✔
141
    return Filter::create<SurfaceFilter>(id);
576✔
142
  } else if (type == "spatiallegendre") {
778✔
143
    return Filter::create<SpatialLegendreFilter>(id);
38✔
144
  } else if (type == "sphericalharmonics") {
740✔
145
    return Filter::create<SphericalHarmonicsFilter>(id);
352✔
146
  } else if (type == "time") {
388✔
147
    return Filter::create<TimeFilter>(id);
39✔
148
  } else if (type == "universe") {
349✔
149
    return Filter::create<UniverseFilter>(id);
124✔
150
  } else if (type == "zernike") {
225✔
151
    return Filter::create<ZernikeFilter>(id);
14✔
152
  } else if (type == "zernikeradial") {
211✔
153
    return Filter::create<ZernikeRadialFilter>(id);
47✔
154
  } else {
164✔
155
    throw std::runtime_error {fmt::format("Unknown filter type: {}", type)};
89✔
156
  }
75✔
157
  return nullptr;
19✔
158
}
56✔
159

56✔
160
void Filter::set_id(int32_t id)
×
UNCOV
161
{
×
162
  Expects(id >= 0 || id == C_NONE);
UNCOV
163

×
164
  // Clear entry in filter map if an ID was already assigned before
165
  if (id_ != C_NONE) {
166
    model::filter_map.erase(id_);
167
    id_ = C_NONE;
168
  }
10,749✔
169

170
  // Make sure no other filter has same ID
10,749✔
171
  if (model::filter_map.find(id) != model::filter_map.end()) {
172
    throw std::runtime_error {
173
      "Two filters have the same ID: " + std::to_string(id)};
10,749✔
174
  }
1,888✔
175

1,888✔
176
  // If no ID specified, auto-assign next ID in sequence
177
  if (id == C_NONE) {
178
    id = 0;
179
    for (const auto& f : model::tally_filters) {
10,749✔
UNCOV
180
      id = std::max(id, f->id_);
×
UNCOV
181
    }
×
182
    ++id;
183
  }
184

185
  // Update ID and entry in filter map
10,749✔
186
  id_ = id;
2,020✔
187
  model::filter_map[id] = index_;
9,539✔
188
}
7,519✔
189

190
//==============================================================================
2,020✔
191
// C API functions
192
//==============================================================================
193

194
int verify_filter(int32_t index)
10,749✔
195
{
10,749✔
196
  if (index < 0 || index >= model::tally_filters.size()) {
10,749✔
197
    set_errmsg("Filter index is out of bounds.");
198
    return OPENMC_E_OUT_OF_BOUNDS;
199
  }
200
  return 0;
201
}
202

29,012✔
203
extern "C" int openmc_filter_get_id(int32_t index, int32_t* id)
204
{
29,012✔
UNCOV
205
  if (int err = verify_filter(index))
×
UNCOV
206
    return err;
×
207

208
  *id = model::tally_filters[index]->id();
29,012✔
209
  return 0;
210
}
211

15,110✔
212
extern "C" int openmc_filter_set_id(int32_t index, int32_t id)
213
{
15,110✔
UNCOV
214
  if (int err = verify_filter(index))
×
215
    return err;
216

15,110✔
217
  model::tally_filters[index]->set_id(id);
15,110✔
218
  return 0;
219
}
220

1,888✔
221
extern "C" int openmc_filter_get_type(int32_t index, char* type)
222
{
1,888✔
UNCOV
223
  if (int err = verify_filter(index))
×
224
    return err;
225

1,888✔
226
  std::strcpy(type, model::tally_filters[index]->type_str().c_str());
1,888✔
227
  return 0;
228
}
229

7,906✔
230
extern "C" int openmc_filter_get_num_bins(int32_t index, int* n_bins)
231
{
7,906✔
UNCOV
232
  if (int err = verify_filter(index))
×
233
    return err;
234

7,906✔
235
  *n_bins = model::tally_filters[index]->n_bins();
7,906✔
236
  return 0;
237
}
238

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

247
  *index = it->second;
14✔
248
  return 0;
249
}
14✔
250

14✔
UNCOV
251
extern "C" void openmc_get_filter_next_id(int32_t* id)
×
UNCOV
252
{
×
253
  int32_t largest_filter_id = 0;
254
  for (const auto& t : model::tally_filters) {
255
    largest_filter_id = std::max(largest_filter_id, t->id());
14✔
256
  }
14✔
257
  *id = largest_filter_id + 1;
258
}
259

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

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