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

openmc-dev / openmc / 13183515203

06 Feb 2025 04:36PM UTC coverage: 82.601% (-2.3%) from 84.867%
13183515203

Pull #3087

github

web-flow
Merge d68c72d5e into 6e0f156d3
Pull Request #3087: wheel building with scikit build core

107123 of 129687 relevant lines covered (82.6%)

12608333.34 hits per line

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

85.44
/src/universe.cpp
1
#include "openmc/universe.h"
2

3
#include <set>
4

5
#include "openmc/hdf5_interface.h"
6
#include "openmc/particle.h"
7

8
namespace openmc {
9

10
namespace model {
11

12
std::unordered_map<int32_t, int32_t> universe_map;
13
vector<unique_ptr<Universe>> universes;
14

15
} // namespace model
16

17
//==============================================================================
18
// Universe implementation
19
//==============================================================================
20

21
void Universe::to_hdf5(hid_t universes_group) const
7,446✔
22
{
23
  // Create a group for this universe.
24
  auto group = create_group(universes_group, fmt::format("universe {}", id_));
14,892✔
25

26
  // Write the geometry representation type.
27
  write_string(group, "geom_type", "csg", false);
7,446✔
28

29
  // Write the contained cells.
30
  if (cells_.size() > 0) {
7,446✔
31
    vector<int32_t> cell_ids;
7,446✔
32
    for (auto i_cell : cells_)
23,058✔
33
      cell_ids.push_back(model::cells[i_cell]->id_);
15,612✔
34
    write_dataset(group, "cells", cell_ids);
7,446✔
35
  }
7,446✔
36

37
  close_group(group);
7,446✔
38
}
7,446✔
39

40
bool Universe::find_cell(GeometryState& p) const
897,241,901✔
41
{
42
  const auto& cells {
43
    !partitioner_ ? cells_ : partitioner_->get_cells(p.r_local(), p.u_local())};
897,241,901✔
44

45
  Position r {p.r_local()};
897,241,901✔
46
  Position u {p.u_local()};
897,241,901✔
47
  auto surf = p.surface();
897,241,901✔
48
  int32_t i_univ = p.lowest_coord().universe;
897,241,901✔
49

50
  for (auto i_cell : cells) {
1,433,152,377✔
51
    if (model::cells[i_cell]->universe_ != i_univ)
1,252,282,965✔
52
      continue;
×
53
    // Check if this cell contains the particle
54
    if (model::cells[i_cell]->contains(r, u, surf)) {
1,252,282,965✔
55
      p.lowest_coord().cell = i_cell;
716,372,489✔
56
      return true;
716,372,489✔
57
    }
58
  }
59
  return false;
180,869,412✔
60
}
61

62
BoundingBox Universe::bounding_box() const
×
63
{
64
  BoundingBox bbox = {INFTY, -INFTY, INFTY, -INFTY, INFTY, -INFTY};
×
65
  if (cells_.size() == 0) {
×
66
    return {};
×
67
  } else {
68
    for (const auto& cell : cells_) {
×
69
      auto& c = model::cells[cell];
×
70
      bbox |= c->bounding_box();
×
71
    }
72
  }
73
  return bbox;
×
74
}
75

76
//==============================================================================
77
// UniversePartitioner implementation
78
//==============================================================================
79

80
UniversePartitioner::UniversePartitioner(const Universe& univ)
102✔
81
{
82
  // Define an ordered set of surface indices that point to z-planes.  Use a
83
  // functor to to order the set by the z0_ values of the corresponding planes.
84
  struct compare_surfs {
85
    bool operator()(const int32_t& i_surf, const int32_t& j_surf) const
10,489✔
86
    {
87
      const auto* surf = model::surfaces[i_surf].get();
10,489✔
88
      const auto* zplane = dynamic_cast<const SurfaceZPlane*>(surf);
10,489✔
89
      double zi = zplane->z0_;
10,489✔
90
      surf = model::surfaces[j_surf].get();
10,489✔
91
      zplane = dynamic_cast<const SurfaceZPlane*>(surf);
10,489✔
92
      double zj = zplane->z0_;
10,489✔
93
      return zi < zj;
10,489✔
94
    }
95
  };
96
  std::set<int32_t, compare_surfs> surf_set;
102✔
97

98
  // Find all of the z-planes in this universe.  A set is used here for the
99
  // O(log(n)) insertions that will ensure entries are not repeated.
100
  for (auto i_cell : univ.cells_) {
1,428✔
101
    for (auto token : model::cells[i_cell]->surfaces()) {
5,865✔
102
      auto i_surf = std::abs(token) - 1;
4,539✔
103
      const auto* surf = model::surfaces[i_surf].get();
4,539✔
104
      if (const auto* zplane = dynamic_cast<const SurfaceZPlane*>(surf))
4,539✔
105
        surf_set.insert(i_surf);
2,584✔
106
    }
1,326✔
107
  }
108

109
  // Populate the surfs_ vector from the ordered set.
110
  surfs_.insert(surfs_.begin(), surf_set.begin(), surf_set.end());
102✔
111

112
  // Populate the partition lists.
113
  partitions_.resize(surfs_.size() + 1);
102✔
114
  for (auto i_cell : univ.cells_) {
1,428✔
115
    // It is difficult to determine the bounds of a complex cell, so add complex
116
    // cells to all partitions.
117
    if (!model::cells[i_cell]->is_simple()) {
1,326✔
118
      for (auto& p : partitions_)
×
119
        p.push_back(i_cell);
×
120
      continue;
×
121
    }
122

123
    // Find the tokens for bounding z-planes.
124
    int32_t lower_token = 0, upper_token = 0;
1,326✔
125
    double min_z, max_z;
126
    for (auto token : model::cells[i_cell]->surfaces()) {
5,865✔
127
      const auto* surf = model::surfaces[std::abs(token) - 1].get();
4,539✔
128
      if (const auto* zplane = dynamic_cast<const SurfaceZPlane*>(surf)) {
4,539✔
129
        if (lower_token == 0 || zplane->z0_ < min_z) {
2,584✔
130
          lower_token = token;
1,326✔
131
          min_z = zplane->z0_;
1,326✔
132
        }
133
        if (upper_token == 0 || zplane->z0_ > max_z) {
2,584✔
134
          upper_token = token;
2,584✔
135
          max_z = zplane->z0_;
2,584✔
136
        }
137
      }
138
    }
1,326✔
139

140
    // If there are no bounding z-planes, add this cell to all partitions.
141
    if (lower_token == 0) {
1,326✔
142
      for (auto& p : partitions_)
×
143
        p.push_back(i_cell);
×
144
      continue;
×
145
    }
146

147
    // Find the first partition this cell lies in.  If the lower_token indicates
148
    // a negative halfspace, then the cell is unbounded in the lower direction
149
    // and it lies in the first partition onward.  Otherwise, it is bounded by
150
    // the positive halfspace given by the lower_token.
151
    int first_partition = 0;
1,326✔
152
    if (lower_token > 0) {
1,326✔
153
      for (int i = 0; i < surfs_.size(); ++i) {
4,913✔
154
        if (lower_token == surfs_[i] + 1) {
4,913✔
155
          first_partition = i + 1;
1,292✔
156
          break;
1,292✔
157
        }
158
      }
159
    }
160

161
    // Find the last partition this cell lies in.  The logic is analogous to the
162
    // logic for first_partition.
163
    int last_partition = surfs_.size();
1,326✔
164
    if (upper_token < 0) {
1,326✔
165
      for (int i = first_partition; i < surfs_.size(); ++i) {
2,788✔
166
        if (upper_token == -(surfs_[i] + 1)) {
2,788✔
167
          last_partition = i;
1,292✔
168
          break;
1,292✔
169
        }
170
      }
171
    }
172

173
    // Add the cell to all relevant partitions.
174
    for (int i = first_partition; i <= last_partition; ++i) {
4,165✔
175
      partitions_[i].push_back(i_cell);
2,839✔
176
    }
177
  }
178
}
102✔
179

180
const vector<int32_t>& UniversePartitioner::get_cells(
271,255✔
181
  Position r, Direction u) const
182
{
183
  // Perform a binary search for the partition containing the given coordinates.
184
  int left = 0;
271,255✔
185
  int middle = (surfs_.size() - 1) / 2;
271,255✔
186
  int right = surfs_.size() - 1;
271,255✔
187
  while (true) {
188
    // Check the sense of the coordinates for the current surface.
189
    const auto& surf = *model::surfaces[surfs_[middle]];
813,794✔
190
    if (surf.sense(r, u)) {
813,794✔
191
      // The coordinates lie in the positive halfspace.  Recurse if there are
192
      // more surfaces to check.  Otherwise, return the cells on the positive
193
      // side of this surface.
194
      int right_leaf = right - (right - middle) / 2;
315,514✔
195
      if (right_leaf != middle) {
315,514✔
196
        left = middle + 1;
272,344✔
197
        middle = right_leaf;
272,344✔
198
      } else {
199
        return partitions_[middle + 1];
43,170✔
200
      }
201

202
    } else {
203
      // The coordinates lie in the negative halfspace.  Recurse if there are
204
      // more surfaces to check.  Otherwise, return the cells on the negative
205
      // side of this surface.
206
      int left_leaf = left + (middle - left) / 2;
498,280✔
207
      if (left_leaf != middle) {
498,280✔
208
        right = middle - 1;
270,195✔
209
        middle = left_leaf;
270,195✔
210
      } else {
211
        return partitions_[middle];
228,085✔
212
      }
213
    }
214
  }
542,539✔
215
}
216

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

© 2025 Coveralls, Inc