From a465dcdb1666bf15c0a6c9f859e06b800c0738cd Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 4 Jun 2019 14:15:12 -0500 Subject: [PATCH 1/3] Consistently use 'x' / 'y' for hex lattice orientation --- include/openmc/lattice.h | 16 ++--- openmc/lattice.py | 36 ++++++------ src/lattice.cpp | 58 +++++++++---------- .../lattice_hex_OX/inputs_true.dat | 2 +- tests/regression_tests/lattice_hex_OX/test.py | 6 +- 5 files changed, 60 insertions(+), 58 deletions(-) diff --git a/include/openmc/lattice.h b/include/openmc/lattice.h index c06920759e..8f2b6c4a1e 100644 --- a/include/openmc/lattice.h +++ b/include/openmc/lattice.h @@ -267,17 +267,19 @@ public: private: enum class Orientation { - oy, ox - }; - //! Fill universes_ vector for OY orientation - void fill_lattice_oy(const std::vector& univ_words); + y, //!< Flat side perpendicular to y-axis + x //!< Flat side perpendicular to x-axis + }; - //! Fill universes_ vector for OX orientation - void fill_lattice_ox(const std::vector& univ_words); + //! Fill universes_ vector for 'y' orientation + void fill_lattice_y(const std::vector& univ_words); + + //! Fill universes_ vector for 'x' orientation + void fill_lattice_x(const std::vector& univ_words); int n_rings_; //!< Number of radial tile positions int n_axial_; //!< Number of axial tile positions - Orientation orientation_; //!< Flat side up (oy) vs. sharp side up (ox) + Orientation orientation_; //!< Orientation of lattice Position center_; //!< Global center of lattice std::array pitch_; //!< Lattice tile width and height }; diff --git a/openmc/lattice.py b/openmc/lattice.py index 43d7eb5250..4f7caa20ad 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -141,7 +141,7 @@ class Lattice(IDManagerMixin, metaclass=ABCMeta): center = group['center'][()] pitch = group['pitch'][()] outer = group['outer'][()] - if ('orientation' in group): + if 'orientation' in group: orientation = group['orientation'][()].decode() else: orientation = "y" @@ -156,7 +156,7 @@ class Lattice(IDManagerMixin, metaclass=ABCMeta): # If the Universe specified outer the Lattice is not void if outer >= 0: lattice.outer = universes[outer] - if (orientation.lower() == "oy"): + if orientation == "y": # Build array of Universe pointers for the Lattice. Note that # we need to convert between the HDF5's square array of # (x, alpha, z) to the Python API's format of a ragged nested @@ -1207,8 +1207,8 @@ class HexLattice(Lattice): ---------- idx : Iterable of int Lattice element indices in the :math:`(x,\alpha,z)` coordinate - system in 'OY' orientation case, or indices in the - :math:`(\alpha,y,z)` coordinate system in 'OX' one + system in 'y' orientation case, or indices in the + :math:`(\alpha,y,z)` coordinate system in 'x' one Returns ------- @@ -1297,7 +1297,7 @@ class HexLattice(Lattice): lattice_subelement.set("n_rings", str(self._num_rings)) # If orientation is "OX" export it to XML if self._orientation == 'x': - lattice_subelement.set("orient", "OX") + lattice_subelement.set("orientation", "x") if self._num_axial is not None: lattice_subelement.set("n_axial", str(self._num_axial)) @@ -1429,13 +1429,13 @@ class HexLattice(Lattice): outer ring. """ if self._orientation == 'x': - return self._repr_axial_slice_ox(universes) + return self._repr_axial_slice_x(universes) else: - return self._repr_axial_slice_oy(universes) + return self._repr_axial_slice_y(universes) - def _repr_axial_slice_ox(self, universes): + def _repr_axial_slice_x(self, universes): """Return string representation for the given 2D group of universes - in 'OX' orientation case. + in 'x' orientation case. The 'universes' argument should be a list of lists of universes where each sub-list represents a single ring. The first list should be the @@ -1535,9 +1535,9 @@ class HexLattice(Lattice): universe_ids = '\n'.join(rows) return universe_ids - def _repr_axial_slice_oy(self, universes): + def _repr_axial_slice_y(self, universes): """Return string representation for the given 2D group of universes in - 'OY' orientation case.. + 'y' orientation case.. The 'universes' argument should be a list of lists of universes where each sub-list represents a single ring. The first list should be the @@ -1750,22 +1750,22 @@ class HexLattice(Lattice): @staticmethod def _show_indices_x(num_rings): - """Return a diagram of the hexagonal lattice with OX orientation + """Return a diagram of the hexagonal lattice with x orientation layout with indices. This method can be used to show the proper indices to be used when setting the :attr:`HexLattice.universes` property. For example,running this method with num_rings=3 will return the similar diagram:: - (0, 4) (0, 3) (0, 2) + (0, 4) (0, 3) (0, 2) - (0, 5) (1, 2) (1, 1) (0, 1) + (0, 5) (1, 2) (1, 1) (0, 1) - (0, 6) (1, 3) (2, 0) (1, 0) (0, 0) + (0, 6) (1, 3) (2, 0) (1, 0) (0, 0) - (0, 7) (1, 4) (1, 5) (0,11) + (0, 7) (1, 4) (1, 5) (0,11) - (0, 8) (0, 9) (0,10) + (0, 8) (0, 9) (0,10) Parameters ---------- @@ -1855,7 +1855,7 @@ class HexLattice(Lattice): num_rings : int Number of rings in the hexagonal lattice orientation : {"x", "y"} - str type of hex lattice orientation + Orientation of the hexagonal lattice Returns ------- diff --git a/src/lattice.cpp b/src/lattice.cpp index d2e29e1067..1838df133c 100644 --- a/src/lattice.cpp +++ b/src/lattice.cpp @@ -440,19 +440,19 @@ HexLattice::HexLattice(pugi::xml_node lat_node) is_3d_ = false; } - // Read the lattice orientation. Default to OY. - if (check_for_node(lat_node, "orient")) { - std::string orientation = get_node_value(lat_node, "orient"); - if (orientation == "OY") { - orientation_ = Orientation::oy; - } else if (orientation == "OX") { - orientation_ = Orientation::ox; + // Read the lattice orientation. Default to 'y'. + if (check_for_node(lat_node, "orientation")) { + std::string orientation = get_node_value(lat_node, "orientation"); + if (orientation == "y") { + orientation_ = Orientation::y; + } else if (orientation == "x") { + orientation_ = Orientation::x; } else { fatal_error("Unrecognized orientation '" + orientation + "' for lattice " + std::to_string(id_)); } } else { - orientation_ = Orientation::oy; + orientation_ = Orientation::y; } // Read the lattice center. @@ -497,25 +497,25 @@ HexLattice::HexLattice(pugi::xml_node lat_node) // Parse the universes. // Universes in hexagonal lattices are stored in a manner that represents - // a skewed coordinate system: (x, alpha) in case of OY orientation - // and (alpha,y) in OX one rather than (x, y). There is + // a skewed coordinate system: (x, alpha) in case of 'y' orientation + // and (alpha,y) in 'x' one rather than (x, y). There is // no obvious, direct relationship between the order of universes in the // input and the order that they will be stored in the skewed array so // the following code walks a set of index values across the skewed array // in a manner that matches the input order. Note that i_x = 0, i_a = 0 // or i_a = 0, i_y = 0 corresponds to the center of the hexagonal lattice. universes_.resize((2*n_rings_-1) * (2*n_rings_-1) * n_axial_, C_NONE); - if (orientation_ == Orientation::oy) { - fill_lattice_oy(univ_words); + if (orientation_ == Orientation::y) { + fill_lattice_y(univ_words); } else { - fill_lattice_ox(univ_words); + fill_lattice_x(univ_words); } } - + //============================================================================== - + void -HexLattice::fill_lattice_ox(const std::vector& univ_words) +HexLattice::fill_lattice_x(const std::vector& univ_words) { int input_index = 0; for (int m = 0; m < n_axial_; m++) { @@ -568,7 +568,7 @@ HexLattice::fill_lattice_ox(const std::vector& univ_words) //============================================================================== void -HexLattice::fill_lattice_oy(const std::vector& univ_words) +HexLattice::fill_lattice_y(const std::vector& univ_words) { int input_index = 0; for (int m = 0; m < n_axial_; m++) { @@ -692,13 +692,13 @@ const { // Short description of the direction vectors used here. The beta, gamma, and // delta vectors point towards the flat sides of each hexagonal tile. - // OY - orientation: + // Y - orientation: // basis0 = (1, 0) // basis1 = (-1/sqrt(3), 1) = +120 degrees from basis0 // beta = (sqrt(3)/2, 1/2) = +30 degrees from basis0 // gamma = (sqrt(3)/2, -1/2) = -60 degrees from beta // delta = (0, 1) = +60 degrees from beta - // OX - orientation: + // X - orientation: // basis0 = (1/sqrt(3), -1) // basis1 = (0, 1) = +120 degrees from basis0 // beta = (1, 0) = +30 degrees from basis0 @@ -708,7 +708,7 @@ const double beta_dir; double gamma_dir; double delta_dir; - if (orientation_ == Orientation::oy) { + if (orientation_ == Orientation::y) { beta_dir = u.x * std::sqrt(3.0) / 2.0 + u.y / 2.0; gamma_dir = u.x * std::sqrt(3.0) / 2.0 - u.y / 2.0; delta_dir = u.y; @@ -737,7 +737,7 @@ const r_t = get_local_position(r, i_xyz_t); } double beta; - if (orientation_ == Orientation::oy) { + if (orientation_ == Orientation::y) { beta = r_t.x * std::sqrt(3.0) / 2.0 + r_t.y / 2.0; } else { beta = r_t.x; @@ -761,7 +761,7 @@ const r_t = get_local_position(r, i_xyz_t); } double gamma; - if (orientation_ == Orientation::oy) { + if (orientation_ == Orientation::y) { gamma = r_t.x * std::sqrt(3.0) / 2.0 - r_t.y / 2.0; } else { gamma = r_t.x / 2.0 - r_t.y * std::sqrt(3.0) / 2.0; @@ -788,7 +788,7 @@ const r_t = get_local_position(r, i_xyz_t); } double delta; - if (orientation_ == Orientation::oy) { + if (orientation_ == Orientation::y) { delta = r_t.y; } else { delta = r_t.x / 2.0 + r_t.y * std::sqrt(3.0) / 2.0; @@ -848,7 +848,7 @@ HexLattice::get_indices(Position r, Direction u) const } int i1, i2; - if (orientation_ == Orientation::oy) { + if (orientation_ == Orientation::y) { // Convert coordinates into skewed bases. The (x, alpha) basis is used to // find the index of the global coordinates to within 4 cells. double alpha = r_o.y - r_o.x / std::sqrt(3.0); @@ -926,7 +926,7 @@ Position HexLattice::get_local_position(Position r, const std::array i_xyz) const { - if (orientation_ == Orientation::oy) { + if (orientation_ == Orientation::y) { // x_l = x_g - (center + pitch_x*cos(30)*index_x) r.x -= center_.x + std::sqrt(3.0)/2.0 * (i_xyz[0] - n_rings_ + 1) * pitch_[0]; @@ -941,7 +941,7 @@ const r.y -= center_.y + std::sqrt(3.0)/2.0 * (i_xyz[1] - n_rings_ + 1) * pitch_[0]; } - + if (is_3d_) { r.z -= center_.z - (0.5 * n_axial_ - i_xyz[2] - 0.5) * pitch_[1]; } @@ -1003,10 +1003,10 @@ HexLattice::to_hdf5_inner(hid_t lat_group) const write_string(lat_group, "type", "hexagonal", false); write_dataset(lat_group, "n_rings", n_rings_); write_dataset(lat_group, "n_axial", n_axial_); - if (orientation_ == Orientation::oy) { - write_string(lat_group, "orientation", "oy", false); + if (orientation_ == Orientation::y) { + write_string(lat_group, "orientation", "y", false); } else { - write_string(lat_group, "orientation", "ox", false); + write_string(lat_group, "orientation", "x", false); } if (is_3d_) { write_dataset(lat_group, "pitch", pitch_); diff --git a/tests/regression_tests/lattice_hex_OX/inputs_true.dat b/tests/regression_tests/lattice_hex_OX/inputs_true.dat index 9130cf284d..9c0b102a93 100644 --- a/tests/regression_tests/lattice_hex_OX/inputs_true.dat +++ b/tests/regression_tests/lattice_hex_OX/inputs_true.dat @@ -13,7 +13,7 @@ - + 1.235 5.0 4
0.0 0.0 5.0
diff --git a/tests/regression_tests/lattice_hex_OX/test.py b/tests/regression_tests/lattice_hex_OX/test.py index bcef2357db..c958387ddf 100644 --- a/tests/regression_tests/lattice_hex_OX/test.py +++ b/tests/regression_tests/lattice_hex_OX/test.py @@ -148,7 +148,7 @@ class HexLatticeOXTestHarness(PyAPITestHarness): inf_mat = openmc.Cell(cell_id=12) inf_mat.fill = coolant - inf_mat_univ = openmc.Universe(universe_id=4, cells=[inf_mat, ]) + inf_mat_univ = openmc.Universe(universe_id=4, cells=[inf_mat]) # Fill lattice by channels @@ -167,7 +167,7 @@ class HexLatticeOXTestHarness(PyAPITestHarness): for i, j in channels: universes[i][j] = abs_ch_univ lattice = openmc.HexLattice(name="regular fuel assembly") - lattice.orientation = "ox" + lattice.orientation = "x" lattice.center = (0., 0., length/2.0) lattice.pitch = (assembly_pitch, length/2.0) lattice.universes = 2*[universes] @@ -179,7 +179,7 @@ class HexLatticeOXTestHarness(PyAPITestHarness): assembly_cell.fill = lattice root_univ = openmc.Universe(universe_id=5, name="root universe", - cells=[assembly_cell, ]) + cells=[assembly_cell]) geom = openmc.Geometry(root_univ) geom.export_to_xml() From 3794c3eec44ba69a67b0028cb76954aa3f7c20a6 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 4 Jun 2019 14:42:57 -0500 Subject: [PATCH 2/3] Update documentation for hex lattice --- docs/source/io_formats/geometry.rst | 7 +++++++ openmc/lattice.py | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/source/io_formats/geometry.rst b/docs/source/io_formats/geometry.rst index 94511842dc..a89bfb1e34 100644 --- a/docs/source/io_formats/geometry.rst +++ b/docs/source/io_formats/geometry.rst @@ -318,6 +318,13 @@ the following attributes or sub-elements: *Default*: None + :orientation: + The orientation of the hexagonal lattice. The string "x" indicates that two + sides of the lattice are perpendicular to the x-axis, whereas the string "y" + indicates that two sides are perpendicular to the y-axis. + + *Default*: "y" + :center: The coordinates of the center of the lattice. If the lattice does not have axial sections then only the x- and y-coordinates are specified. diff --git a/openmc/lattice.py b/openmc/lattice.py index 4f7caa20ad..b2bdc8a564 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -884,6 +884,10 @@ class HexLattice(Lattice): :attr:`HexLattice.universes` property, the array indices do not correspond to natural indices. + .. versionchanged:: 0.11 + The orientation of the lattice can now be changed with the + :attr:`orientation` attribute. + Parameters ---------- lattice_id : int, optional @@ -1295,7 +1299,7 @@ class HexLattice(Lattice): self._outer.create_xml_subelement(xml_element) lattice_subelement.set("n_rings", str(self._num_rings)) - # If orientation is "OX" export it to XML + # If orientation is "x" export it to XML if self._orientation == 'x': lattice_subelement.set("orientation", "x") From d1a2640ac350cc4acde81193c6ef9362e9237a92 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 4 Jun 2019 16:00:50 -0500 Subject: [PATCH 3/3] Rename lattice_hex_OX -> lattice_hex_x --- .../{lattice_hex_OX => lattice_hex_x}/__init__.py | 0 .../{lattice_hex_OX => lattice_hex_x}/inputs_true.dat | 0 .../{lattice_hex_OX => lattice_hex_x}/results_true.dat | 0 tests/regression_tests/{lattice_hex_OX => lattice_hex_x}/test.py | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename tests/regression_tests/{lattice_hex_OX => lattice_hex_x}/__init__.py (100%) rename tests/regression_tests/{lattice_hex_OX => lattice_hex_x}/inputs_true.dat (100%) rename tests/regression_tests/{lattice_hex_OX => lattice_hex_x}/results_true.dat (100%) rename tests/regression_tests/{lattice_hex_OX => lattice_hex_x}/test.py (100%) diff --git a/tests/regression_tests/lattice_hex_OX/__init__.py b/tests/regression_tests/lattice_hex_x/__init__.py similarity index 100% rename from tests/regression_tests/lattice_hex_OX/__init__.py rename to tests/regression_tests/lattice_hex_x/__init__.py diff --git a/tests/regression_tests/lattice_hex_OX/inputs_true.dat b/tests/regression_tests/lattice_hex_x/inputs_true.dat similarity index 100% rename from tests/regression_tests/lattice_hex_OX/inputs_true.dat rename to tests/regression_tests/lattice_hex_x/inputs_true.dat diff --git a/tests/regression_tests/lattice_hex_OX/results_true.dat b/tests/regression_tests/lattice_hex_x/results_true.dat similarity index 100% rename from tests/regression_tests/lattice_hex_OX/results_true.dat rename to tests/regression_tests/lattice_hex_x/results_true.dat diff --git a/tests/regression_tests/lattice_hex_OX/test.py b/tests/regression_tests/lattice_hex_x/test.py similarity index 100% rename from tests/regression_tests/lattice_hex_OX/test.py rename to tests/regression_tests/lattice_hex_x/test.py