2018-08-20 14:40:32 -05:00
|
|
|
#ifndef OPENMC_PLOT_H
|
|
|
|
|
#define OPENMC_PLOT_H
|
2018-04-24 22:42:04 -05:00
|
|
|
|
2023-12-28 14:37:21 -06:00
|
|
|
#include <cmath>
|
2018-10-07 19:55:45 -05:00
|
|
|
#include <sstream>
|
2018-10-30 19:41:30 -05:00
|
|
|
#include <unordered_map>
|
2018-04-24 22:42:04 -05:00
|
|
|
|
2019-02-20 15:45:30 -06:00
|
|
|
#include "pugixml.hpp"
|
2018-10-30 11:13:03 -05:00
|
|
|
#include "xtensor/xarray.hpp"
|
|
|
|
|
|
2018-10-09 09:35:55 -05:00
|
|
|
#include "hdf5.h"
|
2019-03-18 10:07:18 -05:00
|
|
|
#include "openmc/cell.h"
|
2018-10-09 09:35:55 -05:00
|
|
|
#include "openmc/constants.h"
|
2020-01-20 13:43:02 -06:00
|
|
|
#include "openmc/error.h"
|
2019-03-18 10:07:18 -05:00
|
|
|
#include "openmc/geometry.h"
|
2018-10-09 09:46:00 -05:00
|
|
|
#include "openmc/particle.h"
|
2018-10-10 17:16:55 -05:00
|
|
|
#include "openmc/position.h"
|
2019-11-22 18:23:16 +00:00
|
|
|
#include "openmc/random_lcg.h"
|
2018-10-09 09:46:00 -05:00
|
|
|
#include "openmc/xml_interface.h"
|
2018-10-09 09:35:55 -05:00
|
|
|
|
2018-04-24 22:42:04 -05:00
|
|
|
namespace openmc {
|
|
|
|
|
|
2018-10-26 14:40:11 -05:00
|
|
|
//===============================================================================
|
|
|
|
|
// Global variables
|
|
|
|
|
//===============================================================================
|
2018-10-09 19:56:32 -05:00
|
|
|
|
2021-12-13 16:05:41 -05:00
|
|
|
class PlottableInterface;
|
2019-03-05 19:24:38 -06:00
|
|
|
|
2018-11-08 15:14:01 -06:00
|
|
|
namespace model {
|
2018-10-09 19:56:32 -05:00
|
|
|
|
2018-11-08 15:14:01 -06:00
|
|
|
extern std::unordered_map<int, int> plot_map; //!< map of plot ids to index
|
2023-03-17 13:20:16 -04:00
|
|
|
extern vector<std::unique_ptr<PlottableInterface>>
|
2021-12-13 16:05:41 -05:00
|
|
|
plots; //!< Plot instance container
|
2019-11-22 22:56:16 +00:00
|
|
|
|
2021-10-05 12:49:30 -05:00
|
|
|
extern uint64_t plotter_seed; // Stream index used by the plotter
|
2018-11-08 15:14:01 -06:00
|
|
|
|
|
|
|
|
} // namespace model
|
2018-10-07 19:35:37 -05:00
|
|
|
|
2018-10-29 09:53:31 -05:00
|
|
|
//===============================================================================
|
|
|
|
|
// RGBColor holds color information for plotted objects
|
|
|
|
|
//===============================================================================
|
|
|
|
|
|
2018-10-31 15:26:32 -05:00
|
|
|
struct RGBColor {
|
|
|
|
|
// Constructors
|
|
|
|
|
RGBColor() : red(0), green(0), blue(0) {};
|
2018-11-02 22:33:09 -05:00
|
|
|
RGBColor(const int v[3]) : red(v[0]), green(v[1]), blue(v[2]) {};
|
2018-10-31 15:26:32 -05:00
|
|
|
RGBColor(int r, int g, int b) : red(r), green(g), blue(b) {};
|
2018-11-02 23:08:51 -05:00
|
|
|
|
2021-04-22 16:46:23 -04:00
|
|
|
RGBColor(const vector<int>& v)
|
|
|
|
|
{
|
2018-11-02 23:06:19 -05:00
|
|
|
if (v.size() != 3) {
|
|
|
|
|
throw std::out_of_range("Incorrect vector size for RGBColor.");
|
|
|
|
|
}
|
2018-10-31 15:26:32 -05:00
|
|
|
red = v[0];
|
|
|
|
|
green = v[1];
|
|
|
|
|
blue = v[2];
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-10 19:55:56 -05:00
|
|
|
bool operator==(const RGBColor& other)
|
|
|
|
|
{
|
|
|
|
|
return red == other.red && green == other.green && blue == other.blue;
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-31 15:26:32 -05:00
|
|
|
// Members
|
2018-10-31 17:55:18 -05:00
|
|
|
uint8_t red, green, blue;
|
2018-10-31 15:26:32 -05:00
|
|
|
};
|
2018-11-02 23:08:51 -05:00
|
|
|
|
2019-06-13 23:09:26 -05:00
|
|
|
// some default colors
|
|
|
|
|
const RGBColor WHITE {255, 255, 255};
|
|
|
|
|
const RGBColor RED {255, 0, 0};
|
2021-12-14 15:37:40 -05:00
|
|
|
const RGBColor BLACK {0, 0, 0};
|
2019-06-13 23:09:26 -05:00
|
|
|
|
2021-12-13 16:05:41 -05:00
|
|
|
/*
|
|
|
|
|
* PlottableInterface classes just have to have a unique ID in the plots.xml
|
|
|
|
|
* file, and guarantee being able to create output in some way.
|
|
|
|
|
*/
|
|
|
|
|
class PlottableInterface {
|
|
|
|
|
private:
|
|
|
|
|
void set_id(pugi::xml_node plot_node);
|
|
|
|
|
int id_; // unique plot ID
|
|
|
|
|
|
|
|
|
|
void set_bg_color(pugi::xml_node plot_node);
|
|
|
|
|
void set_universe(pugi::xml_node plot_node);
|
|
|
|
|
void set_default_colors(pugi::xml_node plot_node);
|
|
|
|
|
void set_user_colors(pugi::xml_node plot_node);
|
|
|
|
|
void set_overlap_color(pugi::xml_node plot_node);
|
|
|
|
|
void set_mask(pugi::xml_node plot_node);
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
// Plot output filename, derived classes have logic to set it
|
|
|
|
|
std::string path_plot_;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
enum class PlotColorBy { cells = 0, mats = 1 };
|
|
|
|
|
|
|
|
|
|
// Creates the output image named path_plot_
|
|
|
|
|
virtual void create_output() const = 0;
|
|
|
|
|
|
|
|
|
|
// Print useful info to the terminal
|
|
|
|
|
virtual void print_info() const = 0;
|
|
|
|
|
|
|
|
|
|
const std::string& path_plot() const { return path_plot_; }
|
2023-09-15 17:46:54 -04:00
|
|
|
int id() const { return id_; }
|
|
|
|
|
int level() const { return level_; }
|
2021-12-13 16:05:41 -05:00
|
|
|
|
|
|
|
|
// Public color-related data
|
|
|
|
|
PlottableInterface(pugi::xml_node plot_node);
|
2023-05-31 20:13:52 -05:00
|
|
|
virtual ~PlottableInterface() = default;
|
2021-12-13 16:05:41 -05:00
|
|
|
int level_; // Universe level to plot
|
|
|
|
|
bool color_overlaps_; // Show overlapping cells?
|
|
|
|
|
PlotColorBy color_by_; // Plot coloring (cell/material)
|
|
|
|
|
RGBColor not_found_ {WHITE}; // Plot background color
|
|
|
|
|
RGBColor overlap_color_ {RED}; // Plot overlap color
|
|
|
|
|
vector<RGBColor> colors_; // Plot colors
|
|
|
|
|
};
|
|
|
|
|
|
2018-10-30 11:13:03 -05:00
|
|
|
typedef xt::xtensor<RGBColor, 2> ImageData;
|
2019-03-12 17:37:27 -05:00
|
|
|
|
2019-03-18 09:48:21 -05:00
|
|
|
struct IdData {
|
2019-03-12 17:37:27 -05:00
|
|
|
// Constructor
|
2019-03-18 14:47:44 -05:00
|
|
|
IdData(size_t h_res, size_t v_res);
|
2019-03-12 17:37:27 -05:00
|
|
|
|
|
|
|
|
// Methods
|
2024-01-16 10:35:57 -06:00
|
|
|
void set_value(size_t y, size_t x, const GeometryState& p, int level);
|
2019-06-10 18:16:11 -05:00
|
|
|
void set_overlap(size_t y, size_t x);
|
2019-03-12 17:37:27 -05:00
|
|
|
|
|
|
|
|
// Members
|
2019-03-17 19:36:34 -05:00
|
|
|
xt::xtensor<int32_t, 3> data_; //!< 2D array of cell & material ids
|
2019-03-12 17:37:27 -05:00
|
|
|
};
|
|
|
|
|
|
2019-03-18 09:48:21 -05:00
|
|
|
struct PropertyData {
|
2019-03-12 17:37:27 -05:00
|
|
|
// Constructor
|
2019-03-18 14:47:44 -05:00
|
|
|
PropertyData(size_t h_res, size_t v_res);
|
2019-03-12 17:37:27 -05:00
|
|
|
|
|
|
|
|
// Methods
|
2024-01-16 10:35:57 -06:00
|
|
|
void set_value(size_t y, size_t x, const GeometryState& p, int level);
|
2019-06-10 18:16:11 -05:00
|
|
|
void set_overlap(size_t y, size_t x);
|
2019-03-12 17:37:27 -05:00
|
|
|
|
|
|
|
|
// Members
|
2019-03-17 19:36:34 -05:00
|
|
|
xt::xtensor<double, 3> data_; //!< 2D array of temperature & density data
|
2019-03-12 17:37:27 -05:00
|
|
|
};
|
2018-10-09 19:56:32 -05:00
|
|
|
|
2018-10-04 08:58:55 -05:00
|
|
|
//===============================================================================
|
2018-10-29 09:33:24 -05:00
|
|
|
// Plot class
|
2018-10-04 08:58:55 -05:00
|
|
|
//===============================================================================
|
2021-12-13 16:05:41 -05:00
|
|
|
|
2021-12-13 14:37:08 -05:00
|
|
|
class SlicePlotBase {
|
2019-03-18 14:16:56 -05:00
|
|
|
public:
|
2019-03-18 10:07:18 -05:00
|
|
|
template<class T>
|
|
|
|
|
T get_map() const;
|
2019-03-11 10:14:17 -05:00
|
|
|
|
2021-12-13 16:05:41 -05:00
|
|
|
enum class PlotBasis { xy = 1, xz = 2, yz = 3 };
|
|
|
|
|
|
2019-03-05 19:24:38 -06:00
|
|
|
// Members
|
2019-03-18 14:16:56 -05:00
|
|
|
public:
|
2023-05-31 20:13:52 -05:00
|
|
|
Position origin_; //!< Plot origin in geometry
|
|
|
|
|
Position width_; //!< Plot width in geometry
|
|
|
|
|
PlotBasis basis_; //!< Plot basis (XY/XZ/YZ)
|
|
|
|
|
array<size_t, 3> pixels_; //!< Plot size in pixels
|
2021-12-13 14:37:08 -05:00
|
|
|
bool slice_color_overlaps_; //!< Show overlapping cells?
|
|
|
|
|
int slice_level_ {-1}; //!< Plot universe level
|
|
|
|
|
private:
|
2019-02-26 11:10:19 -06:00
|
|
|
};
|
|
|
|
|
|
2019-03-18 10:07:18 -05:00
|
|
|
template<class T>
|
2021-12-13 14:37:08 -05:00
|
|
|
T SlicePlotBase::get_map() const
|
2019-03-18 10:07:18 -05:00
|
|
|
{
|
|
|
|
|
|
|
|
|
|
size_t width = pixels_[0];
|
|
|
|
|
size_t height = pixels_[1];
|
|
|
|
|
|
|
|
|
|
// get pixel size
|
|
|
|
|
double in_pixel = (width_[0]) / static_cast<double>(width);
|
|
|
|
|
double out_pixel = (width_[1]) / static_cast<double>(height);
|
|
|
|
|
|
|
|
|
|
// size data array
|
|
|
|
|
T data(width, height);
|
|
|
|
|
|
|
|
|
|
// setup basis indices and initial position centered on pixel
|
|
|
|
|
int in_i, out_i;
|
|
|
|
|
Position xyz = origin_;
|
|
|
|
|
switch (basis_) {
|
|
|
|
|
case PlotBasis::xy:
|
|
|
|
|
in_i = 0;
|
|
|
|
|
out_i = 1;
|
|
|
|
|
break;
|
|
|
|
|
case PlotBasis::xz:
|
|
|
|
|
in_i = 0;
|
|
|
|
|
out_i = 2;
|
|
|
|
|
break;
|
|
|
|
|
case PlotBasis::yz:
|
|
|
|
|
in_i = 1;
|
|
|
|
|
out_i = 2;
|
|
|
|
|
break;
|
2019-03-15 15:36:45 -05:00
|
|
|
default:
|
2020-01-20 13:43:02 -06:00
|
|
|
UNREACHABLE();
|
2019-03-18 10:07:18 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// set initial position
|
|
|
|
|
xyz[in_i] = origin_[in_i] - width_[0] / 2. + in_pixel / 2.;
|
|
|
|
|
xyz[out_i] = origin_[out_i] + width_[1] / 2. - out_pixel / 2.;
|
|
|
|
|
|
|
|
|
|
// arbitrary direction
|
2023-12-28 14:37:21 -06:00
|
|
|
Direction dir = {1. / std::sqrt(2.), 1. / std::sqrt(2.), 0.0};
|
2019-03-18 10:07:18 -05:00
|
|
|
|
|
|
|
|
#pragma omp parallel
|
|
|
|
|
{
|
2024-01-16 10:35:57 -06:00
|
|
|
GeometryState p;
|
2019-03-18 10:07:18 -05:00
|
|
|
p.r() = xyz;
|
|
|
|
|
p.u() = dir;
|
2021-04-14 17:13:59 -04:00
|
|
|
p.coord(0).universe = model::root_universe;
|
2021-12-13 14:37:08 -05:00
|
|
|
int level = slice_level_;
|
2019-03-18 10:07:18 -05:00
|
|
|
int j {};
|
|
|
|
|
|
|
|
|
|
#pragma omp for
|
|
|
|
|
for (int y = 0; y < height; y++) {
|
|
|
|
|
p.r()[out_i] = xyz[out_i] - out_pixel * y;
|
|
|
|
|
for (int x = 0; x < width; x++) {
|
|
|
|
|
p.r()[in_i] = xyz[in_i] + in_pixel * x;
|
2021-04-14 17:13:59 -04:00
|
|
|
p.n_coord() = 1;
|
2019-03-18 10:07:18 -05:00
|
|
|
// local variables
|
2021-03-08 11:54:16 -05:00
|
|
|
bool found_cell = exhaustive_find_cell(p);
|
2021-04-14 17:13:59 -04:00
|
|
|
j = p.n_coord() - 1;
|
2020-09-03 22:30:46 -05:00
|
|
|
if (level >= 0) {
|
|
|
|
|
j = level;
|
|
|
|
|
}
|
2019-03-18 10:07:18 -05:00
|
|
|
if (found_cell) {
|
|
|
|
|
data.set_value(y, x, p, j);
|
|
|
|
|
}
|
2021-12-13 14:37:08 -05:00
|
|
|
if (slice_color_overlaps_ && check_cell_overlap(p, false)) {
|
2019-06-10 18:16:11 -05:00
|
|
|
data.set_overlap(y, x);
|
|
|
|
|
}
|
2019-03-18 10:07:18 -05:00
|
|
|
} // inner for
|
|
|
|
|
} // outer for
|
|
|
|
|
} // omp parallel
|
|
|
|
|
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-13 14:37:08 -05:00
|
|
|
// Represents either a voxel or pixel plot
|
2021-12-13 16:05:41 -05:00
|
|
|
class Plot : public PlottableInterface, public SlicePlotBase {
|
2018-10-26 11:04:38 -05:00
|
|
|
|
|
|
|
|
public:
|
2021-12-13 16:05:41 -05:00
|
|
|
enum class PlotType { slice = 1, voxel = 2 };
|
|
|
|
|
|
|
|
|
|
Plot(pugi::xml_node plot, PlotType type);
|
2018-10-26 11:04:38 -05:00
|
|
|
|
2018-10-26 14:46:57 -05:00
|
|
|
private:
|
2018-10-29 10:35:22 -05:00
|
|
|
void set_output_path(pugi::xml_node plot_node);
|
|
|
|
|
void set_basis(pugi::xml_node plot_node);
|
|
|
|
|
void set_origin(pugi::xml_node plot_node);
|
|
|
|
|
void set_width(pugi::xml_node plot_node);
|
|
|
|
|
void set_meshlines(pugi::xml_node plot_node);
|
2018-10-13 20:09:53 -05:00
|
|
|
|
2018-10-26 14:46:57 -05:00
|
|
|
public:
|
2021-12-13 16:05:41 -05:00
|
|
|
// Add mesh lines to ImageData
|
|
|
|
|
void draw_mesh_lines(ImageData& data) const;
|
|
|
|
|
void create_image() const;
|
|
|
|
|
void create_voxel() const;
|
|
|
|
|
|
|
|
|
|
virtual void create_output() const;
|
|
|
|
|
virtual void print_info() const;
|
|
|
|
|
|
2019-02-26 15:46:24 -06:00
|
|
|
PlotType type_; //!< Plot type (Slice/Voxel)
|
|
|
|
|
int meshlines_width_; //!< Width of lines added to the plot
|
2019-06-13 23:09:26 -05:00
|
|
|
int index_meshlines_mesh_ {-1}; //!< Index of the mesh to draw on the plot
|
2019-02-26 15:46:24 -06:00
|
|
|
RGBColor meshlines_color_; //!< Color of meshlines on the plot
|
2018-10-26 14:40:11 -05:00
|
|
|
};
|
2018-10-09 22:24:59 -05:00
|
|
|
|
2021-12-13 16:05:41 -05:00
|
|
|
class ProjectionPlot : public PlottableInterface {
|
2021-12-14 15:37:40 -05:00
|
|
|
|
2021-12-13 16:05:41 -05:00
|
|
|
public:
|
|
|
|
|
ProjectionPlot(pugi::xml_node plot);
|
|
|
|
|
|
|
|
|
|
virtual void create_output() const;
|
|
|
|
|
virtual void print_info() const;
|
|
|
|
|
|
|
|
|
|
private:
|
2021-12-16 15:10:16 -05:00
|
|
|
void set_output_path(pugi::xml_node plot_node);
|
2021-12-14 15:37:40 -05:00
|
|
|
void set_look_at(pugi::xml_node node);
|
|
|
|
|
void set_camera_position(pugi::xml_node node);
|
|
|
|
|
void set_field_of_view(pugi::xml_node node);
|
|
|
|
|
void set_pixels(pugi::xml_node node);
|
|
|
|
|
void set_opacities(pugi::xml_node node);
|
2021-12-16 17:24:32 -05:00
|
|
|
void set_orthographic_width(pugi::xml_node node);
|
2021-12-17 17:11:49 -05:00
|
|
|
void set_wireframe_thickness(pugi::xml_node node);
|
2022-01-09 01:54:38 -05:00
|
|
|
void set_wireframe_ids(pugi::xml_node node);
|
|
|
|
|
void set_wireframe_color(pugi::xml_node node);
|
2021-12-13 16:05:41 -05:00
|
|
|
|
2023-03-17 13:20:16 -04:00
|
|
|
/* If starting the particle from outside the geometry, we have to
|
|
|
|
|
* find a distance to the boundary in a non-standard surface intersection
|
|
|
|
|
* check. It's an exhaustive search over surfaces in the top-level universe.
|
|
|
|
|
*/
|
2024-01-16 10:35:57 -06:00
|
|
|
static int advance_to_boundary_from_void(GeometryState& p);
|
2023-03-17 13:20:16 -04:00
|
|
|
|
|
|
|
|
/* Checks if a vector of two TrackSegments is equivalent. We define this
|
|
|
|
|
* to mean not having matching intersection lengths, but rather having
|
|
|
|
|
* a matching sequence of surface/cell/material intersections.
|
|
|
|
|
*/
|
2023-03-19 14:56:55 -04:00
|
|
|
struct TrackSegment;
|
2023-03-17 13:20:16 -04:00
|
|
|
bool trackstack_equivalent(const vector<TrackSegment>& track1,
|
|
|
|
|
const vector<TrackSegment>& track2) const;
|
|
|
|
|
|
2021-12-16 14:41:03 -05:00
|
|
|
/* Used for drawing wireframe and colors. We record the list of
|
|
|
|
|
* surface/cell/material intersections and the corresponding lengths as a ray
|
|
|
|
|
* traverses the geometry, then color by iterating in reverse.
|
|
|
|
|
*/
|
|
|
|
|
struct TrackSegment {
|
|
|
|
|
int id; // material or cell ID (which is being colored)
|
|
|
|
|
double length; // length of this track intersection
|
|
|
|
|
|
|
|
|
|
/* Recording this allows us to draw edges on the wireframe. For instance
|
|
|
|
|
* if two surfaces bound a single cell, it allows drawing that sharp edge
|
|
|
|
|
* where the surfaces intersect.
|
|
|
|
|
*/
|
|
|
|
|
int surface; // last surface ID intersected in this segment
|
|
|
|
|
TrackSegment(int id_a, double length_a, int surface_a)
|
|
|
|
|
: id(id_a), length(length_a), surface(surface_a)
|
|
|
|
|
{}
|
|
|
|
|
};
|
|
|
|
|
|
2023-03-17 13:20:16 -04:00
|
|
|
// Max intersections before we assume ray tracing is caught in an infinite
|
|
|
|
|
// loop:
|
|
|
|
|
static const int MAX_INTERSECTIONS = 1000000;
|
|
|
|
|
|
2023-05-31 20:13:52 -05:00
|
|
|
std::array<int, 2> pixels_; // pixel dimension of resulting image
|
2021-12-14 15:37:40 -05:00
|
|
|
double horizontal_field_of_view_ {70.0}; // horiz. f.o.v. in degrees
|
2023-05-31 20:13:52 -05:00
|
|
|
Position camera_position_; // where camera is
|
|
|
|
|
Position look_at_; // point camera is centered looking at
|
|
|
|
|
Direction up_ {0.0, 0.0, 1.0}; // which way is up
|
2023-03-17 13:20:16 -04:00
|
|
|
|
|
|
|
|
// which color IDs should be wireframed. If empty, all cells are wireframed.
|
|
|
|
|
vector<int> wireframe_ids_;
|
2021-12-16 17:24:32 -05:00
|
|
|
|
|
|
|
|
/* The horizontal thickness, if using an orthographic projection.
|
|
|
|
|
* If set to zero, we assume using a perspective projection.
|
|
|
|
|
*/
|
|
|
|
|
double orthographic_width_ {0.0};
|
|
|
|
|
|
2021-12-17 17:11:49 -05:00
|
|
|
// Thickness of the wireframe lines. Can set to zero for no wireframe.
|
|
|
|
|
int wireframe_thickness_ {1};
|
|
|
|
|
|
2021-12-14 15:37:40 -05:00
|
|
|
RGBColor wireframe_color_ {BLACK}; // wireframe color
|
2023-03-17 13:20:16 -04:00
|
|
|
vector<double> xs_; // macro cross section values for cell volume rendering
|
2021-12-13 16:05:41 -05:00
|
|
|
};
|
|
|
|
|
|
2018-10-26 14:40:11 -05:00
|
|
|
//===============================================================================
|
|
|
|
|
// Non-member functions
|
|
|
|
|
//===============================================================================
|
2018-10-09 22:24:59 -05:00
|
|
|
|
2021-12-13 16:05:41 -05:00
|
|
|
/* Write a PPM image
|
|
|
|
|
* filename - name of output file
|
|
|
|
|
* data - image data to write
|
|
|
|
|
*/
|
|
|
|
|
void output_ppm(const std::string& filename, const ImageData& data);
|
2018-10-09 19:56:32 -05:00
|
|
|
|
2021-09-30 16:28:05 -05:00
|
|
|
#ifdef USE_LIBPNG
|
2021-12-13 16:05:41 -05:00
|
|
|
/* Write a PNG image
|
|
|
|
|
* filename - name of output file
|
|
|
|
|
* data - image data to write
|
|
|
|
|
*/
|
|
|
|
|
void output_png(const std::string& filename, const ImageData& data);
|
2021-09-30 16:28:05 -05:00
|
|
|
#endif
|
|
|
|
|
|
2018-10-26 14:40:11 -05:00
|
|
|
//! Initialize a voxel file
|
|
|
|
|
//! \param[in] id of an open hdf5 file
|
|
|
|
|
//! \param[in] dimensions of the voxel file (dx, dy, dz)
|
|
|
|
|
//! \param[out] dataspace pointer to voxel data
|
|
|
|
|
//! \param[out] dataset pointer to voxesl data
|
|
|
|
|
//! \param[out] pointer to memory space of voxel data
|
2018-10-09 22:24:59 -05:00
|
|
|
void voxel_init(hid_t file_id, const hsize_t* dims, hid_t* dspace, hid_t* dset,
|
2018-11-08 15:14:01 -06:00
|
|
|
hid_t* memspace);
|
2018-10-26 14:46:57 -05:00
|
|
|
|
2018-10-26 14:40:11 -05:00
|
|
|
//! Write a section of the voxel data to hdf5
|
2018-10-26 14:46:57 -05:00
|
|
|
//! \param[in] voxel slice
|
2018-10-26 14:40:11 -05:00
|
|
|
//! \param[out] dataspace pointer to voxel data
|
|
|
|
|
//! \param[out] dataset pointer to voxesl data
|
|
|
|
|
//! \param[out] pointer to data to write
|
2018-10-09 22:24:59 -05:00
|
|
|
void voxel_write_slice(
|
|
|
|
|
int x, hid_t dspace, hid_t dset, hid_t memspace, void* buf);
|
2018-11-08 15:14:01 -06:00
|
|
|
|
2018-10-26 14:40:11 -05:00
|
|
|
//! Close voxel file entities
|
|
|
|
|
//! \param[in] data space to close
|
|
|
|
|
//! \param[in] dataset to close
|
|
|
|
|
//! \param[in] memory space to close
|
2018-10-09 22:24:59 -05:00
|
|
|
void voxel_finalize(hid_t dspace, hid_t dset, hid_t memspace);
|
2018-10-09 19:56:32 -05:00
|
|
|
|
2018-10-26 14:40:11 -05:00
|
|
|
//===============================================================================
|
|
|
|
|
// External functions
|
|
|
|
|
//===============================================================================
|
|
|
|
|
|
2019-02-20 15:45:30 -06:00
|
|
|
//! Read plot specifications from a plots.xml file
|
|
|
|
|
void read_plots_xml();
|
2018-10-26 14:40:11 -05:00
|
|
|
|
2022-11-03 20:10:22 -05:00
|
|
|
//! Read plot specifications from an XML Node
|
|
|
|
|
//! \param[in] XML node containing plot info
|
|
|
|
|
void read_plots_xml(pugi::xml_node root);
|
|
|
|
|
|
2021-09-30 15:15:58 -05:00
|
|
|
//! Clear memory
|
|
|
|
|
void free_memory_plot();
|
|
|
|
|
|
2018-10-31 15:42:08 -05:00
|
|
|
//! Create a randomly generated RGB color
|
|
|
|
|
//! \return RGBColor with random value
|
2019-11-22 22:56:16 +00:00
|
|
|
RGBColor random_color();
|
2018-10-26 14:46:57 -05:00
|
|
|
|
2018-04-24 22:42:04 -05:00
|
|
|
} // namespace openmc
|
2018-08-20 14:40:32 -05:00
|
|
|
#endif // OPENMC_PLOT_H
|