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

openmc-dev / openmc / 27291281945

10 Jun 2026 04:44PM UTC coverage: 81.338% (+0.06%) from 81.281%
27291281945

Pull #3965

github

web-flow
Merge 0ec75ce2d into 02eb999af
Pull Request #3965: MGXS Bootstrapping

18167 of 26320 branches covered (69.02%)

Branch coverage included in aggregate %.

68 of 68 new or added lines in 4 files covered. (100.0%)

787 existing lines in 47 files now uncovered.

59351 of 68984 relevant lines covered (86.04%)

67755206.51 hits per line

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

99.29
/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)
6,244✔
33
{
34
  auto& track = p.tracks().emplace_back();
6,244✔
35
  track.particle = p.type();
6,244✔
36
}
6,244✔
37

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

43
void open_track_file()
101✔
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;
52✔
49
  if (mpi::n_procs > 1) {
52✔
50
    filename = fmt::format("{}tracks_p{}.h5", settings::path_output, mpi::rank);
60✔
51
  } else {
52
    filename = fmt::format("{}tracks.h5", settings::path_output);
5✔
53
  }
54
#else
55
  std::string filename = fmt::format("{}tracks.h5", settings::path_output);
49✔
56
#endif
57
  track_file = file_open(filename, 'w');
101✔
58
  write_attribute(track_file, "filetype", "track");
101✔
59
  write_attribute(track_file, "version", VERSION_TRACK);
101✔
60

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

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

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

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

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

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

104
  // Check for match from explicit track identifiers
105
  if (settings::track_identifiers.size() > 0) {
209,005,065✔
106
    for (const auto& t : settings::track_identifiers) {
17,402✔
107
      if (simulation::current_batch == t[0] &&
13,101✔
108
          simulation::current_gen == t[1] && p.id() == t[2]) {
13,101!
109
        return true;
209,008,365✔
110
      }
111
    }
112
  }
113
  return false;
114
}
115

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

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

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

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

149
    // Free resources
150
    H5Dclose(dset);
1,010✔
151
    H5Sclose(dspace);
1,010✔
UNCOV
152
  }
600✔
153

154
  // Clear particle tracks
155
  p.tracks().clear();
1,010✔
156
}
1,010✔
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