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

openmc-dev / openmc / 22070080915

16 Feb 2026 04:15PM UTC coverage: 81.702% (-0.02%) from 81.72%
22070080915

Pull #3806

github

web-flow
Merge 4824efac8 into c6ef84d1d
Pull Request #3806: Introduce new C API function for slice plots

17579 of 24709 branches covered (71.14%)

Branch coverage included in aggregate %.

197 of 245 new or added lines in 4 files covered. (80.41%)

336 existing lines in 26 files now uncovered.

57190 of 66805 relevant lines covered (85.61%)

50553675.8 hits per line

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

91.67
/include/openmc/plot.h
1
#ifndef OPENMC_PLOT_H
2
#define OPENMC_PLOT_H
3

4
#include <cmath>
5
#include <sstream>
6
#include <unordered_map>
7
#include <unordered_set>
8

9
#include "pugixml.hpp"
10
#include "xtensor/xarray.hpp"
11

12
#include "hdf5.h"
13
#include "openmc/cell.h"
14
#include "openmc/constants.h"
15
#include "openmc/error.h"
16
#include "openmc/geometry.h"
17
#include "openmc/particle.h"
18
#include "openmc/position.h"
19
#include "openmc/random_lcg.h"
20
#include "openmc/tallies/filter.h"
21
#include "openmc/tallies/filter_match.h"
22
#include "openmc/xml_interface.h"
23

