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

openmc-dev / openmc / 23919098363

02 Apr 2026 07:53PM UTC coverage: 81.336% (+0.01%) from 81.324%
23919098363

Pull #3734

github

web-flow
Merge 5ddfca290 into d9b30bbbd
Pull Request #3734: Specify temperature from a field (structured mesh only)

17720 of 25601 branches covered (69.22%)

Branch coverage included in aggregate %.

183 of 204 new or added lines in 15 files covered. (89.71%)

69 existing lines in 3 files now uncovered.

58284 of 67843 relevant lines covered (85.91%)

44754406.4 hits per line

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

65.71
/src/event.cpp
1
#include "openmc/event.h"
2

3
#include "openmc/material.h"
4
#include "openmc/simulation.h"
5
#include "openmc/timer.h"
6

7
namespace openmc {
8

9
//==============================================================================
10
// Global variables
11
//==============================================================================
12

13
namespace simulation {
14

15
SharedArray<EventQueueItem> calculate_fuel_xs_queue;
16
SharedArray<EventQueueItem> calculate_nonfuel_xs_queue;
17
SharedArray<EventQueueItem> advance_particle_queue;
18
SharedArray<EventQueueItem> surface_crossing_queue;
19
SharedArray<EventQueueItem> collision_queue;
20
SharedArray<EventQueueItem> temperature_mesh_crossing_queue;
21

22
vector<Particle> particles;
23

24
} // namespace simulation
25

26
//==============================================================================
27
// Non-member functions
28
//==============================================================================
29

30
void init_event_queues(int64_t n_particles)
209✔
31
{
32
  simulation::calculate_fuel_xs_queue.reserve(n_particles);
209✔
33
  simulation::calculate_nonfuel_xs_queue.reserve(n_particles);
209✔
34
  simulation::advance_particle_queue.reserve(n_particles);
209✔
35
  simulation::surface_crossing_queue.reserve(n_particles);
209✔
36
  simulation::collision_queue.reserve(n_particles);
209✔
37
  if (settings::temperature_field_on) {
209✔
38
    simulation::temperature_mesh_crossing_queue.reserve(n_particles);
1✔
39
  }
40

41
  simulation::particles.resize(n_particles);
209✔
42
}
209✔
43

44
void free_event_queues(void)
×
45
{
46
  simulation::calculate_fuel_xs_queue.clear();
×
47
  simulation::calculate_nonfuel_xs_queue.clear();
×
48
  simulation::advance_particle_queue.clear();
×
49
  simulation::surface_crossing_queue.clear();
×
50
  simulation::collision_queue.clear();
×
NEW
51
  simulation::temperature_mesh_crossing_queue.clear();
×
52

53
  simulation::particles.clear();
×
54
}
×
55

56
void dispatch_xs_event(int64_t buffer_idx)
228,690,547✔
57
{
58
  Particle& p = simulation::particles[buffer_idx];
228,690,547✔
59
  if (p.material() == MATERIAL_VOID ||
228,690,547✔
60
      !model::materials[p.material()]->fissionable()) {
211,419,513✔
61
    simulation::calculate_nonfuel_xs_queue.thread_safe_append({p, buffer_idx});
51,154,678✔
62
  } else {
63
    simulation::calculate_fuel_xs_queue.thread_safe_append({p, buffer_idx});
177,535,869✔
64
  }
65
}
228,690,547✔
66

67
void process_init_events(int64_t n_particles, int64_t source_offset)
3,203✔
68
{
69
  simulation::time_event_init.start();
3,203✔
70
#pragma omp parallel for schedule(runtime)
3,203✔
71
  for (int64_t i = 0; i < n_particles; i++) {
×
72
    initialize_history(simulation::particles[i], source_offset + i + 1);
73
    dispatch_xs_event(i);
74
  }
75
  simulation::time_event_init.stop();
3,203✔
76
}
3,203✔
77

78
void process_calculate_xs_events(SharedArray<EventQueueItem>& queue)
942,545✔
79
{
80
  simulation::time_event_calculate_xs.start();
942,545✔
81

82
  // TODO: If using C++17, we could perform a parallel sort of the queue by
83
  // particle type, material type, and then energy, in order to improve cache
84
  // locality and reduce thread divergence on GPU. However, the parallel
85
  // algorithms typically require linking against an additional library (Intel
86
  // TBB). Prior to C++17, std::sort is a serial only operation, which in this
87
  // case makes it too slow to be practical for most test problems.
88
  //
89
  // std::sort(std::execution::par_unseq, queue.data(), queue.data() +
90
  // queue.size());
91

92
  int64_t offset = simulation::advance_particle_queue.size();
942,545✔
93

94
#pragma omp parallel for schedule(runtime)
942,545✔
95
  for (int64_t i = 0; i < queue.size(); i++) {
×
96
    Particle* p = &simulation::particles[queue[i].idx];
97
    p->event_calculate_xs();
98

99
    // After executing a calculate_xs event, particles will
100
    // always require an advance event. Therefore, we don't need to use
101
    // the protected enqueuing function.
102
    simulation::advance_particle_queue[offset + i] = queue[i];
103
  }
104

105
  simulation::advance_particle_queue.resize(offset + queue.size());
942,545✔
106

107
  queue.resize(0);
942,545✔
108

109
  simulation::time_event_calculate_xs.stop();
942,545✔
110
}
942,545✔
111

112
void process_advance_particle_events()
937,270✔
113
{
114
  simulation::time_event_advance_particle.start();
937,270✔
115

116
#pragma omp parallel for schedule(runtime)
937,270✔
117
  for (int64_t i = 0; i < simulation::advance_particle_queue.size(); i++) {
×
118
    int64_t buffer_idx = simulation::advance_particle_queue[i].idx;
119
    Particle& p = simulation::particles[buffer_idx];
120
    p.event_advance();
121
    if (!p.alive())
×
122
      continue;
123

124
    switch (p.next_event()) {
×
125
    case EVENT_CROSS_SURFACE:
126
      simulation::surface_crossing_queue.thread_safe_append({p, buffer_idx});
127
      break;
128
    case EVENT_COLLIDE:
129
      simulation::collision_queue.thread_safe_append({p, buffer_idx});
130
      break;
131
    case EVENT_CROSS_TEMPERATURE_MESH:
132
      simulation::temperature_mesh_crossing_queue.thread_safe_append(
133
        {p, buffer_idx});
134
      break;
135
    case EVENT_TIME_CUTOFF:
136
      p.wgt() = 0.0;
137
      break;
138
    default:
139
      fatal_error(fmt::format(
140
        "Unknown event '{}' in event-based transport!", p.next_event()));
141
      break;
142
    }
143
  }
144

145
  simulation::advance_particle_queue.resize(0);
937,270✔
146

147
  simulation::time_event_advance_particle.stop();
937,270✔
148
}
937,270✔
149

150
void process_surface_crossing_events()
263,095✔
151
{
152
  simulation::time_event_surface_crossing.start();
263,095✔
153

154
#pragma omp parallel for schedule(runtime)
263,095✔
155
  for (int64_t i = 0; i < simulation::surface_crossing_queue.size(); i++) {
×
156
    int64_t buffer_idx = simulation::surface_crossing_queue[i].idx;
157
    Particle& p = simulation::particles[buffer_idx];
158
    p.event_cross_surface();
159
    p.event_revive_from_secondary();
160
    if (p.alive())
×
161
      dispatch_xs_event(buffer_idx);
162
  }
163

164
  simulation::surface_crossing_queue.resize(0);
263,095✔
165

166
  simulation::time_event_surface_crossing.stop();
263,095✔
167
}
263,095✔
168

169
void process_collision_events()
692,143✔
170
{
171
  simulation::time_event_collision.start();
692,143✔
172

173
#pragma omp parallel for schedule(runtime)
692,143✔
174
  for (int64_t i = 0; i < simulation::collision_queue.size(); i++) {
×
175
    int64_t buffer_idx = simulation::collision_queue[i].idx;
176
    Particle& p = simulation::particles[buffer_idx];
177
    p.event_collide();
178
    p.event_revive_from_secondary();
179
    if (p.alive())
×
180
      dispatch_xs_event(buffer_idx);
181
  }
182

183
  simulation::collision_queue.resize(0);
692,143✔
184

185
  simulation::time_event_collision.stop();
692,143✔
186
}
692,143✔
187

188
void process_temperature_mesh_crossing_events()
655✔
189
{
190
  simulation::time_event_temperature_mesh_crossing.start();
655✔
191

192
#pragma omp parallel for schedule(runtime)
655✔
193
  for (int64_t i = 0; i < simulation::temperature_mesh_crossing_queue.size();
×
194
       i++) {
195
    int64_t buffer_idx = simulation::temperature_mesh_crossing_queue[i].idx;
196
    Particle& p = simulation::particles[buffer_idx];
197
    p.event_cross_temperature_mesh();
198
    p.event_revive_from_secondary();
199
    if (p.alive())
×
200
      dispatch_xs_event(buffer_idx);
201
  }
202

203
  simulation::temperature_mesh_crossing_queue.resize(0);
655✔
204

205
  simulation::time_event_temperature_mesh_crossing.stop();
655✔
206
}
655✔
207

208
void process_death_events(int64_t n_particles)
3,203✔
209
{
210
  simulation::time_event_death.start();
3,203✔
211
#pragma omp parallel for schedule(runtime)
3,203✔
212
  for (int64_t i = 0; i < n_particles; i++) {
×
213
    Particle& p = simulation::particles[i];
214
    p.event_death();
215
  }
216
  simulation::time_event_death.stop();
3,203✔
217
}
3,203✔
218

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