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

openmc-dev / openmc / 23266050270

18 Mar 2026 08:42PM UTC coverage: 81.284% (-0.2%) from 81.447%
23266050270

Pull #3889

github

web-flow
Merge 1584b9380 into 3ce6cbfdd
Pull Request #3889: `XDGMesh` Object

17613 of 25446 branches covered (69.22%)

Branch coverage included in aggregate %.

171 of 331 new or added lines in 11 files covered. (51.66%)

1 existing line in 1 file now uncovered.

58228 of 67858 relevant lines covered (85.81%)

46439984.53 hits per line

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

31.89
/src/xdg.cpp
1
#include <algorithm>
2
#include <fstream>
3
#include <sstream>
4
#include <string>
5

6
#include "openmc/xdg.h"
7

8
#include "openmc/constants.h"
9
#include "openmc/container_util.h"
10
#include "openmc/error.h"
11
#include "openmc/file_utils.h"
12
#include "openmc/geometry.h"
13
#include "openmc/geometry_aux.h"
14
#include "openmc/hdf5_interface.h"
15
#include "openmc/material.h"
16
#include "openmc/settings.h"
17
#include "openmc/string_utils.h"
18

19
#include <fmt/core.h>
20

21
#ifdef OPENMC_XDG_ENABLED
22
#include "xdg/xdg.h"
23
#endif
24

25
namespace openmc {
26

27
#ifdef OPENMC_XDG_ENABLED
28
const bool XDG_ENABLED = true;
29
#else
30
const bool XDG_ENABLED = false;
31
#endif
32

33
} // namespace openmc
34

35
#ifdef OPENMC_XDG_ENABLED
36