24
namespace openmc {
25

26
//===============================================================================
27
// Global variables
28
//===============================================================================
29

30
class PlottableInterface;
31

32
namespace model {
33

34
extern std::unordered_map<int, int> plot_map; //!< map of plot ids to index
35
extern vector<std::unique_ptr<PlottableInterface>>
36
  plots; //!< Plot instance container
37

38
extern uint64_t plotter_seed; // Stream index used by the plotter
39

40
} // namespace model
41

42
//===============================================================================
43
// RGBColor holds color information for plotted objects
44
//===============================================================================
45

46
struct RGBColor {
47
  // Constructors
48
  RGBColor() : red(0), green(0), blue(0) {};
12,074,516✔
49
  RGBColor(const int v[3]) : red(v[0]), green(v[1]), blue(v[2]) {};
50
  RGBColor(int r, int g, int b) : red(r), green(g), blue(b) {};
164,861✔
51

52
  RGBColor(const vector<int>& v)
280✔
53
  {
280✔
54
    if (v.size() != 3) {
280!
55
      throw std::out_of_range("Incorrect vector size for RGBColor.");
×
56
    }
57
    red = v[0];
280✔
58
    green = v[1];
280✔
59
    blue = v[2];
280✔
60
  }
280✔
61

62
  bool operator==(const RGBColor& other)
6,168✔
63
  {
64
    return red == other.red && green == other.green && blue == other.blue;
6,168!
65
  }
66

67
  RGBColor& operator*=(const double x)
674,210✔
68
  {
69
    red *= x;
674,210✔
70
    green *= x;
674,210✔
71
    blue *= x;
674,210✔
72
    return *this;
674,210✔
73
  }
74

75
  // Members
76
  uint8_t red, green, blue;
77
};
78

79
// some default colors
80
const RGBColor WHITE {255, 255, 255};
81
const RGBColor RED {255, 0, 0};
82
const RGBColor BLACK {0, 0, 0};
83

84
/**
85
 * \class PlottableInterface
86
 * \brief Interface for plottable objects.
87
 *
88
 * PlottableInterface classes must have unique IDs. If no ID (or -1) is
89
 * provided, the next available ID is assigned automatically. They guarantee
90
 * the ability to create output in some form. This interface is designed to be
91
 * implemented by classes that produce plot-relevant data which can be
92
 * visualized.
93
 */
94

95
typedef xt::xtensor<RGBColor, 2> ImageData;
96
class PlottableInterface {
97
public:
98
  PlottableInterface() = default;
10✔
99

100
  void set_default_colors();
101

102
private:
103
  void set_id(pugi::xml_node plot_node);
104
  int id_ {C_NONE}; // unique plot ID
105

106
  void set_bg_color(pugi::xml_node plot_node);
107
  void set_universe(pugi::xml_node plot_node);
108
  void set_color_by(pugi::xml_node plot_node);
109
  void set_user_colors(pugi::xml_node plot_node);
110
  void set_overlap_color(pugi::xml_node plot_node);
111
  void set_mask(pugi::xml_node plot_node);
112

113
protected:
114
  // Plot output filename, derived classes have logic to set it
115
  std::string path_plot_;
116

117
public:
118
  enum class PlotColorBy { cells = 0, mats = 1 };
119

120
  // Generates image data based on plot parameters and returns it
121
  virtual ImageData create_image() const = 0;
122

123
  // Creates the output image named path_plot_
124
  virtual void create_output() const = 0;
125

126
  // Write populated image data to file
127
  void write_image(const ImageData& data) const;
128

129
  // Print useful info to the terminal
130
  virtual void print_info() const = 0;
131

132
  const std::string& path_plot() const { return path_plot_; }
210✔
133
  std::string& path_plot() { return path_plot_; }
490✔
134
  int id() const { return id_; }
1,994✔
135
  void set_id(int id = C_NONE);
136
  int level() const { return level_; }
220✔
137
  PlotColorBy color_by() const { return color_by_; }
138

139
  // Public color-related data
140
  PlottableInterface(pugi::xml_node plot_node);
141
  virtual ~PlottableInterface() = default;
874✔
142
  int level_ {-1};                           // Universe level to plot
143
  bool color_overlaps_ {false};              // Show overlapping cells?
144
  PlotColorBy color_by_ {PlotColorBy::mats}; // Plot coloring (cell/material)
145
  RGBColor not_found_ {WHITE};               // Plot background color
146
  RGBColor overlap_color_ {RED};             // Plot overlap color
147
  vector<RGBColor> colors_;                  // Plot colors
148
};
149

150
struct IdData {
151
  // Constructor
152
  IdData(size_t h_res, size_t v_res, bool include_filter = false);
153

154
  // Methods
155
  void set_value(size_t y, size_t x, const Particle& p, int level,
156
    Filter* filter = nullptr, FilterMatch* match = nullptr);
157
  void set_overlap(size_t y, size_t x);
158

159
  // Members
160
  xt::xtensor<int32_t, 3> data_; //!< 3D array of cell ID, cell instance,
161
                                 //!< and material ID
162
};
163

164
struct PropertyData {
165
  // Constructor
166
  PropertyData(size_t h_res, size_t v_res, bool include_filter = false);
167

168
  // Methods
169
  void set_value(size_t y, size_t x, const Particle& p, int level,
170
    Filter* filter = nullptr, FilterMatch* match = nullptr);
171
  void set_overlap(size_t y, size_t x);
172

173
  // Members
174
  xt::xtensor<double, 3> data_; //!< 2D array of temperature & density data
175
};
176

177
struct RasterData {
178
  // Constructor
179
  RasterData(size_t h_res, size_t v_res, bool include_filter = false);
180

181
  // Methods
182
  void set_value(size_t y, size_t x, const Particle& p, int level,
183
    Filter* filter = nullptr, FilterMatch* match = nullptr);
184
  void set_overlap(size_t y, size_t x);
185

186
  // Members
187
  xt::xtensor<int32_t, 3>
188
    id_data_; //!< [v_res, h_res, 3 or 4]: cell, instance, mat, [filter_bin]
189
  xt::xtensor<double, 3>
190
    property_data_;     //!< [v_res, h_res, 2]: temperature, density
191
  bool include_filter_; //!< Whether filter bin index is included
192
};
193

194
//===============================================================================
195
// Plot class
196
//===============================================================================
197

198
class SlicePlotBase {
199
public:
200
  template<class T>
201
  T get_map(int32_t filter_index = -1) const;
202

203
  enum class PlotBasis { xy = 1, xz = 2, yz = 3 };
204

205
  // Accessors
206

207
  const std::array<size_t, 3>& pixels() const { return pixels_; }
106,430✔
208
  std::array<size_t, 3>& pixels() { return pixels_; }
1,668✔
209

210
  // Members
211
public:
212
  Position origin_;           //!< Plot origin in geometry
213
  Position u_span_;           //!< Full-width span vector in geometry
214
  Position v_span_;           //!< Full-height span vector in geometry
215
  Position width_;            //!< Axis-aligned plot width in geometry
216
  PlotBasis basis_;           //!< Plot basis (XY/XZ/YZ) for axis-aligned slices
217
  array<size_t, 3> pixels_;   //!< Plot size in pixels
218
  bool slice_color_overlaps_; //!< Show overlapping cells?
219
  int slice_level_ {-1};      //!< Plot universe level
220
private:
221
};
222

223
template<class T>
224
T SlicePlotBase::get_map(int32_t filter_index) const
4,793✔
225
{
226

227
  size_t width = pixels_[0];
4,793✔
228
  size_t height = pixels_[1];
4,793✔
229

230
  // Determine if filter is being used
231
  bool include_filter = (filter_index >= 0);
4,793✔
232
  Filter* filter = nullptr;
4,793✔
233
  if (include_filter) {
4,793✔
234
    filter = model::tally_filters[filter_index].get();
20✔
235
  }
236

237
  // size data array
238
  T data(width, height, include_filter);
4,793✔
239

240
  // compute pixel steps and top-left pixel center
241
  Position u_step = u_span_ / static_cast<double>(width);
4,793✔
242
  Position v_step = v_span_ / static_cast<double>(height);
4,793✔
243

244
  Position start =
245
    origin_ - 0.5 * u_span_ + 0.5 * v_span_ + 0.5 * u_step - 0.5 * v_step;
4,793✔
246

247
  // Validate that span vectors define a valid plane
248
  Position cross = u_span_.cross(v_span_);
4,793✔
249
  if (cross.norm() == 0.0) {
4,793!
NEW
250
    fatal_error("Slice span vectors are invalid (zero area).");
×
251
  }
252

253
  // Use an arbitrary direction that is not aligned with any coordinate axis.
254
  // The direction has no physical meaning for plotting but is used by
255
  // Surface::sense() to break ties when a pixel is coincident with a surface.
256
  Direction dir = {1.0 / std::sqrt(2.0), 1.0 / std::sqrt(2.0), 0.0};
4,793✔
257

258
#pragma omp parallel
2,877✔
259
  {
260
    Particle p;
1,916✔
261
    p.r() = start;
1,916✔
262
    p.u() = dir;
1,916✔
263
    p.coord(0).universe() = model::root_universe;
1,916✔
264
    int level = slice_level_;
1,916✔
265
    int j {};
1,916✔
266
    FilterMatch match;
1,916✔
267

268
#pragma omp for
269
    for (int y = 0; y < height; y++) {
354,908✔
270
      Position row = start - v_step * static_cast<double>(y);
352,992✔
271
      for (int x = 0; x < width; x++) {
69,856,512✔
272
        p.r() = row + u_step * static_cast<double>(x);
69,503,520✔
273
        p.n_coord() = 1;
69,503,520✔
274
        // local variables
275
        bool found_cell = exhaustive_find_cell(p);
69,503,520✔
276
        j = p.n_coord() - 1;
69,503,520✔
277
        if (level >= 0) {
69,503,520✔
278
          j = level;
10,000✔
279
        }
280
        if (found_cell) {
69,503,520✔
281
          data.set_value(y, x, p, j, filter, &match);
14,148,152✔
282
        }
283
        if (slice_color_overlaps_ && check_cell_overlap(p, false)) {
69,503,520✔
284
          data.set_overlap(y, x);
136,112✔
285
        }
286
      } // inner for
287
    }
288
  }
1,916✔
289

290
  return data;
9,586✔
291
}
×
292

293
// Represents either a voxel or pixel plot
294
class Plot : public PlottableInterface, public SlicePlotBase {
295

296
public:
297
  enum class PlotType { slice = 1, voxel = 2 };
298

299
  Plot(pugi::xml_node plot, PlotType type);
300

301
private:
302
  void set_output_path(pugi::xml_node plot_node);
303
  void set_basis(pugi::xml_node plot_node);
304
  void set_origin(pugi::xml_node plot_node);
305
  void set_width(pugi::xml_node plot_node);
306
  void set_meshlines(pugi::xml_node plot_node);
307

308
public:
309
  // Add mesh lines to ImageData
310
  void draw_mesh_lines(ImageData& data) const;
311
  ImageData create_image() const override;
312
  void create_voxel() const;
313

314
  void create_output() const override;
315
  void print_info() const override;
316

317
  PlotType type_;                 //!< Plot type (Slice/Voxel)
318
  int meshlines_width_;           //!< Width of lines added to the plot
319
  int index_meshlines_mesh_ {-1}; //!< Index of the mesh to draw on the plot
320
  RGBColor meshlines_color_;      //!< Color of meshlines on the plot
321
};
322

323
/**
324
 * \class RaytracePlot
325
 * \brief Base class for plots that generate images through ray tracing.
326
 *
327
 * This class serves as a base for plots that create their visuals by tracing
328
 * rays from a camera through the problem geometry. It inherits from
329
 * PlottableInterface, ensuring that it provides an implementation for
330
 * generating output specific to ray-traced visualization. WireframeRayTracePlot
331
 * and SolidRayTracePlot provide concrete implementations of this class.
332
 */
333
class RayTracePlot : public PlottableInterface {
334
public:
335
  RayTracePlot() = default;
10✔
336
  RayTracePlot(pugi::xml_node plot);
337

338
  // Standard getters. No setting since it's done from XML.
339
  const Position& camera_position() const { return camera_position_; }
102,980✔
340
  Position& camera_position() { return camera_position_; }
40✔
341
  const Position& look_at() const { return look_at_; }
342
  Position& look_at() { return look_at_; }
20✔
343

344
  const double& horizontal_field_of_view() const
345
  {
346
    return horizontal_field_of_view_;
347
  }
348
  double& horizontal_field_of_view() { return horizontal_field_of_view_; }
20✔
349

350
  void print_info() const override;
351

352
  const std::array<int, 2>& pixels() const { return pixels_; }
13,725,752✔
353
  std::array<int, 2>& pixels() { return pixels_; }
280✔
354

355
  const Direction& up() const { return up_; }
356
  Direction& up() { return up_; }
20✔
357

358
  //! brief Updates the cached camera-to-model matrix after changes to
359
  //! camera parameters.
360
  void update_view();
361

362
protected:
363
  Direction camera_x_axis() const
400,000✔
364
  {
365
    return {camera_to_model_[0], camera_to_model_[3], camera_to_model_[6]};
400,000✔
366
  }
367

368
  Direction camera_y_axis() const
400,000✔
369
  {
370
    return {camera_to_model_[1], camera_to_model_[4], camera_to_model_[7]};
400,000✔
371
  }
372

373
  Direction camera_z_axis() const
400,000✔
374
  {
375
    return {camera_to_model_[2], camera_to_model_[5], camera_to_model_[8]};
400,000✔
376
  }
377

378
  void set_output_path(pugi::xml_node plot_node);
379

380
  /*
381
   * Gets the starting position and direction for the pixel corresponding
382
   * to this horizontal and vertical position.
383
   */
384
  std::pair<Position, Direction> get_pixel_ray(int horiz, int vert) const;
385

386
private:
387
  void set_look_at(pugi::xml_node node);
388
  void set_camera_position(pugi::xml_node node);
389
  void set_field_of_view(pugi::xml_node node);
390
  void set_pixels(pugi::xml_node node);
391
  void set_orthographic_width(pugi::xml_node node);
392

393
  double horizontal_field_of_view_ {70.0}; // horiz. f.o.v. in degrees
394
  Position camera_position_;               // where camera is
395
  Position look_at_;                     // point camera is centered looking at
396
  std::array<int, 2> pixels_ {100, 100}; // pixel dimension of resulting image
397
  Direction up_ {0.0, 0.0, 1.0};         // which way is up
398

399
  /* The horizontal thickness, if using an orthographic projection.
400
   * If set to zero, we assume using a perspective projection.
401
   */
402
  double orthographic_width_ {C_NONE};
403

404
  /*
405
   * Cached camera-to-model matrix with column vectors of axes. The x-axis is
406
   * the vector between the camera_position_ and look_at_; the y-axis is the
407
   * cross product of the x-axis with the up_ vector, and the z-axis is the
408
   * cross product of the x and y axes.
409
   */
410
  std::array<double, 9> camera_to_model_;
411
};
412

413
class ProjectionRay;
414

415
/**
416
 * \class WireframeRayTracePlot
417
 * \brief Creates plots that are like colorful x-ray imaging
418
 *
419
 * WireframeRayTracePlot is a specialized form of RayTracePlot designed for
420
 * creating projection plots. This involves tracing rays from a camera through
421
 * the problem geometry and rendering the results based on depth of penetration
422
 * through materials or cells and their colors.
423
 */
424
class WireframeRayTracePlot : public RayTracePlot {
425

426
  friend class ProjectionRay;
427

428
public:
429
  WireframeRayTracePlot(pugi::xml_node plot);
430

431
  ImageData create_image() const override;
432
  void create_output() const override;
433
  void print_info() const override;
434

435
private:
436
  void set_opacities(pugi::xml_node node);
437
  void set_wireframe_thickness(pugi::xml_node node);
438
  void set_wireframe_ids(pugi::xml_node node);
439
  void set_wireframe_color(pugi::xml_node node);
440

441
  /* Checks if a vector of two TrackSegments is equivalent. We define this
442
   * to mean not having matching intersection lengths, but rather having
443
   * a matching sequence of surface/cell/material intersections.
444
   */
445
  struct TrackSegment;
446
  bool trackstack_equivalent(const vector<TrackSegment>& track1,
447
    const vector<TrackSegment>& track2) const;
448

449
  /* Used for drawing wireframe and colors. We record the list of
450
   * surface/cell/material intersections and the corresponding lengths as a ray
451
   * traverses the geometry, then color by iterating in reverse.
452
   */
453
  struct TrackSegment {
454
    int id;        // material or cell ID (which is being colored)
455
    double length; // length of this track intersection
456

457
    /* Recording this allows us to draw edges on the wireframe. For instance
458
     * if two surfaces bound a single cell, it allows drawing that sharp edge
459
     * where the surfaces intersect.
460
     */
461
    int surface_index {-1}; // last surface index intersected in this segment
462
    TrackSegment(int id_a, double length_a, int surface_a)
2,144,680✔
463
      : id(id_a), length(length_a), surface_index(surface_a)
2,144,680✔
464
    {}
2,144,680✔
465
  };
466

467
  // which color IDs should be wireframed. If empty, all cells are wireframed.
468
  vector<int> wireframe_ids_;
469

470
  // Thickness of the wireframe lines. Can set to zero for no wireframe.
471
  int wireframe_thickness_ {1};
472

473
  RGBColor wireframe_color_ {BLACK}; // wireframe color
474
  vector<double> xs_; // macro cross section values for cell volume rendering
475
};
476

477
/**
478
 * \class SolidRayTracePlot
479
 * \brief Plots 3D objects as the eye might see them.
480
 *
481
 * Plots a geometry with single-scattered Phong lighting plus a diffuse lighting
482
 * contribution. The result is a physically reasonable, aesthetic 3D view of a
483
 * geometry.
484
 */
485
class SolidRayTracePlot : public RayTracePlot {
486
  friend class PhongRay;
487

488
public:
489
  SolidRayTracePlot() = default;
10✔
490

491
  SolidRayTracePlot(pugi::xml_node plot);
492

493
  ImageData create_image() const override;
494
  void create_output() const override;
495
  void print_info() const override;
496

497
  const std::unordered_set<int>& opaque_ids() const { return opaque_ids_; }
498
  std::unordered_set<int>& opaque_ids() { return opaque_ids_; }
20✔
499

500
  const Position& light_location() const { return light_location_; }
501
  Position& light_location() { return light_location_; }
20✔
502

503
  const double& diffuse_fraction() const { return diffuse_fraction_; }
504
  double& diffuse_fraction() { return diffuse_fraction_; }
20✔
505

506
private:
507
  void set_opaque_ids(pugi::xml_node node);
508
  void set_light_position(pugi::xml_node node);
509
  void set_diffuse_fraction(pugi::xml_node node);
510

511
  std::unordered_set<int> opaque_ids_;
512

513
  double diffuse_fraction_ {0.1};
514

515
  // By default, the light is at the camera unless otherwise specified.
516
  Position light_location_;
517
};
518

519
// Base class that implements ray tracing logic, not necessarily through
520
// defined regions of the geometry but also outside of it.
521
class Ray : public GeometryState {
522

523
public:
524
  Ray(Position r, Direction u) { init_from_r_u(r, u); }
3,200,960✔
525

526
  // Called at every surface intersection within the model
527
  virtual void on_intersection() = 0;
528

529
  /*
530
   * Traces the ray through the geometry, calling on_intersection
531
   * at every surface boundary.
532
   */
533
  void trace();
534

535
  // Stops the ray and exits tracing when called from on_intersection
536
  void stop() { stop_ = true; }
32,330✔
537

538
  // Sets the dist_ variable
539
  void compute_distance();
540

541
protected:
542
  // Records how far the ray has traveled
543
  double traversal_distance_ {0.0};
544

545
private:
546
  // Max intersections before we assume ray tracing is caught in an infinite
547
  // loop:
548
  static const int MAX_INTERSECTIONS = 1000000;
549

550
  bool hit_something_ {false};
551
  bool stop_ {false};
552

553
  unsigned event_counter_ {0};
554
};
555

556
class ProjectionRay : public Ray {
557
public:
558
  ProjectionRay(Position r, Direction u, const WireframeRayTracePlot& plot,
2,000,000✔
559
    vector<WireframeRayTracePlot::TrackSegment>& line_segments)
560
    : Ray(r, u), plot_(plot), line_segments_(line_segments)
2,000,000✔
561
  {}
2,000,000✔
562

563
  void on_intersection() override;
564

565
private:
566
  /* Store a reference to the plot object which is running this ray, in order
567
   * to access some of the plot settings which influence the behavior where
568
   * intersections are.
569
   */
570
  const WireframeRayTracePlot& plot_;
571

572
  /* The ray runs through the geometry, and records the lengths of ray segments
573
   * and cells they lie in along the way.
574
   */
575
  vector<WireframeRayTracePlot::TrackSegment>& line_segments_;
576
};
577

578
class PhongRay : public Ray {
579
public:
580
  PhongRay(Position r, Direction u, const SolidRayTracePlot& plot)
1,200,960✔
581
    : Ray(r, u), plot_(plot)
1,200,960✔
582
  {
583
    result_color_ = plot_.not_found_;
1,200,960✔
584
  }
1,200,960✔
585

586
  void on_intersection() override;
587

588
  const RGBColor& result_color() { return result_color_; }
1,200,960✔
589

590
private:
591
  const SolidRayTracePlot& plot_;
592

593
  /* After the ray is reflected, it is moving towards the
594
   * camera. It does that in order to see if the exposed surface
595
   * is shadowed by something else.
596
   */
597
  bool reflected_ {false};
598

599
  // Have to record the first hit ID, so that if the region
600
  // does get shadowed, we recall what its color should be
601
  // when tracing from the surface to the light.
602
  int orig_hit_id_ {-1};
603

604
  RGBColor result_color_;
605
};
606

607
//===============================================================================
608
// Non-member functions
609
//===============================================================================
610

611
/* Write a PPM image
612
 * filename - name of output file
613
 * data - image data to write
614
 */
615
void output_ppm(const std::string& filename, const ImageData& data);
616

617
#ifdef USE_LIBPNG
618
/* Write a PNG image
619
 * filename - name of output file
620
 * data - image data to write
621
 */
622
void output_png(const std::string& filename, const ImageData& data);
623
#endif
624

625
//! Initialize a voxel file
626
//! \param[in] id of an open hdf5 file
627
//! \param[in] dimensions of the voxel file (dx, dy, dz)
628
//! \param[out] dataspace pointer to voxel data
629
//! \param[out] dataset pointer to voxesl data
630
//! \param[out] pointer to memory space of voxel data
631
void voxel_init(hid_t file_id, const hsize_t* dims, hid_t* dspace, hid_t* dset,
632
  hid_t* memspace);
633

634
//! Write a section of the voxel data to hdf5
635
//! \param[in] voxel slice
636
//! \param[out] dataspace pointer to voxel data
637
//! \param[out] dataset pointer to voxesl data
638
//! \param[out] pointer to data to write
639
void voxel_write_slice(
640
  int x, hid_t dspace, hid_t dset, hid_t memspace, void* buf);
641

642
//! Close voxel file entities
643
//! \param[in] data space to close
644
//! \param[in] dataset to close
645
//! \param[in] memory space to close
646
void voxel_finalize(hid_t dspace, hid_t dset, hid_t memspace);
647

648
//===============================================================================
649
// External functions
650
//===============================================================================
651

652
//! Read plot specifications from a plots.xml file
653
void read_plots_xml();
654

655
//! Read plot specifications from an XML Node
656
//! \param[in] XML node containing plot info
657
void read_plots_xml(pugi::xml_node root);
658

659
//! Clear memory
660
void free_memory_plot();
661

662
//! Create a randomly generated RGB color
663
//! \return RGBColor with random value
664
RGBColor random_color();
665

666
} // namespace openmc
667
#endif // OPENMC_PLOT_H
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