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

openmc-dev / openmc / 23291766092

19 Mar 2026 11:01AM UTC coverage: 80.712% (-0.7%) from 81.447%
23291766092

Pull #3886

github

web-flow
Merge 7b45738dd into 3ce6cbfdd
Pull Request #3886: Implement python tally types

16322 of 23494 branches covered (69.47%)

Branch coverage included in aggregate %.

213 of 262 new or added lines in 11 files covered. (81.3%)

710 existing lines in 49 files now uncovered.

56450 of 66668 relevant lines covered (84.67%)

7838586.91 hits per line

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

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

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

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

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

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

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

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

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

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

104
  // Check for match from explicit track identifiers
105
  if (settings::track_identifiers.size() > 0) {
15,340,223✔
106
    for (const auto& t : settings::track_identifiers) {
1,582✔
107
      if (simulation::current_batch == t[0] &&
1,191✔
108
          simulation::current_gen == t[1] && p.id() == t[2]) {
1,191!
109
        return true;
15,340,523✔
110
      }
111
    }
112
  }
113
  return false;
114
}
115

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

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

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

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

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

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