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

openmc-dev / openmc / 14260484407

04 Apr 2025 07:41AM UTC coverage: 84.589% (-0.3%) from 84.851%
14260484407

Pull #3279

github

web-flow
Merge 33e03305e into 07f533461
Pull Request #3279: Hexagonal mesh model

2 of 332 new or added lines in 3 files covered. (0.6%)

2798 existing lines in 84 files now uncovered.

51799 of 61236 relevant lines covered (84.59%)

38650400.15 hits per line

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

80.58
/src/tallies/filter_mesh.cpp
1
#include "openmc/tallies/filter_mesh.h"
2

3
#include <fmt/core.h>
4

5
#include "openmc/capi.h"
6
#include "openmc/constants.h"
7
#include "openmc/error.h"
8
#include "openmc/mesh.h"
9
#include "openmc/xml_interface.h"
10

11
namespace openmc {
12

13
void MeshFilter::from_xml(pugi::xml_node node)
2,059✔
14
{
15
  auto bins_ = get_node_array<int32_t>(node, "bins");
2,059✔
16
  if (bins_.size() != 1) {
2,059✔
UNCOV
17
    fatal_error(
×
18
      "Only one mesh can be specified per " + type_str() + " mesh filter.");
×
19
  }
20

21
  auto id = bins_[0];
2,059✔
22
  auto search = model::mesh_map.find(id);
2,059✔
23
  if (search != model::mesh_map.end()) {
2,059✔
24
    set_mesh(search->second);
2,059✔
25
  } else {
UNCOV
26
    fatal_error(
×
27
      fmt::format("Could not find mesh {} specified on tally filter.", id));
×
28
  }
29

30
  if (check_for_node(node, "translation")) {
2,059✔
31
    set_translation(get_node_array<double>(node, "translation"));
32✔
32
  }
33
}
2,059✔
34

35
void MeshFilter::get_all_bins(
462,748,346✔
36
  const Particle& p, TallyEstimator estimator, FilterMatch& match) const
37
{
38

39
  Position last_r = p.r_last();
462,748,346✔
40
  Position r = p.r();
462,748,346✔
41
  Position u = p.u();
462,748,346✔
42

43
  // apply translation if present
44
  if (translated_) {
462,748,346✔
45
    last_r -= translation();
757,438✔
46
    r -= translation();
757,438✔
47
  }
48

49
  if (estimator != TallyEstimator::TRACKLENGTH) {
462,748,346✔
50
    auto bin = model::meshes[mesh_]->get_bin(r);
115,108,348✔
51
    if (bin >= 0) {
115,108,348✔
52
      match.bins_.push_back(bin);
93,302,687✔
53
      match.weights_.push_back(1.0);
93,302,687✔
54
    }
55
  } else {
56
    model::meshes[mesh_]->bins_crossed(
347,639,998✔
57
      last_r, r, u, match.bins_, match.weights_);
347,639,998✔
58
  }
59
}
462,748,346✔
60

61
void MeshFilter::to_statepoint(hid_t filter_group) const
2,377✔
62
{
63
  Filter::to_statepoint(filter_group);
2,377✔
64
  write_dataset(filter_group, "bins", model::meshes[mesh_]->id_);
2,377✔
65
  if (translated_) {
2,377✔
66
    write_dataset(filter_group, "translation", translation_);
22✔
67
  }
68
}
2,377✔
69

70
std::string MeshFilter::text_label(int bin) const
5,325,857✔
71
{
72
  auto& mesh = *model::meshes.at(mesh_);
5,325,857✔
73
  std::string label = mesh.bin_label(bin);
5,325,857✔
74
  return label;
5,325,857✔
75
}
76

77
void MeshFilter::set_mesh(int32_t mesh)
2,209✔
78
{
79
  // perform any additional perparation for mesh tallies here
80
  mesh_ = mesh;
2,209✔
81
  n_bins_ = model::meshes[mesh_]->n_bins();
2,209✔
82
  model::meshes[mesh_]->prepare_for_point_location();
2,209✔
83
}
2,209✔
84

85
void MeshFilter::set_translation(const Position& translation)
54✔
86
{
87
  translated_ = true;
54✔
88
  translation_ = translation;
54✔
89
}
54✔
90

91
void MeshFilter::set_translation(const double translation[3])
22✔
92
{
93
  this->set_translation({translation[0], translation[1], translation[2]});
22✔
94
}
22✔
95

96
//==============================================================================
97
// C-API functions
98
//==============================================================================
99

100
extern "C" int openmc_mesh_filter_get_mesh(int32_t index, int32_t* index_mesh)
536✔
101
{
102
  if (!index_mesh) {
536✔
UNCOV
103
    set_errmsg("Mesh index argument is a null pointer.");
×
104
    return OPENMC_E_INVALID_ARGUMENT;
×
105
  }
106

107
  // Make sure this is a valid index to an allocated filter.
108
  if (int err = verify_filter(index))
536✔
UNCOV
109
    return err;
×
110

111
  // Get a pointer to the filter and downcast.
112
  const auto& filt_base = model::tally_filters[index].get();
536✔
113
  auto* filt = dynamic_cast<MeshFilter*>(filt_base);
536✔
114

115
  // Check the filter type.
116
  if (!filt) {
536✔
UNCOV
117
    set_errmsg("Tried to get mesh on a non-mesh filter.");
×
118
    return OPENMC_E_INVALID_TYPE;
×
119
  }
120

121
  // Output the mesh.
122
  *index_mesh = filt->mesh();
536✔
123
  return 0;
536✔
124
}
125

126
extern "C" int openmc_mesh_filter_set_mesh(int32_t index, int32_t index_mesh)
548✔
127
{
128
  // Make sure this is a valid index to an allocated filter.
129
  if (int err = verify_filter(index))
548✔
UNCOV
130
    return err;
×
131

132
  // Get a pointer to the filter and downcast.
133
  const auto& filt_base = model::tally_filters[index].get();
548✔
134
  auto* filt = dynamic_cast<MeshFilter*>(filt_base);
548✔
135

136
  // Check the filter type.
137
  if (!filt) {
548✔
UNCOV
138
    set_errmsg("Tried to set mesh on a non-mesh filter.");
×
139
    return OPENMC_E_INVALID_TYPE;
×
140
  }
141

142
  // Check the mesh index.
143
  if (index_mesh < 0 || index_mesh >= model::meshes.size()) {
548✔
UNCOV
144
    set_errmsg("Index in 'meshes' array is out of bounds.");
×
145
    return OPENMC_E_OUT_OF_BOUNDS;
×
146
  }
147

148
  // Update the filter.
149
  filt->set_mesh(index_mesh);
548✔
150
  return 0;
548✔
151
}
152

153
extern "C" int openmc_mesh_filter_get_translation(
22✔
154
  int32_t index, double translation[3])
155
{
156
  // Make sure this is a valid index to an allocated filter
157
  if (int err = verify_filter(index))
22✔
UNCOV
158
    return err;
×
159

160
  // Check the filter type
161
  const auto& filter = model::tally_filters[index];
22✔
162
  if (filter->type() != FilterType::MESH &&
22✔
163
      filter->type() != FilterType::MESHBORN &&
33✔
164
      filter->type() != FilterType::MESH_SURFACE) {
11✔
UNCOV
165
    set_errmsg("Tried to get a translation from a non-mesh-based filter.");
×
166
    return OPENMC_E_INVALID_TYPE;
×
167
  }
168

169
  // Get translation from the mesh filter and set value
170
  auto mesh_filter = dynamic_cast<MeshFilter*>(filter.get());
22✔
171
  const auto& t = mesh_filter->translation();
22✔
172
  for (int i = 0; i < 3; i++) {
88✔
173
    translation[i] = t[i];
66✔
174
  }
175

176
  return 0;
22✔
177
}
178

179
extern "C" int openmc_mesh_filter_set_translation(
22✔
180
  int32_t index, double translation[3])
181
{
182
  // Make sure this is a valid index to an allocated filter
183
  if (int err = verify_filter(index))
22✔
UNCOV
184
    return err;
×
185

186
  const auto& filter = model::tally_filters[index];
22✔
187
  // Check the filter type
188
  if (filter->type() != FilterType::MESH &&
22✔
189
      filter->type() != FilterType::MESHBORN &&
33✔
190
      filter->type() != FilterType::MESH_SURFACE) {
11✔
UNCOV
191
    set_errmsg("Tried to set mesh on a non-mesh-based filter.");
×
192
    return OPENMC_E_INVALID_TYPE;
×
193
  }
194

195
  // Get a pointer to the filter and downcast
196
  auto mesh_filter = dynamic_cast<MeshFilter*>(filter.get());
22✔
197

198
  // Set the translation
199
  mesh_filter->set_translation(translation);
22✔
200

201
  return 0;
22✔
202
}
203

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