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

openmc-dev / openmc / 37663791721

07 Oct 2026 06:02PM UTC coverage: 80.891% (-0.5%) from 81.396%
37663791721

push

github

web-flow
Broadcast tally results in chunks (#4125)

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Paul Romano <paul.k.romano@gmail.com>

18851 of 27271 branches covered (69.12%)

Branch coverage included in aggregate %.

13 of 13 new or added lines in 3 files covered. (100.0%)

722 existing lines in 40 files now uncovered.

60967 of 71403 relevant lines covered (85.38%)

29085075.4 hits per line

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

75.19
/src/initialize.cpp
1
#include "openmc/initialize.h"
2

3
#include <clocale>
4
#include <cstddef>
5
#include <cstdlib> // for getenv
6
#include <cstring>
7
#include <string>
8

9
#ifdef _OPENMP
10
#include <omp.h>
11
#endif
12
#include <fmt/core.h>
13

14
#include "openmc/capi.h"
15
#include "openmc/chain.h"
16
#include "openmc/constants.h"
17
#include "openmc/cross_sections.h"
18
#include "openmc/error.h"
19
#include "openmc/file_utils.h"
20
#include "openmc/geometry_aux.h"
21
#include "openmc/hdf5_interface.h"
22
#include "openmc/material.h"
23
#include "openmc/memory.h"
24
#include "openmc/message_passing.h"
25
#include "openmc/mgxs_interface.h"
26
#include "openmc/nuclide.h"
27
#include "openmc/openmp_interface.h"
28
#include "openmc/output.h"
29
#include "openmc/plot.h"
30
#include "openmc/random_lcg.h"
31
#include "openmc/settings.h"
32
#include "openmc/simulation.h"
33
#include "openmc/string_utils.h"
34
#include "openmc/summary.h"
35
#include "openmc/tallies/tally.h"
36
#include "openmc/thermal.h"
37
#include "openmc/timer.h"
38
#include "openmc/vector.h"
39
#include "openmc/weight_windows.h"
40

41
#ifdef OPENMC_LIBMESH_ENABLED
42
#include "libmesh/libmesh.h"
43
#endif
44

45
#ifdef OPENMC_XDG_ENABLED
46
#include "xdg/config.h"
47
#endif
48

49
int openmc_init(int argc, char* argv[], const void* intracomm)
3,391 ✔
50
{
51
  using namespace openmc;
3,391 ✔
52

53
#ifdef OPENMC_MPI
54
  // Check if intracomm was passed
55
  MPI_Comm comm;
1,045 ✔
56
  if (intracomm) {
1,045 ✔
57
    comm = *static_cast<const MPI_Comm*>(intracomm);
995 ✔
58
  } else {
59
    comm = MPI_COMM_WORLD;
60
  }
61

62
  // Initialize MPI for C++
63
  initialize_mpi(comm);
1,045 ✔
64
#endif
65

66
  // Parse command-line arguments
67
  int err = parse_command_line(argc, argv);
3,391 ✔
68
  if (err)
3,379 ✔
69
    return err;
70

71
#ifdef OPENMC_LIBMESH_ENABLED
72
  const int n_threads = num_threads();
73
  // initialize libMesh if it hasn't been initialized already
74
  // (if initialized externally, the libmesh_init object needs to be provided
75
  // also)
76
  if (!settings::libmesh_init && !libMesh::initialized()) {
77
#if defined(OPENMC_MPI) && defined(LIBMESH_HAVE_MPI)
78
    // Pass command line arguments, the OpenMC communicator, and thread count.
79
    // Because libMesh was not initialized, we assume that OpenMC is the primary
80
    // application and that its main MPI comm should be used.
81
    settings::libmesh_init =
82
      make_unique<libMesh::LibMeshInit>(argc, argv, comm, n_threads);
83
#else
84
    // libMesh was built without MPI, so use its serial communicator.
85
    settings::libmesh_init =
86
      make_unique<libMesh::LibMeshInit>(argc, argv, 0, n_threads);
87
#endif
88

89
    settings::libmesh_comm = &(settings::libmesh_init->comm());
90
  }
91

92
#if defined(OPENMC_XDG_ENABLED) && defined(XDG_ENABLE_LIBMESH)
93
  // Set the external libMesh initialization and communicator for XDG if
94
  // libMesh was initialized externally. If libMesh was initialized internally,
95
  // the XDG config will use the internal initialization and communicator.
96
  xdg::config::external_libmesh_init = settings::libmesh_init.get();
97
  xdg::config::external_libmesh_comm = settings::libmesh_comm;
98
#endif
99

100
#endif
101

102
  // Start total and initialization timer
103
  simulation::time_total.start();
3,375 ✔
104
  simulation::time_initialize.start();
3,375 ✔
105

106
#ifdef _OPENMP
107
  // If OMP_SCHEDULE is not set, default to a static schedule
108
  char* envvar = std::getenv("OMP_SCHEDULE");
109
  if (!envvar) {
110
    omp_set_schedule(omp_sched_static, 0);
111
  }
112
#endif
113

114
  // Initialize random number generator -- if the user specifies a seed and/or
115
  // stride, it will be re-initialized later
116
  openmc::openmc_set_seed(DEFAULT_SEED);
3,375 ✔
117
  openmc::openmc_set_stride(DEFAULT_STRIDE);
3,375 ✔
118

119
  // Copy previous locale and set locale to C. This is a workaround for an issue
120
  // whereby when openmc_init is called from the plotter, the Qt application
121
  // framework first calls std::setlocale, which affects how pugixml reads
122
  // floating point numbers due to a bug:
123
  // https://github.com/zeux/pugixml/issues/469
124
  std::string prev_locale = std::setlocale(LC_ALL, nullptr);
3,375 ✔
125
  if (std::setlocale(LC_ALL, "C") == NULL) {
3,375 !
126
    fatal_error("Cannot set locale to C.");
×
127
  }
128

129
  // Read XML input files
130
  if (!read_model_xml())
3,375 ✔
131
    read_separate_xml_files();
499 ✔
132

133
  if (!settings::properties_file.empty()) {
3,335 ✔
134
    openmc_properties_import(settings::properties_file.c_str());
4 ✔
135
  }
136

137
  // Reset locale to previous state
138
  if (std::setlocale(LC_ALL, prev_locale.c_str()) == NULL) {
3,335 !
139
    fatal_error("Cannot reset locale.");
×
140
  }
141

142
  // Write some initial output under the header if needed
143
  initial_output();
3,335 ✔
144

145
  // Check for particle restart run
146
  if (settings::particle_restart_run)
3,335 ✔
147
    settings::run_mode = RunMode::PARTICLE;
19 ✔
148

149
  // Stop initialization timer
150
  simulation::time_initialize.stop();
3,335 ✔
151
  simulation::time_total.stop();
3,335 ✔
152

153
  return 0;
3,335 ✔
154
}
3,339 ✔
155

156
namespace openmc {
157

158
#ifdef OPENMC_MPI
159
void initialize_mpi(MPI_Comm intracomm)
1,045 ✔
160
{
161
  mpi::intracomm = intracomm;
1,045 ✔
162

163
  // Initialize MPI
164
  int flag;
1,045 ✔
165
  MPI_Initialized(&flag);
1,045 ✔
166
  if (!flag)
1,045 ✔
167
    MPI_Init(nullptr, nullptr);
841 ✔
168

169
  // Determine number of processes and rank for each
170
  MPI_Comm_size(intracomm, &mpi::n_procs);
1,045 ✔
171
  MPI_Comm_rank(intracomm, &mpi::rank);
1,045 ✔
172
  mpi::master = (mpi::rank == 0);
1,045 ✔
173

174
  // Create bank datatype
175
  SourceSite b;
1,045 ✔
176
  MPI_Aint disp[15];
1,045 ✔
177
  MPI_Get_address(&b.r, &disp[0]);
1,045 ✔
178
  MPI_Get_address(&b.u, &disp[1]);
1,045 ✔
179
  MPI_Get_address(&b.E, &disp[2]);
1,045 ✔
180
  MPI_Get_address(&b.time, &disp[3]);
1,045 ✔
181
  MPI_Get_address(&b.wgt, &disp[4]);
1,045 ✔
182
  MPI_Get_address(&b.delayed_group, &disp[5]);
1,045 ✔
183
  MPI_Get_address(&b.surf_id, &disp[6]);
1,045 ✔
184
  MPI_Get_address(&b.particle, &disp[7]);
1,045 ✔
185
  MPI_Get_address(&b.parent_nuclide, &disp[8]);
1,045 ✔
186
  MPI_Get_address(&b.parent_id, &disp[9]);
1,045 ✔
187
  MPI_Get_address(&b.progeny_id, &disp[10]);
1,045 ✔
188
  MPI_Get_address(&b.wgt_born, &disp[11]);
1,045 ✔
189
  MPI_Get_address(&b.wgt_ww_born, &disp[12]);
1,045 ✔
190
  MPI_Get_address(&b.n_split, &disp[13]);
1,045 ✔
191
  MPI_Get_address(&b.n_collision, &disp[14]);
1,045 ✔
192
  for (int i = 14; i >= 0; --i) {
16,720 ✔
193
    disp[i] -= disp[0];
15,675 ✔
194
  }
195

196
  // Block counts for each field
197
  int blocks[] = {3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
1,045 ✔
198

199
  // Types for each field
200
  MPI_Datatype types[] = {
1,045 ✔
201
    MPI_DOUBLE,  // r (3 doubles)
202
    MPI_DOUBLE,  // u (3 doubles)
203
    MPI_DOUBLE,  // E
204
    MPI_DOUBLE,  // time
205
    MPI_DOUBLE,  // wgt
206
    MPI_INT,     // delayed_group
207
    MPI_INT,     // surf_id
208
    MPI_INT,     // particle (enum)
209
    MPI_INT,     // parent_nuclide
210
    MPI_INT64_T, // parent_id
211
    MPI_INT64_T, // progeny_id
212
    MPI_DOUBLE,  // wgt_born
213
    MPI_DOUBLE,  // wgt_ww_born
214
    MPI_INT64_T, // n_split
215
    MPI_INT      // n_collision
216
  };
217

218
  MPI_Type_create_struct(15, blocks, disp, types, &mpi::source_site);
1,045 ✔
219
  MPI_Type_commit(&mpi::source_site);
1,045 ✔
220

221
  CollisionTrackSite bc;
1,045 ✔
222
  MPI_Aint dispc[16];
1,045 ✔
223
  MPI_Get_address(&bc.r, &dispc[0]);             // double
1,045 ✔
224
  MPI_Get_address(&bc.u, &dispc[1]);             // double
1,045 ✔
225
  MPI_Get_address(&bc.E, &dispc[2]);             // double
1,045 ✔
226
  MPI_Get_address(&bc.dE, &dispc[3]);            // double
1,045 ✔
227
  MPI_Get_address(&bc.time, &dispc[4]);          // double
1,045 ✔
228
  MPI_Get_address(&bc.wgt, &dispc[5]);           // double
1,045 ✔
229
  MPI_Get_address(&bc.event_mt, &dispc[6]);      // int
1,045 ✔
230
  MPI_Get_address(&bc.delayed_group, &dispc[7]); // int
1,045 ✔
231
  MPI_Get_address(&bc.cell_id, &dispc[8]);       // int
1,045 ✔
232
  MPI_Get_address(&bc.nuclide_id, &dispc[9]);    // int
1,045 ✔
233
  MPI_Get_address(&bc.material_id, &dispc[10]);  // int
1,045 ✔
234
  MPI_Get_address(&bc.universe_id, &dispc[11]);  // int
1,045 ✔
235
  MPI_Get_address(&bc.n_collision, &dispc[12]);  // int
1,045 ✔
236
  MPI_Get_address(&bc.particle, &dispc[13]);     // int
1,045 ✔
237
  MPI_Get_address(&bc.parent_id, &dispc[14]);    // int64_t
1,045 ✔
238
  MPI_Get_address(&bc.progeny_id, &dispc[15]);   // int64_t
1,045 ✔
239
  for (int i = 15; i >= 0; --i) {
17,765 ✔
240
    dispc[i] -= dispc[0];
16,720 ✔
241
  }
242

243
  int blocksc[] = {3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
1,045 ✔
244
  MPI_Datatype typesc[] = {MPI_DOUBLE, MPI_DOUBLE, MPI_DOUBLE, MPI_DOUBLE,
1,045 ✔
245
    MPI_DOUBLE, MPI_DOUBLE, MPI_INT, MPI_INT, MPI_INT, MPI_INT, MPI_INT,
246
    MPI_INT, MPI_INT, MPI_INT, MPI_INT64_T, MPI_INT64_T};
247

248
  MPI_Type_create_struct(
1,045 ✔
249
    16, blocksc, dispc, typesc, &mpi::collision_track_site);
250
  MPI_Type_commit(&mpi::collision_track_site);
1,045 ✔
251
}
1,045 ✔
252
#endif // OPENMC_MPI
253

254
int parse_command_line(int argc, char* argv[])
3,391 ✔
255
{
256
  int last_flag = 0;
3,391 ✔
257
  for (int i = 1; i < argc; ++i) {
3,909 ✔
258
    std::string arg {argv[i]};
522 ✔
259
    if (arg[0] == '-') {
522 ✔
260
      if (arg == "-p" || arg == "--plot") {
928 !
261
        settings::run_mode = RunMode::PLOTTING;
44 ✔
262
        settings::check_overlaps = true;
44 ✔
263

264
      } else if (arg == "-n" || arg == "--particles") {
880 !
265
        i += 1;
4 ✔
266
        settings::n_particles = std::stoll(argv[i]);
8 ✔
267

268
      } else if (arg == "-q" || arg == "--verbosity") {
876 !
269
        i += 1;
×
270
        settings::verbosity = std::stoi(argv[i]);
×
271
        if (settings::verbosity > 10 || settings::verbosity < 1) {
×
272
          auto msg = fmt::format("Invalid verbosity: {}.", settings::verbosity);
×
273
          set_errmsg(msg);
×
274
          return OPENMC_E_INVALID_ARGUMENT;
×
275
        }
×
276

277
      } else if (arg == "-e" || arg == "--event") {
876 !
UNCOV
278
        settings::event_based = true;
×
279
      } else if (arg == "-r" || arg == "--restart") {
830 !
280
        i += 1;
46 ✔
281
        // Check what type of file this is
282
        hid_t file_id = file_open(argv[i], 'r', true);
46 ✔
283
        std::string filetype;
46 ✔
284
        read_attribute(file_id, "filetype", filetype);
46 ✔
285
        file_close(file_id);
46 ✔
286

287
        // Set path and flag for type of run
288
        if (filetype == "statepoint") {
46 ✔
289
          settings::path_statepoint = argv[i];
27 ✔
290
          settings::restart_run = true;
27 ✔
291
        } else if (filetype == "particle restart") {
19 !
292
          settings::path_particle_restart = argv[i];
19 ✔
293
          settings::particle_restart_run = true;
19 ✔
294
        } else {
295
          auto msg =
×
296
            fmt::format("Unrecognized file after restart flag: {}.", filetype);
×
297
          set_errmsg(msg);
×
298
          return OPENMC_E_INVALID_ARGUMENT;
×
299
        }
×
300

301
        // If its a restart run check for additional source file
302
        if (settings::restart_run && i + 1 < argc) {
46 !
303
          // Check if it has extension we can read
304
          if (ends_with(argv[i + 1], ".h5")) {
×
305

306
            // Check file type is a source file
307
            file_id = file_open(argv[i + 1], 'r', true);
×
308
            read_attribute(file_id, "filetype", filetype);
×
309
            file_close(file_id);
×
310
            if (filetype != "source") {
×
311
              std::string msg {
×
312
                "Second file after restart flag must be a source file"};
×
313
              set_errmsg(msg);
×
314
              return OPENMC_E_INVALID_ARGUMENT;
×
315
            }
×
316

317
            // It is a source file
318
            settings::path_sourcepoint = argv[i + 1];
46 !
319
            i += 1;
320

321
          } else {
322
            // Source is in statepoint file
323
            settings::path_sourcepoint = settings::path_statepoint;
×
324
          }
325

326
        } else {
327
          // Source is assumed to be in statepoint file
328
          settings::path_sourcepoint = settings::path_statepoint;
92 ✔
329
        }
330

331
      } else if (arg == "-g" || arg == "--geometry-debug") {
830 !
332
        settings::check_overlaps = true;
×
333
      } else if (arg == "-c" || arg == "--volume") {
464 ✔
334
        settings::run_mode = RunMode::VOLUME;
352 ✔
335
      } else if (arg == "-s" || arg == "--threads") {
63 !
336
        // Read number of threads
337
        if (i + 1 >= argc) {
17 !
338
          std::string msg {"Number of threads not specified."};
×
339
          set_errmsg(msg);
×
340
          return OPENMC_E_INVALID_ARGUMENT;
×
341
        }
×
342
        i += 1;
17 ✔
343

344
#ifdef _OPENMP
345
        // Read and set number of OpenMP threads
346
        int n_threads = std::stoi(argv[i]);
347
        if (n_threads < 1) {
348
          std::string msg {"Number of threads must be positive."};
349
          set_errmsg(msg);
350
          return OPENMC_E_INVALID_ARGUMENT;
351
        }
352
        omp_set_num_threads(n_threads);
353
#else
354
        if (mpi::master) {
17 ✔
355
          warning("Ignoring number of threads specified on command line.");
32 ✔
356
        }
357
#endif
358

359
      } else if (arg == "-?" || arg == "-h" || arg == "--help") {
69 !
360
        print_usage();
×
361
        return OPENMC_E_UNASSIGNED;
362

363
      } else if (arg == "-v" || arg == "--version") {
42 !
364
        print_version();
4 ✔
365
        print_build_info();
4 ✔
366
        return OPENMC_E_UNASSIGNED;
367

368
      } else if (arg == "-t" || arg == "--track") {
19 !
369
        settings::write_all_tracks = true;
19 ✔
370

371
      } else {
372
        fmt::print(stderr, "Unknown option: {}\n", argv[i]);
×
373
        print_usage();
×
374
        return OPENMC_E_UNASSIGNED;
375
      }
376

377
      last_flag = i;
378
    }
379
  }
522 ✔
380

381
  // Determine directory where XML input files are
382
  if (argc > 1 && last_flag < argc - 1) {
3,387 ✔
383
    settings::path_input = std::string(argv[last_flag + 1]);
36 ✔
384

385
    // check that the path is either a valid directory or file
386
    if (!dir_exists(settings::path_input) &&
68 ✔
387
        !file_exists(settings::path_input)) {
32 ✔
388
      fatal_error(fmt::format(
12 ✔
389
        "The path specified to the OpenMC executable '{}' does not exist.",
390
        settings::path_input));
391
    }
392

393
    // Add slash at end of directory if it isn't there
394
    if (!ends_with(settings::path_input, "/") &&
72 !
395
        dir_exists(settings::path_input)) {
24 ✔
396
      settings::path_input += "/";
3,379 ✔
397
    }
398
  }
399

400
  return 0;
401
}
402

403
// TODO: Pulse-height tallies require per-history scoring across the full
404
// particle tree (parent + all descendants). The shared secondary bank
405
// transports each secondary as an independent Particle, breaking this
406
// assumption. A proper fix would defer pulse-height scoring: save
407
// (root_source_id, cell, pht_storage) per particle, then aggregate by
408
// root_source_id after all secondary generations complete before scoring
409
// into the histogram. For now, disable shared secondary when pulse-height
410
// tallies are present.
411
static void check_pulse_height_compatibility()
3,339 ✔
412
{
413
  if (settings::use_shared_secondary_bank) {
3,339 ✔
414
    for (const auto& t : model::tallies) {
266 ✔
415
      if (t->type_ == TallyType::PULSE_HEIGHT) {
162 ✔
416
        settings::use_shared_secondary_bank = false;
15 ✔
417
        warning("Pulse-height tallies are not yet compatible with the shared "
15 ✔
418
                "secondary bank. Disabling shared secondary bank.");
419
        break;
15 ✔
420
      }
421
    }
422
  }
423
}
3,339 ✔
424

425
bool read_model_xml()
3,375 ✔
426
{
427
  std::string model_filename = settings::path_input;
3,375 ✔
428

429
  // if the current filename is a directory, append the default model filename
430
  if (model_filename.empty() || dir_exists(model_filename))
3,375 ✔
431
    model_filename += "model.xml";
3,355 ✔
432

433
  // if this file doesn't exist, stop here
434
  if (!file_exists(model_filename))
3,375 ✔
435
    return false;
436

437
  // try to process the path input as an XML file
438
  pugi::xml_document doc;
2,876 ✔
439
  if (!doc.load_file(model_filename.c_str())) {
2,876 !
440
    fatal_error(fmt::format(
×
441
      "Error reading from single XML input file '{}'", model_filename));
442
  }
443

444
  pugi::xml_node root = doc.document_element();
2,876 ✔
445

446
  // Read settings
447
  if (!check_for_node(root, "settings")) {
2,876 !
448
    fatal_error("No <settings> node present in the model.xml file.");
×
449
  }
450
  auto settings_root = root.child("settings");
2,876 ✔
451

452
  // Verbosity
453
  if (check_for_node(settings_root, "verbosity") && settings::verbosity == -1) {
2,876 !
454
    settings::verbosity = std::stoi(get_node_value(settings_root, "verbosity"));
20 ✔
455
  } else if (settings::verbosity == -1) {
2,866 !
456
    settings::verbosity = 7;
2,866 ✔
457
  }
458

459
  // To this point, we haven't displayed any output since we didn't know what
460
  // the verbosity is. Now that we checked for it, show the title if necessary
461
  if (mpi::master) {
2,876 ✔
462
    if (settings::verbosity >= 2)
2,658 ✔
463
      title();
2,650 ✔
464
  }
465

466
  write_message(
2,876 ✔
467
    fmt::format("Reading model XML file '{}' ...", model_filename), 5);
2,876 ✔
468

469
  // Read chain data before settings so DecaySpectrum source distributions can
470
  // resolve nuclides while sources are constructed.
471
  read_chain_file_xml();
2,876 ✔
472

473
  read_settings_xml(settings_root);
2,876 ✔
474

475
  // If other XML files are present, display warning
476
  // that they will be ignored
477
  auto other_inputs = {"materials.xml", "geometry.xml", "settings.xml",
2,852 ✔
478
    "tallies.xml", "plots.xml"};
2,852 ✔
479
  for (const auto& input : other_inputs) {
16,815 ✔
480
    if (file_exists(settings::path_input + input)) {
14,034 ✔
481
      warning((fmt::format("Other XML file input(s) are present. These files "
71 ✔
482
                           "may be ignored in favor of the {} file.",
483
        model_filename)));
484
      break;
71 ✔
485
    }
486
  }
487

488
  // Read materials and cross sections
489
  if (!check_for_node(root, "materials")) {
2,852 !
490
    fatal_error(fmt::format(
×
491
      "No <materials> node present in the {} file.", model_filename));
492
  }
493

494
  if (settings::run_mode != RunMode::PLOTTING) {
2,852 ✔
495
    read_cross_sections_xml(root.child("materials"));
2,820 ✔
496
  }
497
  read_materials_xml(root.child("materials"));
2,852 ✔
498

499
  // Read geometry
500
  if (!check_for_node(root, "geometry")) {
2,852 !
501
    fatal_error(fmt::format(
×
502
      "No <geometry> node present in the {} file.", model_filename));
503
  }
504
  read_geometry_xml(root.child("geometry"));
2,852 ✔
505

506
  // Final geometry setup and assign temperatures
507
  finalize_geometry();
2,852 ✔
508

509
  // Finalize cross sections having assigned temperatures
510
  finalize_cross_sections();
2,852 ✔
511

512
  // Compute cell density multipliers now that material densities
513
  // have been finalized (from geometry_aux.h)
514
  finalize_cell_densities();
2,852 ✔
515

516
  if (check_for_node(root, "tallies"))
2,852 ✔
517
    read_tallies_xml(root.child("tallies"));
1,671 ✔
518

519
  check_pulse_height_compatibility();
2,844 ✔
520

521
  // Initialize distribcell_filters
522
  prepare_distribcell();
2,844 ✔
523

524
  if (check_for_node(root, "plots")) {
2,844 ✔
525
    read_plots_xml(root.child("plots"));
181 ✔
526
  } else {
527
    // When no <plots> element is present in the model.xml file, check for a
528
    // regular plots.xml file
529
    std::string filename = settings::path_input + "plots.xml";
2,663 ✔
530
    if (file_exists(filename)) {
2,663 !
531
      read_plots_xml();
×
532
    }
533
  }
2,663 ✔
534

535
  finalize_variance_reduction();
2,840 ✔
536

537
  return true;
2,840 ✔
538
}
6,179 ✔
539

540
void read_separate_xml_files()
499 ✔
541
{
542
  // Read chain data before settings so DecaySpectrum source distributions can
543
  // resolve nuclides while sources are constructed.
544
  read_chain_file_xml();
499 ✔
545

546
  read_settings_xml();
499 ✔
547
  if (settings::run_mode != RunMode::PLOTTING) {
495 ✔
548
    read_cross_sections_xml();
483 ✔
549
  }
550

551
  read_materials_xml();
495 ✔
552
  read_geometry_xml();
495 ✔
553

554
  // Final geometry setup and assign temperatures
555
  finalize_geometry();
495 ✔
556

557
  // Finalize cross sections having assigned temperatures
558
  finalize_cross_sections();
495 ✔
559

560
  // Compute cell density multipliers now that material densities
561
  // have been finalized (from geometry_aux.h)
562
  finalize_cell_densities();
495 ✔
563

564
  read_tallies_xml();
495 ✔
565

566
  check_pulse_height_compatibility();
495 ✔
567

568
  // Initialize distribcell_filters
569
  prepare_distribcell();
495 ✔
570

571
  // Read the plots.xml regardless of plot mode in case plots are requested
572
  // via the API
573
  read_plots_xml();
495 ✔
574

575
  finalize_variance_reduction();
495 ✔
576
}
495 ✔
577

578
void initial_output()
3,335 ✔
579
{
580
  // write initial output
581
  if (settings::run_mode == RunMode::PLOTTING) {
3,335 ✔
582
    // Read plots.xml if it exists
583
    if (mpi::master && settings::verbosity >= 5)
40 !
584
      print_plot();
32 ✔
585

586
  } else {
587
    // Write summary information
588
    if (mpi::master && settings::output_summary)
3,295 ✔
589
      write_summary();
2,877 ✔
590

591
    // Warn if overlap checking is on
592
    if (mpi::master && settings::check_overlaps) {
3,295 !
593
      warning("Cell overlap checking is ON.");
×
594
    }
595
  }
596
}
3,335 ✔
597

598
} // namespace openmc
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc