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

openmc-dev / openmc / 25279631769

03 May 2026 12:49PM UTC coverage: 80.729% (-0.6%) from 81.374%
25279631769

Pull #3934

github

web-flow
Merge 04f48e991 into 368ea069c
Pull Request #3934: Fix virtual surface crossing

16767 of 24138 branches covered (69.46%)

Branch coverage included in aggregate %.

19 of 19 new or added lines in 1 file covered. (100.0%)

690 existing lines in 41 files now uncovered.

57123 of 67390 relevant lines covered (84.76%)

31328495.39 hits per line

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

98.55
/src/track_output.cpp
1
#include "openmc/track_output.h"
2

3
#include "openmc/constants.h"
4
#include "openmc/hdf5_interface.h"
5
#include "openmc/message_passing.h"
6
#include "openmc/position.h"
7
#include "openmc/settings.h"
8
#include "openmc/simulation.h"
9
#include "openmc/vector.h"
10

11
#include "openmc/tensor.h"
12
#include <fmt/core.h>
13
#include <hdf5.h>
14

15
#include <cstddef> // for size_t
16
#include <string>
17

18
namespace openmc {
19

20
//==============================================================================
21
// Global variables
22
//==============================================================================
23

24
hid_t track_file;     //! HDF5 identifier for track file
25
hid_t track_dtype;    //! HDF5 identifier for track datatype
26
int n_tracks_written; //! Number of tracks written
27

28
//==============================================================================
29
// Non-member functions
30
//==============================================================================
31

32
void add_particle_track(Particle& p)
2,482✔
33
{
34
  auto& track = p.tracks().emplace_back();
2,482✔
35
  track.particle = p.type();
2,482✔
36
}
2,482✔
37

38
void write_particle_track(Particle& p)
6,776✔
39
{
40
  p.tracks().back().states.push_back(p.get_track_state());
6,776✔
41
}
6,776✔
42

43
void open_track_file()
41✔
44
{
45
  // Open file and write filetype/version -- when MPI is enabled and there is
46
  // more than one rank, each rank writes its own file
47
#ifdef OPENMC_MPI
48
  std::string filename;
13✔
49
  if (mpi::n_procs > 1) {
13✔
50
    filename = fmt::format("{}tracks_p{}.h5", settings::path_output, mpi::rank);
12✔
51
  } else {
52
    filename = fmt::format("{}tracks.h5", settings::path_output);
1✔
53
  }
54
#else
55
  std::string filename = fmt::format("{}tracks.h5", settings::path_output);
28✔
56
#endif
57
  track_file = file_open(filename, 'w');
41✔
58
  write_attribute(track_file, "filetype", "track");
41✔
59
  write_attribute(track_file, "version", VERSION_TRACK);
41✔
60

61
  // Create compound type for Position
62
  hid_t postype = H5Tcreate(H5T_COMPOUND, sizeof(struct Position));
41✔
63
  H5Tinsert(postype, "x", HOFFSET(Position, x), H5T_NATIVE_DOUBLE);
41✔
64
  H5Tinsert(postype, "y", HOFFSET(Position, y), H5T_NATIVE_DOUBLE);
41✔
65
  H5Tinsert(postype, "z", HOFFSET(Position, z), H5T_NATIVE_DOUBLE);
41✔
66

67
  // Create compound type for TrackState
68
  track_dtype = H5Tcreate(H5T_COMPOUND, sizeof(struct TrackState));
41✔
69
  H5Tinsert(track_dtype, "r", HOFFSET(TrackState, r), postype);
41✔
70
  H5Tinsert(track_dtype, "u", HOFFSET(TrackState, u), postype);
41✔
71
  H5Tinsert(track_dtype, "E", HOFFSET(TrackState, E), H5T_NATIVE_DOUBLE);
41✔
72
  H5Tinsert(track_dtype, "time", HOFFSET(TrackState, time), H5T_NATIVE_DOUBLE);
41✔
73
  H5Tinsert(track_dtype, "wgt", HOFFSET(TrackState, wgt), H5T_NATIVE_DOUBLE);
41✔
74
  H5Tinsert(
41✔
75
    track_dtype, "cell_id", HOFFSET(TrackState, cell_id), H5T_NATIVE_INT);
41✔
76
  H5Tinsert(track_dtype, "cell_instance", HOFFSET(TrackState, cell_instance),
41✔
77
    H5T_NATIVE_INT);
41✔
78
  H5Tinsert(track_dtype, "material_id", HOFFSET(TrackState, material_id),
41✔
79
    H5T_NATIVE_INT);
41✔
80
  H5Tclose(postype);
41✔
81
}
41✔
82

83
void close_track_file()
41✔
84
{
85
  H5Tclose(track_dtype);
41✔
86
  file_close(track_file);
41✔
87

88
  // Reset number of tracks written
89
  n_tracks_written = 0;
41✔
90
}
41✔
91

92
bool check_track_criteria(const Particle& p)
80,658,125✔
93
{
94
  if (settings::write_all_tracks) {
80,658,125✔
95
    // Increment number of tracks written and get previous value
96
    int n;
1,500✔
97
#pragma omp atomic capture
98
    n = n_tracks_written++;
1,500✔
99

100
    // Indicate that track should be written for this particle
101
    return n < settings::max_tracks;
1,500✔
102
  }
103

104
  // Check for match from explicit track identifiers
105
  if (settings::track_identifiers.size() > 0) {
80,656,625✔
106
    for (const auto& t : settings::track_identifiers) {
7,910✔
107
      if (simulation::current_batch == t[0] &&
5,955✔
108
          simulation::current_gen == t[1] && p.id() == t[2]) {
5,955!
109
        return true;
80,658,125✔
110
      }
111
    }
112
  }
113
  return false;
114
}
115

116
void finalize_particle_track(Particle& p)
410✔
117
{
118
  // Determine number of coordinates for each particle
119
  vector<int> offsets;
410✔
120
  vector<int> particles;
410✔
121
  vector<TrackState> tracks;
410✔
122
  int offset = 0;
410✔
123
  for (auto& track_i : p.tracks()) {
2,892✔
124
    offsets.push_back(offset);
2,482✔
125
    particles.push_back(track_i.particle.pdg_number());
2,482✔
126
    offset += track_i.states.size();
2,482✔
127
    tracks.insert(tracks.end(), track_i.states.begin(), track_i.states.end());
2,482✔
128
  }
129
  offsets.push_back(offset);
410✔
130

131
#pragma omp critical(FinalizeParticleTrack)
132
  {
410✔
133
    // Create name for dataset
134
    std::string dset_name = fmt::format("track_{}_{}_{}",
410✔
135
      simulation::current_batch, simulation::current_gen, p.id());
410✔
136

137
    // Write array of TrackState to file
138
    hsize_t dims[] {static_cast<hsize_t>(tracks.size())};
410✔
139
    hid_t dspace = H5Screate_simple(1, dims, nullptr);
410✔
140
    hid_t dset = H5Dcreate(track_file, dset_name.c_str(), track_dtype, dspace,
410✔
141
      H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
142
    H5Dwrite(dset, track_dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, tracks.data());
410✔
143

144
    // Write attributes
145
    write_attribute(dset, "n_particles", p.tracks().size());
410✔
146
    write_attribute(dset, "offsets", offsets);
410✔
147
    write_attribute(dset, "particles", particles);
410✔
148

149
    // Free resources
150
    H5Dclose(dset);
410✔
151
    H5Sclose(dspace);
410✔
UNCOV
152
  }
×
153

154
  // Clear particle tracks
155
  p.tracks().clear();
410✔
156
}
410✔
157

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