diff --git a/include/openmc/capi.h b/include/openmc/capi.h index 07c6bc80e..ed58eaded 100644 --- a/include/openmc/capi.h +++ b/include/openmc/capi.h @@ -70,7 +70,7 @@ extern "C" { int openmc_next_batch(int* status); int openmc_nuclide_name(int index, const char** name); int openmc_plot_geometry(); - int openmc_id_map(void* slice, int32_t *data_out); + int openmc_id_map(const void* slice, int32_t *data_out); int openmc_reset(); int openmc_run(); void openmc_set_seed(int64_t new_seed); diff --git a/openmc/capi/plot.py b/openmc/capi/plot.py index d66c62746..4ed78e393 100644 --- a/openmc/capi/plot.py +++ b/openmc/capi/plot.py @@ -23,46 +23,11 @@ class _Position(Structure): ('y', c_double), ('z', c_double)] - def __init__(self, vals=None): - if vals: - x = vals[0] - y = vals[1] - z = vals[2] - else: - x = 0.0 - y = 0.0 - z = 0.0 - - @property - def x(self): - return self.x - - @property - def y(self): - return self.y - - @property - def z(self): - return self.z - - @x.setter - def x(self, x_val): - assert(isinstance(x_val, float)) - self.x = x_val - - @y.setter - def y(self, y_val): - assert(isinstance(y_val, float)) - self.y = y_val - - @z.setter - def z(self, z_val): - assert(isinstance(z_val, float)) - self.z = z_val + def __repr__(self): + return "({}, {}, {})".format(self.x, self.y, self.z) def __str__(self): - return "Position: ({}, {}, {})".format(self.x, self.y, self.z) - + return self.__repr__() class _PlotBase(Structure): """A structure defining a 2-D geometry slice with underlying c-types @@ -91,9 +56,9 @@ class _PlotBase(Structure): basis : string One of {'xy', 'xz', 'yz'} indicating the horizontal and vertical axes of the plot. - hRes : float + h_res : float The horizontal resolution of the plot in pixels - vRes : float + v_res : float The vertical resolution of the plot in pixels level : int The universe level for the plot (default: -1 -> all universes shown) @@ -132,11 +97,11 @@ class _PlotBase(Structure): raise ValueError("Plot basis {} is invalid".format(basis_)) @property - def hRes(self): + def h_res(self): return self.pixels_[0] @property - def vRes(self): + def v_res(self): return self.pixels_[1] @property @@ -183,30 +148,30 @@ class _PlotBase(Structure): raise ValueError("{} of type {} is an" " invalid plot basis".format(basis, type(basis))) - @hRes.setter - def hRes(self, hRes): - self.pixels_[0] = hRes + @h_res.setter + def h_res(self, h_res): + self.pixels_[0] = h_res - @vRes.setter - def vRes(self, vRes): - self.pixels_[1] = vRes + @v_res.setter + def v_res(self, v_res): + self.pixels_[1] = v_res @level.setter def level(self, level): self.level_ = level def __repr__(self): - out_str = "-----\n" - out_str += "Plot:\n" - out_str += "-----\n" - out_str += "Origin: {}\n".format(self.origin) - out_str += "Width: {}\n".format(self.width) - out_str += "Height: {}\n".format(self.height) - out_str += "Basis: {}\n".format(self.basis) - out_str += "HRes: {}\n".format(self.hRes) - out_str += "VRes: {}\n".format(self.vRes) - out_str += "Level: {}\n".format(self.level) - return out_str + out_str = ["-----", + "Plot:", + "-----", + "Origin: {}".format(self.origin), + "Width: {}".format(self.width), + "Height: {}".format(self.height), + "Basis: {}".format(self.basis), + "HRes: {}".format(self.h_res), + "VRes: {}".format(self.v_res), + "Level: {}".format(self.level)] + return '\n'.join(output) def __str__(self): return self.__repr__() @@ -220,20 +185,21 @@ _dll.openmc_id_map.errcheck = _error_handler def id_map(plot): """ Generate a 2-D map of (cell_id, material_id). Used for in-memory image - generation. + generation. Parameters ---------- - plot : An openmc.capi.plot._PlotBase object describing the slice of the - model to be generated + plot : An openmc.capi.plot._PlotBase + Object describing the slice of the model to be generated Returns ------- - id_map : a NumPy array with shape (vertical pixels, horizontal pixels, 2) - of OpenMC property ids with dtype int32 + id_map : numpy.ndarray + A NumPy array with shape (vertical pixels, horizontal pixels, 2) of + OpenMC property ids with dtype int32 """ - img_data = np.zeros((plot.vRes, plot.hRes, 2), + img_data = np.zeros((plot.v_res, plot.h_res, 2), dtype=np.dtype('int32')) _dll.openmc_id_map(POINTER(_PlotBase)(plot), img_data.ctypes.data_as(POINTER(c_int32))) diff --git a/src/plot.cpp b/src/plot.cpp index f4e1389e2..281d878a7 100644 --- a/src/plot.cpp +++ b/src/plot.cpp @@ -619,8 +619,8 @@ Plot::set_mask(pugi::xml_node plot_node) } Plot::Plot(pugi::xml_node plot_node) + : index_meshlines_mesh_{-1} { - index_meshlines_mesh_ = -1; set_id(plot_node); set_type(plot_node); set_output_path(plot_node); @@ -952,9 +952,9 @@ RGBColor random_color() { return {int(prn()*255), int(prn()*255), int(prn()*255)}; } -extern "C" int openmc_id_map(void* plot, int32_t* data_out) { +extern "C" int openmc_id_map(const void* plot, int32_t* data_out) { - auto plt = reinterpret_cast(plot); + auto plt = reinterpret_cast(plot); if (!plt) { set_errmsg("Invalid slice pointer passed to openmc_id_map"); return OPENMC_E_INVALID_ARGUMENT; @@ -968,38 +968,32 @@ extern "C" int openmc_id_map(void* plot, int32_t* data_out) { double out_pixel = (plt->width_[1])/static_cast(height); // size data array - IdData data; - data.resize({height, width, 2}); + IdData data({height, width, 2}, NOT_FOUND); // setup basis indices and initial position centered on pixel int in_i, out_i; - double xyz[3]; + Position xyz = plt->origin_; switch(plt->basis_) { case PlotBasis::xy : in_i = 0; out_i = 1; - xyz[0] = plt->origin_[0] - plt->width_[0] / 2. + in_pixel / 2.; - xyz[1] = plt->origin_[1] + plt->width_[1] / 2. - out_pixel / 2.; - xyz[2] = plt->origin_[2]; break; case PlotBasis::xz : in_i = 0; out_i = 2; - xyz[0] = plt->origin_[0] - plt->width_[0] / 2. + in_pixel / 2.; - xyz[1] = plt->origin_[1]; - xyz[2] = plt->origin_[2] + plt->width_[1] / 2. - out_pixel / 2.; break; case PlotBasis::yz : in_i = 1; out_i = 2; - xyz[0] = plt->origin_[0]; - xyz[1] = plt->origin_[1] - plt->width_[0] / 2. + in_pixel / 2.; - xyz[2] = plt->origin_[2] + plt->width_[1] / 2. - out_pixel / 2.; break; } + // set initial position + xyz[in_i] = plt->origin_[in_i] - plt->width_[0] / 2. + in_pixel / 2.; + xyz[out_i] = plt->origin_[out_i] + plt->width_[1] / 2. - out_pixel / 2.; + // arbitrary direction - double dir[3] = {0.5, 0.5, 0.5}; + Direction dir = {0.5, 0.5, 0.5}; #pragma omp parallel { @@ -1010,7 +1004,7 @@ extern "C" int openmc_id_map(void* plot, int32_t* data_out) { int level = plt->level_; int j{}; -#pragma omp for + #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++) { @@ -1020,15 +1014,10 @@ extern "C" int openmc_id_map(void* plot, int32_t* data_out) { bool found_cell = find_cell(&p, 0); j = p.n_coord_ - 1; if (level >=0) {j = level + 1;} - if (!found_cell) { - data(y,x,0) = NOT_FOUND; - data(y,x,1) = NOT_FOUND; - } else { - Cell *c = model::cells[p.coord_[j].cell].get(); + if (found_cell) { + Cell* c = model::cells[p.coord_[j].cell].get(); data(y,x,0) = c->id_; - if (c->type_ == FILL_UNIVERSE || p.material_ == MATERIAL_VOID) { - data(y,x,1) = NOT_FOUND; - } else { + if (c->type_ != FILL_UNIVERSE && p.material_ != MATERIAL_VOID) { data(y,x,1) = model::materials[p.material_]->id_; } } @@ -1037,8 +1026,7 @@ extern "C" int openmc_id_map(void* plot, int32_t* data_out) { } // omp parallel // write id data to array - size_t i = 0; - for (auto v : data) { data_out[i++] = v; } + std::copy(data.begin(), data.end(), data_out); return 0; } diff --git a/tests/unit_tests/test_capi.py b/tests/unit_tests/test_capi.py index bc529f02f..97d18531b 100644 --- a/tests/unit_tests/test_capi.py +++ b/tests/unit_tests/test_capi.py @@ -411,8 +411,8 @@ def test_id_map(capi_init): s = openmc.capi.plot._PlotBase() s.width = 1.26 s.height = 1.26 - s.vRes = 3 - s.hRes = 3 + s.v_res = 3 + s.h_res = 3 s.origin = (0.0, 0.0, 0.0) s.basis = 'xy' s.level = -1