forked from openmc-dev/openmc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtrack_output.cpp
158 lines (134 loc) · 4.9 KB
/
track_output.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include "openmc/track_output.h"
#include "openmc/constants.h"
#include "openmc/hdf5_interface.h"
#include "openmc/message_passing.h"
#include "openmc/position.h"
#include "openmc/settings.h"
#include "openmc/simulation.h"
#include "openmc/vector.h"
#include "xtensor/xtensor.hpp"
#include <fmt/core.h>
#include <hdf5.h>
#include <cstddef> // for size_t
#include <string>
namespace openmc {
//==============================================================================
// Global variables
//==============================================================================
hid_t track_file; //! HDF5 identifier for track file
hid_t track_dtype; //! HDF5 identifier for track datatype
int n_tracks_written; //! Number of tracks written
//==============================================================================
// Non-member functions
//==============================================================================
void add_particle_track(Particle& p)
{
p.tracks().emplace_back();
p.tracks().back().particle = p.type();
}
void write_particle_track(Particle& p)
{
p.tracks().back().states.push_back(p.get_track_state());
}
void open_track_file()
{
// Open file and write filetype/version -- when MPI is enabled and there is
// more than one rank, each rank writes its own file
#ifdef OPENMC_MPI
std::string filename;
if (mpi::n_procs > 1) {
filename = fmt::format("{}tracks_p{}.h5", settings::path_output, mpi::rank);
} else {
filename = fmt::format("{}tracks.h5", settings::path_output);
}
#else
std::string filename = fmt::format("{}tracks.h5", settings::path_output);
#endif
track_file = file_open(filename, 'w');
write_attribute(track_file, "filetype", "track");
write_attribute(track_file, "version", VERSION_TRACK);
// Create compound type for Position
hid_t postype = H5Tcreate(H5T_COMPOUND, sizeof(struct Position));
H5Tinsert(postype, "x", HOFFSET(Position, x), H5T_NATIVE_DOUBLE);
H5Tinsert(postype, "y", HOFFSET(Position, y), H5T_NATIVE_DOUBLE);
H5Tinsert(postype, "z", HOFFSET(Position, z), H5T_NATIVE_DOUBLE);
// Create compound type for TrackState
track_dtype = H5Tcreate(H5T_COMPOUND, sizeof(struct TrackState));
H5Tinsert(track_dtype, "r", HOFFSET(TrackState, r), postype);
H5Tinsert(track_dtype, "u", HOFFSET(TrackState, u), postype);
H5Tinsert(track_dtype, "E", HOFFSET(TrackState, E), H5T_NATIVE_DOUBLE);
H5Tinsert(track_dtype, "time", HOFFSET(TrackState, time), H5T_NATIVE_DOUBLE);
H5Tinsert(track_dtype, "wgt", HOFFSET(TrackState, wgt), H5T_NATIVE_DOUBLE);
H5Tinsert(
track_dtype, "cell_id", HOFFSET(TrackState, cell_id), H5T_NATIVE_INT);
H5Tinsert(track_dtype, "cell_instance", HOFFSET(TrackState, cell_instance),
H5T_NATIVE_INT);
H5Tinsert(track_dtype, "material_id", HOFFSET(TrackState, material_id),
H5T_NATIVE_INT);
H5Tclose(postype);
}
void close_track_file()
{
H5Tclose(track_dtype);
file_close(track_file);
// Reset number of tracks written
n_tracks_written = 0;
}
bool check_track_criteria(const Particle& p)
{
if (settings::write_all_tracks) {
// Increment number of tracks written and get previous value
int n;
#pragma omp atomic capture
n = n_tracks_written++;
// Indicate that track should be written for this particle
return n < settings::max_tracks;
}
// Check for match from explicit track identifiers
if (settings::track_identifiers.size() > 0) {
for (const auto& t : settings::track_identifiers) {
if (simulation::current_batch == t[0] &&
simulation::current_gen == t[1] && p.id() == t[2]) {
return true;
}
}
}
return false;
}
void finalize_particle_track(Particle& p)
{
// Determine number of coordinates for each particle
vector<int> offsets;
vector<int> particles;
vector<TrackState> tracks;
int offset = 0;
for (auto& track_i : p.tracks()) {
offsets.push_back(offset);
particles.push_back(static_cast<int>(track_i.particle));
offset += track_i.states.size();
tracks.insert(tracks.end(), track_i.states.begin(), track_i.states.end());
}
offsets.push_back(offset);
#pragma omp critical(FinalizeParticleTrack)
{
// Create name for dataset
std::string dset_name = fmt::format("track_{}_{}_{}",
simulation::current_batch, simulation::current_gen, p.id());
// Write array of TrackState to file
hsize_t dims[] {static_cast<hsize_t>(tracks.size())};
hid_t dspace = H5Screate_simple(1, dims, nullptr);
hid_t dset = H5Dcreate(track_file, dset_name.c_str(), track_dtype, dspace,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Dwrite(dset, track_dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, tracks.data());
// Write attributes
write_attribute(dset, "n_particles", p.tracks().size());
write_attribute(dset, "offsets", offsets);
write_attribute(dset, "particles", particles);
// Free resources
H5Dclose(dset);
H5Sclose(dspace);
}
// Clear particle tracks
p.tracks().clear();
}
} // namespace openmc