37
namespace openmc {
38

39
//==============================================================================
40
// XDG Mesh implementation
41
//==============================================================================
42

43
const std::string XDGMesh::mesh_lib_type = "xdg";
44

45
XDGMesh::XDGMesh(pugi::xml_node node) : UnstructuredMesh(node)
8✔
46
{
47
  std::string mesh_lib = get_node_value(node, "library", true, true);
8✔
48
  if (mesh_lib == "moab") {
8!
NEW
49
    mesh_library_ = xdg::MeshLibrary::MOAB;
×
50
  } else if (mesh_lib == "libmesh") {
8!
51
    mesh_library_ = xdg::MeshLibrary::LIBMESH;
8✔
52
  }
53
  initialize();
8✔
54
}
8!
55

NEW
56
XDGMesh::XDGMesh(hid_t group) : UnstructuredMesh(group)
×
57
{
NEW
58
  std::string mesh_lib;
×
NEW
59
  read_dataset(group, "library", mesh_lib);
×
NEW
60
  if (mesh_lib == "moab") {
×
NEW
61
    mesh_library_ = xdg::MeshLibrary::MOAB;
×
NEW
62
  } else if (mesh_lib == "libmesh") {
×
NEW
63
    mesh_library_ = xdg::MeshLibrary::LIBMESH;
×
64
  }
NEW
65
  initialize();
×
NEW
66
}
×
67

NEW
68
XDGMesh::XDGMesh(const std::string& filename, double length_multiplier)
×
69
{
NEW
70
  filename_ = filename;
×
NEW
71
  set_length_multiplier(length_multiplier);
×
NEW
72
  initialize();
×
NEW
73
}
×
74

NEW
75
XDGMesh::XDGMesh(std::shared_ptr<xdg::XDG> external_xdg)
×
76
{
NEW
77
  xdg_ = external_xdg;
×
NEW
78
  filename_ = "unknown (external file)";
×
NEW
79
  initialize();
×
NEW
80
}
×
81

82
void XDGMesh::initialize()
8✔
83
{
84
  if (xdg_)
8!
85
    return;
86

87
  // create XDGMesh instance
88
  xdg_ = xdg::XDG::create(mesh_library_);
8!
89

90
  // load XDGMesh file
91
  if (!file_exists(filename_)) {
8!
NEW
92
    fatal_error(fmt::format("Mesh file \"{}\" does not exist", filename_));
×
93
  }
94

95
  xdg_->mesh_manager()->load_file(filename_);
8✔
96
  xdg_->mesh_manager()->init();
8✔
97
  xdg_->mesh_manager()->parse_metadata();
8✔
98
}
99

100
void XDGMesh::prepare_for_point_location()
8✔
101
{
102
  xdg_->prepare_raytracer();
8✔
103
}
8✔
104

NEW
105
Position XDGMesh::sample_element(int32_t bin, uint64_t* seed) const
×
106
{
107
  // MeshIDs are 1-indexed, so we add 1 to the bin, which is 0-indexed
NEW
108
  auto vertices = xdg_->mesh_manager()->element_vertices(bin_to_mesh_id(bin));
×
NEW
109
  return this->sample_tet<xdg::Vertex>(vertices, seed);
×
NEW
110
}
×
111

NEW
112
void XDGMesh::bins_crossed(Position r0, Position r1, const Direction& u,
×
113
  vector<int>& bins, vector<double>& lengths) const
114
{
115
  // TODO: Make more robust (including mesh entrance/re-entrance)
NEW
116
  xdg::Position p0 {r0.x, r0.y, r0.z};
×
NEW
117
  xdg::Position p1 {r1.x, r1.y, r1.z};
×
NEW
118
  double length_rcp = 1 / (p1 - p0).length();
×
NEW
119
  auto track_segments = xdg_->segments(p0, p1);
×
120
  // remove elements with lengths of zero
NEW
121
  track_segments.erase(
×
NEW
122
    std::remove_if(track_segments.begin(), track_segments.end(),
×
NEW
123
      [](const std::pair<xdg::MeshID, double>& p) { return p.second == 0.0; }),
×
NEW
124
    track_segments.end());
×
NEW
125
  for (const auto& track_segment : track_segments) {
×
NEW
126
    bins.push_back(mesh_id_to_bin(track_segment.first));
×
NEW
127
    lengths.push_back(track_segment.second * length_rcp);
×
128
  }
NEW
129
}
×
130

131
int XDGMesh::get_bin(Position r) const
2,140,232✔
132
{
133
  xdg::Position p {r.x, r.y, r.z};
2,140,232✔
134
  return mesh_id_to_bin(xdg_->find_element(p));
2,140,232✔
135
}
136

137
int XDGMesh::n_bins() const
95,904✔
138
{
139
  return xdg_->mesh_manager()->num_volume_elements();
95,904✔
140
}
141

NEW
142
int XDGMesh::n_surface_bins() const
×
143
{
NEW
144
  return 4 * n_bins();
×
145
}
146

NEW
147
std::pair<vector<double>, vector<double>> XDGMesh::plot(
×
148
  Position plot_ll, Position plot_ur) const
149
{
NEW
150
  fatal_error("Plot of XDGMesh mesh not implemented");
×
151
  return {};
152
}
153

154
std::string XDGMesh::library() const
16✔
155
{
156
  return mesh_lib_type;
16✔
157
}
158

NEW
159
std::string XDGMesh::mesh_library() const
×
160
{
NEW
161
  if (mesh_library_ == xdg::MeshLibrary::LIBMESH) {
×
NEW
162
    return "libmesh";
×
NEW
163
  } else if (mesh_library_ == xdg::MeshLibrary::MOAB) {
×
NEW
164
    return "moab";
×
165
  }
166
}
167

168
void XDGMesh::write(const std::string& base_filename) const
8✔
169
{
170
  warning("XDGMesh mesh write from C++ not implemented");
8✔
171
}
8✔
172

NEW
173
Position XDGMesh::centroid(int bin) const
×
174
{
NEW
175
  auto element_vertices =
×
NEW
176
    xdg_->mesh_manager()->element_vertices(bin_to_mesh_id(bin));
×
177

NEW
178
  xdg::Vertex centroid {0.0, 0.0, 0.0};
×
NEW
179
  for (const auto& v : element_vertices) {
×
NEW
180
    centroid += v;
×
181
  }
182

NEW
183
  centroid /= double(element_vertices.size());
×
184

NEW
185
  return {centroid[0], centroid[1], centroid[1]};
×
NEW
186
}
×
187

188
int XDGMesh::n_vertices() const
18,648✔
189
{
190
  return xdg_->mesh_manager()->num_vertices();
18,648✔
191
}
192

193
Position XDGMesh::vertex(int id) const
18,632✔
194
{
195
  xdg::MeshID mesh_id = xdg_->mesh_manager()->vertex_id(id);
18,632✔
196
  auto v = xdg_->mesh_manager()->vertex_coordinates(mesh_id);
18,632✔
197
  return {v[0], v[1], v[2]};
18,632✔
198
}
199

200
std::vector<int> XDGMesh::connectivity(int id) const
95,856✔
201
{
202
  auto conn = xdg_->mesh_manager()->element_connectivity(bin_to_mesh_id(id));
95,856✔
203
  for (auto& c : conn) {
479,280✔
204
    c = xdg_->mesh_manager()->vertex_index(c);
383,424✔
205
  }
206
  return conn;
95,856✔
NEW
207
}
×
208

209
double XDGMesh::volume(int bin) const
191,712✔
210
{
211
  return xdg_->mesh_manager()->element_volume(bin_to_mesh_id(bin));
191,712✔
212
}
213

214
xdg::MeshID XDGMesh::bin_to_mesh_id(int bin) const
287,568✔
215
{
216
  return xdg_->mesh_manager()->element_id(bin);
287,568✔
217
}
218

219
int32_t XDGMesh::mesh_id_to_bin(xdg::MeshID id) const
2,140,232✔
220
{
221
  if (id < 0)
2,140,232✔
222
    return -1;
223
  return xdg_->mesh_manager()->element_index(id);
1,220,206✔
224
}
225

226
} // namespace openmc
227

228
#endif // XDG
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