diff --git a/include/openmc/geometry.h b/include/openmc/geometry.h index 8e6e8a82e..0ceaab104 100644 --- a/include/openmc/geometry.h +++ b/include/openmc/geometry.h @@ -47,7 +47,7 @@ inline bool coincident(double d1, double d2) { //! Check for overlapping cells at a particle's position. //============================================================================== -bool check_cell_overlap(Particle* p); + bool check_cell_overlap(Particle* p, bool error=true); //============================================================================== //! Locate a particle in the geometry tree and set its geometry data fields. diff --git a/include/openmc/plot.h b/include/openmc/plot.h index 8e5aa02a6..1d8ac0ea1 100644 --- a/include/openmc/plot.h +++ b/include/openmc/plot.h @@ -61,6 +61,7 @@ struct IdData { // Methods void set_value(size_t y, size_t x, const Particle& p, int level); + void set_overlap(size_t y, size_t x); // Members xt::xtensor data_; //!< 2D array of cell & material ids @@ -72,6 +73,7 @@ struct PropertyData { // Methods void set_value(size_t y, size_t x, const Particle& p, int level); + void set_overlap(size_t y, size_t x); // Members xt::xtensor data_; //!< 2D array of temperature & density data @@ -106,6 +108,7 @@ public: Position width_; //!< Plot width in geometry PlotBasis basis_; //!< Plot basis (XY/XZ/YZ) std::array pixels_; //!< Plot size in pixels + bool check_overlaps_ = false; int level_; //!< Plot universe level }; @@ -173,6 +176,9 @@ T PlotBase::get_map() const { if (found_cell) { data.set_value(y, x, p, j); } + if (check_overlaps_ && check_cell_overlap(&p, false)) { + data.set_overlap(y, x); + } } // inner for } // outer for } // omp parallel @@ -210,6 +216,7 @@ public: int index_meshlines_mesh_; //!< Index of the mesh to draw on the plot RGBColor meshlines_color_; //!< Color of meshlines on the plot RGBColor not_found_; //!< Plot background color + RGBColor overlap_color_; //!< Plot overlap color std::vector colors_; //!< Plot colors std::string path_plot_; //!< Plot output filename }; diff --git a/openmc/capi/plot.py b/openmc/capi/plot.py index 9ff398f5c..375660b38 100644 --- a/openmc/capi/plot.py +++ b/openmc/capi/plot.py @@ -1,4 +1,5 @@ -from ctypes import c_int, c_size_t, c_int32, c_double, Structure, POINTER +from ctypes import (c_bool, c_int, c_size_t, c_int32, + c_double, Structure, POINTER) from . import _dll from .error import _error_handler @@ -84,6 +85,7 @@ class _PlotBase(Structure): ('width_', _Position), ('basis_', c_int), ('pixels_', 3*c_size_t), + ('color_overlaps_', c_bool), ('level_', c_int)] def __init__(self): @@ -112,32 +114,6 @@ class _PlotBase(Structure): raise ValueError("Plot basis {} is invalid".format(self.basis_)) - @property - def h_res(self): - return self.pixels_[0] - - @property - def v_res(self): - return self.pixels_[1] - - @property - def level(self): - return int(self.level_) - - @origin.setter - def origin(self, origin): - self.origin_.x = origin[0] - self.origin_.y = origin[1] - self.origin_.z = origin[2] - - @width.setter - def width(self, width): - self.width_.x = width - - @height.setter - def height(self, height): - self.width_.y = height - @basis.setter def basis(self, basis): if isinstance(basis, str): @@ -164,6 +140,32 @@ class _PlotBase(Structure): raise ValueError("{} of type {} is an" " invalid plot basis".format(basis, type(basis))) + @property + def h_res(self): + return self.pixels_[0] + + @property + def v_res(self): + return self.pixels_[1] + + @property + def level(self): + return int(self.level_) + + @origin.setter + def origin(self, origin): + self.origin_.x = origin[0] + self.origin_.y = origin[1] + self.origin_.z = origin[2] + + @width.setter + def width(self, width): + self.width_.x = width + + @height.setter + def height(self, height): + self.width_.y = height + @h_res.setter def h_res(self, h_res): self.pixels_[0] = h_res @@ -176,6 +178,14 @@ class _PlotBase(Structure): def level(self, level): self.level_ = level + @property + def color_overlaps(self): + return self.color_overlaps_ + + @color_overlaps.setter + def color_overlaps(self, val): + self.color_overlaps_ = val + def __repr__(self): out_str = ["-----", "Plot:", @@ -186,6 +196,7 @@ class _PlotBase(Structure): "Basis: {}".format(self.basis), "HRes: {}".format(self.h_res), "VRes: {}".format(self.v_res), + "Color Ovrelaps: {}".format(self.color_overlaps), "Level: {}".format(self.level)] return '\n'.join(out_str) diff --git a/src/geometry.cpp b/src/geometry.cpp index aec272ae1..4169a5420 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -32,7 +32,7 @@ std::vector overlap_check_count; // Non-member functions //============================================================================== -bool check_cell_overlap(Particle* p) +bool check_cell_overlap(Particle* p, bool error) { int n_coord = p->n_coord_; @@ -44,7 +44,7 @@ bool check_cell_overlap(Particle* p) for (auto index_cell : univ.cells_) { Cell& c = *model::cells[index_cell]; if (c.contains(p->coord_[j].r, p->coord_[j].u, p->surface_)) { - if (index_cell != p->coord_[j].cell) { + if (error && index_cell != p->coord_[j].cell) { std::stringstream err_msg; err_msg << "Overlapping cells detected: " << c.id_ << ", " << model::cells[p->coord_[j].cell]->id_ << " on universe " diff --git a/src/plot.cpp b/src/plot.cpp index 6bc82e164..0ec26473e 100644 --- a/src/plot.cpp +++ b/src/plot.cpp @@ -29,8 +29,11 @@ namespace openmc { //============================================================================== const RGBColor WHITE {255, 255, 255}; +const RGBColor RED {255, 0, 0}; + constexpr int PLOT_LEVEL_LOWEST {-1}; //!< lower bound on plot universe level constexpr int32_t NOT_FOUND {-2}; +constexpr int32_t OVERLAP{-3}; IdData::IdData(size_t h_res, size_t v_res) : data_({v_res, h_res, 2}, NOT_FOUND) @@ -49,6 +52,10 @@ IdData::set_value(size_t y, size_t x, const Particle& p, int level) { } } +void IdData::set_overlap(size_t y, size_t x) { + data_(y, x) = OVERLAP; +} + PropertyData::PropertyData(size_t h_res, size_t v_res) : data_({v_res, h_res, 2}, NOT_FOUND) { } @@ -63,6 +70,10 @@ PropertyData::set_value(size_t y, size_t x, const Particle& p, int level) { } } +void PropertyData::set_overlap(size_t y, size_t x) { + data_(y, x) = OVERLAP; +} + //============================================================================== // Global variables //============================================================================== @@ -143,6 +154,7 @@ void create_ppm(Plot pl) auto id = ids.data_(y, x, pl.color_by_); // no setting needed if not found if (id == NOT_FOUND) { continue; } + if (id == OVERLAP) data(x,y) = RED; if (PlotColorBy::cells == pl.color_by_) { data(x,y) = pl.colors_[model::cell_map[id]]; } else if (PlotColorBy::mats == pl.color_by_) {