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

openmc-dev / openmc / 13134187828

04 Feb 2025 11:13AM UTC coverage: 84.945% (+0.08%) from 84.869%
13134187828

Pull #3252

github

web-flow
Merge 6f397fdd5 into 59c398be8
Pull Request #3252: Adding vtkhdf option to write vtk data

80 of 92 new or added lines in 1 file covered. (86.96%)

1267 existing lines in 48 files now uncovered.

50221 of 59122 relevant lines covered (84.94%)

35221818.06 hits per line

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

76.6
/src/mcpl_interface.cpp
1
#include "openmc/mcpl_interface.h"
2

3
#include "openmc/bank.h"
4
#include "openmc/error.h"
5
#include "openmc/file_utils.h"
6
#include "openmc/message_passing.h"
7
#include "openmc/settings.h"
8
#include "openmc/simulation.h"
9
#include "openmc/state_point.h"
10
#include "openmc/vector.h"
11

12
#include <fmt/core.h>
13

14
#ifdef OPENMC_MCPL
15
#include <mcpl.h>
16
#endif
17

18
namespace openmc {
19

20
//==============================================================================
21
// Constants
22
//==============================================================================
23

24
#ifdef OPENMC_MCPL
25
const bool MCPL_ENABLED = true;
26
#else
27
const bool MCPL_ENABLED = false;
28
#endif
29

30
//==============================================================================
31
// Functions
32
//==============================================================================
33

34
#ifdef OPENMC_MCPL
35
SourceSite mcpl_particle_to_site(const mcpl_particle_t* particle)
17,000✔
36
{
37
  SourceSite site;
17,000✔
38

39
  switch (particle->pdgcode) {
17,000✔
40
  case 2112:
17,000✔
41
    site.particle = ParticleType::neutron;
17,000✔
42
    break;
17,000✔
43
  case 22:
×
44
    site.particle = ParticleType::photon;
×
45
    break;
×
46
  case 11:
×
47
    site.particle = ParticleType::electron;
×
48
    break;
×
49
  case -11:
×
50
    site.particle = ParticleType::positron;
×
51
    break;
×
52
  }
53

54
  // Copy position and direction
55
  site.r.x = particle->position[0];
17,000✔
56
  site.r.y = particle->position[1];
17,000✔
57
  site.r.z = particle->position[2];
17,000✔
58
  site.u.x = particle->direction[0];
17,000✔
59
  site.u.y = particle->direction[1];
17,000✔
60
  site.u.z = particle->direction[2];
17,000✔
61

62
  // MCPL stores kinetic energy in [MeV], time in [ms]
63
  site.E = particle->ekin * 1e6;
17,000✔
64
  site.time = particle->time * 1e-3;
17,000✔
65
  site.wgt = particle->weight;
17,000✔
66

67
  return site;
17,000✔
68
}
69
#endif
70

71
//==============================================================================
72

73
vector<SourceSite> mcpl_source_sites(std::string path)
17✔
74
{
75
  vector<SourceSite> sites;
17✔
76

77
#ifdef OPENMC_MCPL
78
  // Open MCPL file and determine number of particles
79
  auto mcpl_file = mcpl_open_file(path.c_str());
17✔
80
  size_t n_sites = mcpl_hdr_nparticles(mcpl_file);
17✔
81

82
  for (int i = 0; i < n_sites; i++) {
17,017✔
83
    // Extract particle from mcpl-file, checking if it is a neutron, photon,
84
    // electron, or positron. Otherwise skip.
85
    const mcpl_particle_t* particle;
86
    int pdg = 0;
17,000✔
87
    while (pdg != 2112 && pdg != 22 && pdg != 11 && pdg != -11) {
34,000✔
88
      particle = mcpl_read(mcpl_file);
17,000✔
89
      pdg = particle->pdgcode;
17,000✔
90
    }
91

92
    // Convert to source site and add to vector
93
    sites.push_back(mcpl_particle_to_site(particle));
17,000✔
94
  }
95

96
  // Check that some sites were read
97
  if (sites.empty()) {
17✔
98
    fatal_error("MCPL file contained no neutron, photon, electron, or positron "
×
99
                "source particles.");
100
  }
101

102
  mcpl_close_file(mcpl_file);
17✔
103
#else
104
  fatal_error(
105
    "Your build of OpenMC does not support reading MCPL source files.");
106
#endif
107

108
  return sites;
34✔
109
}
×
110

111
//==============================================================================
112

113
#ifdef OPENMC_MCPL
114
void write_mcpl_source_bank(mcpl_outfile_t file_id,
17✔
115
  gsl::span<SourceSite> source_bank, const vector<int64_t>& bank_index)
116
{
117
  int64_t dims_size = settings::n_particles;
17✔
118
  int64_t count_size = simulation::work_per_rank;
17✔
119

120
  if (mpi::master) {
17✔
121
    // Particles are writeen to disk from the master node only
122

123
    // Save source bank sites since the array is overwritten below
124
#ifdef OPENMC_MPI
125
    vector<SourceSite> temp_source {source_bank.begin(), source_bank.end()};
5✔
126
#endif
127

128
    // loop over the other nodes and receive data - then write those.
129
    for (int i = 0; i < mpi::n_procs; ++i) {
29✔
130
      // number of particles for node node i
131
      size_t count[] {static_cast<size_t>(bank_index[i + 1] - bank_index[i])};
17✔
132

133
#ifdef OPENMC_MPI
134
      if (i > 0)
10✔
135
        MPI_Recv(source_bank.data(), count[0], mpi::source_site, i, i,
5✔
136
          mpi::intracomm, MPI_STATUS_IGNORE);
137
#endif
138
      // now write the source_bank data again.
139
      for (const auto& site : source_bank) {
12,017✔
140
        // particle is now at the iterator
141
        // write it to the mcpl-file
142
        mcpl_particle_t p;
143
        p.position[0] = site.r.x;
12,000✔
144
        p.position[1] = site.r.y;
12,000✔
145
        p.position[2] = site.r.z;
12,000✔
146

147
        // mcpl requires that the direction vector is unit length
148
        // which is also the case in openmc
149
        p.direction[0] = site.u.x;
12,000✔
150
        p.direction[1] = site.u.y;
12,000✔
151
        p.direction[2] = site.u.z;
12,000✔
152

153
        // MCPL stores kinetic energy in [MeV], time in [ms]
154
        p.ekin = site.E * 1e-6;
12,000✔
155
        p.time = site.time * 1e3;
12,000✔
156
        p.weight = site.wgt;
12,000✔
157

158
        switch (site.particle) {
12,000✔
159
        case ParticleType::neutron:
12,000✔
160
          p.pdgcode = 2112;
12,000✔
161
          break;
12,000✔
162
        case ParticleType::photon:
×
163
          p.pdgcode = 22;
×
164
          break;
×
165
        case ParticleType::electron:
×
166
          p.pdgcode = 11;
×
167
          break;
×
168
        case ParticleType::positron:
×
169
          p.pdgcode = -11;
×
170
          break;
×
171
        }
172

173
        mcpl_add_particle(file_id, &p);
12,000✔
174
      }
175
    }
176
#ifdef OPENMC_MPI
177
    // Restore state of source bank
178
    std::copy(temp_source.begin(), temp_source.end(), source_bank.begin());
5✔
179
#endif
180
  } else {
5✔
181
#ifdef OPENMC_MPI
182
    MPI_Send(source_bank.data(), count_size, mpi::source_site, 0, mpi::rank,
5✔
183
      mpi::intracomm);
184
#endif
185
  }
186
}
17✔
187
#endif
188

189
//==============================================================================
190

191
void write_mcpl_source_point(const char* filename,
17✔
192
  gsl::span<SourceSite> source_bank, const vector<int64_t>& bank_index)
193
{
194
  std::string filename_(filename);
17✔
195
  const auto extension = get_file_extension(filename_);
17✔
196
  if (extension == "") {
17✔
UNCOV
197
    filename_.append(".mcpl");
×
198
  } else if (extension != "mcpl") {
17✔
199
    warning("write_mcpl_source_point was passed a file extension differing "
×
200
            "from .mcpl, but an mcpl file will be written.");
201
  }
202

203
#ifdef OPENMC_MCPL
204
  mcpl_outfile_t file_id;
205

206
  std::string line;
17✔
207
  if (mpi::master) {
17✔
208
    file_id = mcpl_create_outfile(filename_.c_str());
12✔
209
    if (VERSION_DEV) {
210
      line = fmt::format("OpenMC {0}.{1}.{2}-development", VERSION_MAJOR,
22✔
211
        VERSION_MINOR, VERSION_RELEASE);
12✔
212
    } else {
213
      line = fmt::format(
214
        "OpenMC {0}.{1}.{2}", VERSION_MAJOR, VERSION_MINOR, VERSION_RELEASE);
215
    }
216
    mcpl_hdr_set_srcname(file_id, line.c_str());
12✔
217
  }
218

219
  write_mcpl_source_bank(file_id, source_bank, bank_index);
17✔
220

221
  if (mpi::master) {
17✔
222
    mcpl_close_outfile(file_id);
12✔
223
  }
224
#endif
225
}
17✔
226

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

© 2025 Coveralls, Inc