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

openmc-dev / openmc / 37216251345

04 Oct 2026 04:17PM UTC coverage: 81.295% (-0.1%) from 81.4%
37216251345

Pull #4166

github

web-flow
Merge a29a4711a into 4c0448d33
Pull Request #4166: Cache surface distances and senses when finding boundaries in complex cells

20094 of 29178 branches covered (68.87%)

Branch coverage included in aggregate %.

249 of 263 new or added lines in 5 files covered. (94.68%)

205 existing lines in 3 files now uncovered.

62624 of 72572 relevant lines covered (86.29%)

42980343.05 hits per line

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

87.7
/src/particle_data.cpp
1
#include "openmc/particle_data.h"
2

3
#include <sstream>
4

5
#include "openmc/cell.h"
6
#include "openmc/error.h"
7
#include "openmc/geometry.h"
8
#include "openmc/material.h"
9
#include "openmc/nuclide.h"
10
#include "openmc/photon.h"
11
#include "openmc/settings.h"
12
#include "openmc/simulation.h"
13
#include "openmc/tallies/derivative.h"
14
#include "openmc/tallies/filter.h"
15
#include "openmc/tallies/tally.h"
16

17
namespace openmc {
18

19
namespace {
20

21
//! Most memory used by the working space for complex regions of all of the
22
//! particles in flight in event-based mode
23
constexpr int64_t MAX_SURFACE_STATES_MEMORY {256'000'000};
24

25
} // namespace
26

UNCOV
27
void GeometryState::mark_as_lost(const char* message)
×
28
{
29
  fatal_error(message);
×
30
}
31

32
void GeometryState::mark_as_lost(const std::string& message)
4,270 ✔
33
{
34
  mark_as_lost(message.c_str());
4,270 ✔
35
}
4,263 ✔
36

37
void GeometryState::mark_as_lost(const std::stringstream& message)
×
38
{
39
  mark_as_lost(message.str());
×
40
}
×
41

42
void LocalCoord::rotate(const vector<double>& rotation)
48,284,144 ✔
43
{
44
  r_ = r_.rotate(rotation);
48,284,144 ✔
45
  u_ = u_.rotate(rotation);
48,284,144 ✔
46
  rotated_ = true;
48,284,144 ✔
47
}
48,284,144 ✔
48

49
void LocalCoord::reset()
1,729,807,097 ✔
50
{
51
  cell_ = C_NONE;
1,729,807,097 ✔
52
  universe_ = C_NONE;
1,729,807,097 ✔
53
  lattice_ = C_NONE;
1,729,807,097 ✔
54
  lattice_index_[0] = 0;
1,729,807,097 ✔
55
  lattice_index_[1] = 0;
1,729,807,097 ✔
56
  lattice_index_[2] = 0;
1,729,807,097 ✔
57
  rotated_ = false;
1,729,807,097 ✔
58
}
1,729,807,097 ✔
59

60
GeometryState::GeometryState()
51,257,055 ✔
61
{
62
  // Create and clear coordinate levels
63
  coord_.resize(model::n_coord_levels);
51,257,055 ✔
64
  cell_last_.resize(model::n_coord_levels);
51,257,055 ✔
65
  clear();
51,257,055 ✔
66
}
51,257,055 ✔
67

68
void GeometryState::advance_to_boundary_from_void()
11,488,704 ✔
69
{
70
  auto root_coord = this->coord(0);
11,488,704 ✔
71
  const auto& root_universe = model::universes[model::root_universe];
11,488,704 ✔
72
  boundary().reset();
11,488,704 ✔
73

74
  for (auto c_i : root_universe->cells_) {
45,931,952 ✔
75
    auto dist =
34,443,248 ✔
76
      model::cells.at(c_i)->distance(root_coord.r(), root_coord.u(), 0, this);
34,443,248 ✔
77
    if (dist.first < boundary().distance()) {
34,443,248 ✔
78
      boundary().distance() = dist.first;
15,190,612 ✔
79
      boundary().surface() = dist.second;
15,190,612 ✔
80
    }
81
  }
82

83
  // if no intersection or near-infinite intersection, reset
84
  // boundary information
85
  if (boundary().distance() > 1e300) {
11,488,704 ✔
86
    boundary().distance() = INFTY;
1,507,152 ✔
87
    boundary().surface() = SURFACE_NONE;
1,507,152 ✔
88
    return;
1,507,152 ✔
89
  }
90

91
  // move the particle up to (and just past) the boundary
92
  move_distance(boundary().distance() + TINY_BIT);
9,981,552 ✔
93
}
94

95
void GeometryState::move_distance(double length)
2,147,483,647 ✔
96
{
97
  for (int j = 0; j < n_coord(); ++j) {
2,147,483,647 ✔
98
    coord(j).r() += length * coord(j).u();
2,147,483,647 ✔
99
  }
100
}
2,147,483,647 ✔
101

102
ParticleData::ParticleData()
14,272,236 ✔
103
{
104
  zero_delayed_bank();
14,272,236 ✔
105

106
  // Every particle starts with no accumulated flux derivative.  Note that in
107
  // event mode, we construct the particle once up front, so have to run this
108
  // even if the current batch is inactive.
109
  if (!model::active_tallies.empty() || settings::event_based) {
14,272,236 ✔
110
    flux_derivs_.resize(model::tally_derivs.size());
4,224,227 ✔
111
    zero_flux_derivs();
4,224,227 ✔
112
  }
113

114
  // Allocate space for tally filter matches
115
  filter_matches_.resize(model::tally_filters.size());
14,272,236 ✔
116

117
  // Create microscopic cross section caches
118
  neutron_xs_.resize(data::nuclides.size());
14,272,236 ✔
119
  photon_xs_.resize(data::elements.size());
14,272,236 ✔
120

121
  // Size the working space for finding boundaries in complex regions for the
122
  // region with the most surfaces. Other geometry states, which are only used
123
  // to locate points, have none. In event-based mode, where many particles
124
  // are in flight, its total size is limited. Regions with more surfaces than
125
  // the working space holds are searched without it.
126
  int64_t n_states = model::max_region_surfaces;
14,272,236 ✔
127
  if (settings::event_based) {
14,272,236 ✔
128
    int64_t n_particles = std::max<int64_t>(1,
788,229 !
129
      std::min(simulation::work_per_rank, settings::max_particles_in_flight));
788,229 ✔
130
    n_states = std::min<int64_t>(n_states,
1,576,458 ✔
131
      MAX_SURFACE_STATES_MEMORY / (n_particles * sizeof(SurfaceState)));
788,229 !
132
  }
133
  surface_states().resize(n_states);
14,272,236 ✔
134

135
  // Creates the pulse-height storage for the particle
136
  if (!model::pulse_height_cells.empty()) {
14,272,236 ✔
137
    pht_storage_.resize(model::pulse_height_cells.size(), 0.0);
971 ✔
138
  }
139
}
14,272,236 ✔
140

141
TrackState ParticleData::get_track_state() const
4,991 ✔
142
{
143
  TrackState state;
4,991 !
144
  state.r = this->r();
4,991 !
145
  state.u = this->u();
4,991 !
146
  state.E = this->E();
4,991 ✔
147
  state.time = this->time();
4,991 ✔
148
  state.wgt = this->wgt();
4,991 !
149
  state.cell_id = model::cells[this->lowest_coord().cell()]->id_;
4,991 !
150
  state.cell_instance = this->cell_instance();
4,991 ✔
151
  if (this->material() != MATERIAL_VOID) {
4,991 !
152
    state.material_id = model::materials[material()]->id_;
4,991 ✔
153
  }
154
  return state;
4,991 ✔
155
}
156

157
} // namespace openmc
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc