Skip to content

Commit a83e501

Browse files
committed
bugfix
1 parent 42dd2e1 commit a83e501

4 files changed

Lines changed: 133 additions & 13 deletions

File tree

include/openmc/mesh.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,11 @@ class HexagonalMesh : public PeriodicStructuredMesh {
783783

784784
int set_grid();
785785

786+
enum class Orientation {
787+
y, //!< Flat side of lattice parallel to y-axis
788+
x //!< Flat side of lattice parallel to x-axis
789+
};
790+
786791
// Data members
787792
int num_rings_;
788793
double pitch_;
@@ -791,15 +796,9 @@ class HexagonalMesh : public PeriodicStructuredMesh {
791796
Direction r_;
792797
Direction q_dual_;
793798
Direction r_dual_;
794-
795-
private:
796-
enum class Orientation {
797-
y, //!< Flat side of lattice parallel to y-axis
798-
x //!< Flat side of lattice parallel to x-axis
799-
};
800-
801799
Orientation orientation_ {Orientation::y};
802800

801+
private:
803802
StructuredMesh::MeshDistance find_z_crossing(
804803
const Position& r, const Direction& u, double l, int shell) const;
805804

openmc/lib/mesh.py

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
__all__ = [
2020
'Mesh', 'RegularMesh', 'RectilinearMesh', 'CylindricalMesh',
21-
'SphericalMesh', 'UnstructuredMesh', 'meshes', 'MeshMaterialVolumes'
21+
'SphericalMesh', 'HexagonalMesh', 'UnstructuredMesh', 'meshes', 'MeshMaterialVolumes'
2222
]
2323

2424

@@ -108,6 +108,11 @@
108108
_dll.openmc_spherical_mesh_set_grid.restype = c_int
109109
_dll.openmc_spherical_mesh_set_grid.errcheck = _error_handler
110110

111+
_dll.openmc_hexagonal_mesh_get_grid.argtypes = [c_int32,
112+
POINTER(POINTER(c_double)), POINTER(c_int), POINTER(c_double),
113+
POINTER(POINTER(c_double)), POINTER(c_double), POINTER(c_char_p)]
114+
_dll.openmc_hexagonal_mesh_get_grid.restype = c_int
115+
_dll.openmc_hexagonal_mesh_get_grid.errcheck = _error_handler
111116

112117
class Mesh(_FortranObjectWithID):
113118
"""Base class to represent mesh objects
@@ -727,6 +732,91 @@ def set_grid(self, r_grid, theta_grid, phi_grid):
727732
ntheta, phi_grid, nphi)
728733

729734

735+
class HexagonalMesh(Mesh):
736+
"""HexagonalMesh stored internally.
737+
738+
This class exposes a mesh that is stored internally in the OpenMC
739+
library. To obtain a view of a mesh with a given ID, use the
740+
:data:`openmc.lib.meshes` mapping.
741+
742+
Parameters
743+
----------
744+
index : int
745+
Index in the `meshes` array.
746+
747+
Attributes
748+
----------
749+
id : int
750+
ID of the mesh
751+
z_grid : numpy.ndarray
752+
1-D array of mesh boundary points along the z-axis.
753+
pitch : float
754+
Radial pitch of the hexagonal mesh in cm.
755+
num_rings : int
756+
Number of radial ring positions in the xy-plane
757+
orientation : {'x', 'y'}
758+
The orientation of the lattice. The 'x' orientation means that each
759+
lattice element has two faces that are perpendicular to the x-axis,
760+
while the 'y' orientation means that each lattice element has two faces
761+
that are perpendicular to the y-axis. By default, the orientation is
762+
'y'.
763+
origin : numpy.ndarray
764+
1-D array of length 3 the (x,y,z) origin of the mesh in
765+
cartesian coordinates
766+
n_elements : int
767+
Total number of mesh elements.
768+
volumes : numpy.ndarray
769+
Volume of each mesh element in [cm^3]
770+
bounding_box : openmc.BoundingBox
771+
Axis-aligned bounding box of the mesh
772+
773+
"""
774+
mesh_type = 'hexagonal'
775+
776+
def __init__(self, uid=None, new=True, index=None):
777+
super().__init__(uid, new, index)
778+
779+
@property
780+
def n_elements(self):
781+
z_grid, nr, *_ = self._get_parameters()
782+
return (z_grid.size-1)*(3*nr*(nr-1)+1)
783+
784+
@property
785+
def num_rings(self):
786+
return self._get_parameters()[1]
787+
788+
@property
789+
def pitch(self):
790+
return self._get_parameters()[2]
791+
792+
@property
793+
def orientation(self):
794+
return self._get_parameters()[4]
795+
796+
@property
797+
def origin(self):
798+
return self._get_parameters()[3]
799+
800+
@property
801+
def z_grid(self):
802+
return self._get_parameters()[0]
803+
804+
def _get_parameters(self):
805+
gz = POINTER(c_double)()
806+
nz = c_int()
807+
nr = c_int()
808+
orig = POINTER(c_double)()
809+
orient = c_char()
810+
p = c_double()
811+
# Call C API to get grid parameters
812+
_dll.openmc_hexagonal_mesh_get_grid(self._index, gz, nz, nr, orig, p, orient)
813+
814+
# Convert grid parameters to Numpy arrays
815+
grid_z = as_array(gz, (nz.value,))
816+
origin = as_array(orig, (3,))
817+
818+
return (grid_z, nr, pitch, origin, orientation.decode())
819+
730820
class UnstructuredMesh(Mesh):
731821
pass
732822

@@ -736,6 +826,7 @@ class UnstructuredMesh(Mesh):
736826
'rectilinear': RectilinearMesh,
737827
'cylindrical': CylindricalMesh,
738828
'spherical': SphericalMesh,
829+
'hexagonal': HexagonalMesh,
739830
'unstructured': UnstructuredMesh
740831
}
741832

openmc/mesh.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2638,10 +2638,18 @@ def pitch(self, pitch):
26382638
cv.check_type('mesh radial pitch', pitch, Real)
26392639
cv.check_greater_than('mesh radial pitch', pitch, 0.0)
26402640
self._pitch = pitch
2641+
2642+
@property
2643+
def n_elements(self):
2644+
return (self.z_grid.size - 1)*(3*self.num_rings*(self.num_rings - 1) + 1)
2645+
2646+
@property
2647+
def dimension(self):
2648+
return (self.n_elements,)
26412649

26422650
@property
26432651
def n_dimension(self):
2644-
return 4
2652+
return 4
26452653

26462654
@property
26472655
def lower_left(self):
@@ -2695,7 +2703,7 @@ def indices(self):
26952703
idx = []
26962704
for j in range(self.z_grid.size-1):
26972705
idx.append((0, 0, 0, j))
2698-
for rad in range(1, self.num_rings+1):
2706+
for rad in range(1, self.num_rings):
26992707
for i in range(rad):
27002708
idx.append((i, rad-i, -rad, j))
27012709
idx.append((rad, -i, i-rad, j))

src/mesh.cpp

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2490,7 +2490,7 @@ std::string HexagonalMesh::surface_label(int surface) const
24902490

24912491
int HexagonalMesh::n_bins() const
24922492
{
2493-
return (1 + 3 * (num_rings_ + 1) * num_rings_) * (grid_.size() - 1);
2493+
return (1 + 3 * num_rings_ * (num_rings_ - 1)) * (grid_.size() - 1);
24942494
}
24952495

24962496
bool HexagonalMesh::valid_index(const MeshIndex& ijk, int k) const
@@ -2507,7 +2507,7 @@ int HexagonalMesh::get_bin_from_indices(const MeshIndex& ijk) const
25072507
int q = ijk[0];
25082508
int r = ijk[1];
25092509
int k = ijk[2];
2510-
int hexes = 3 * num_rings_ * (num_rings_ + 1) + 1;
2510+
int hexes = 3 * num_rings_ * (num_rings_ - 1) + 1;
25112511
int bin = (k - 1) * (grid_.size() - 1) * hexes;
25122512
int rad = std::max({std::abs(r), std::abs(q), std::abs(r + q)});
25132513
if (rad == 0)
@@ -2576,7 +2576,7 @@ StructuredMesh::MeshIndex HexagonalMesh::get_indices(
25762576
StructuredMesh::MeshIndex HexagonalMesh::get_indices_from_bin(int bin) const
25772577
{
25782578
MeshIndex ijk = {0, 0, 0};
2579-
int hexes = 3 * num_rings_ * (num_rings_ + 1) + 1;
2579+
int hexes = 3 * num_rings_ * (num_rings_ - 1) + 1;
25802580
ijk[2] = static_cast<int>(std::floor(bin / hexes)) + 1;
25812581
int sp_idx = bin % hexes;
25822582
if (sp_idx == 0) {
@@ -3277,6 +3277,28 @@ extern "C" int openmc_spherical_mesh_set_grid(int32_t index,
32773277
index, grid_x, nx, grid_y, ny, grid_z, nz);
32783278
}
32793279

3280+
//! Get the hexagonal mesh grid
3281+
extern "C" int openmc_hexagonal_mesh_get_grid(int32_t index, double** grid_z,
3282+
int* nz, int* nr, double** origin, double* pitch, const char** orient)
3283+
{
3284+
if (int err = check_mesh_type<HexagonalMesh>(index))
3285+
return err;
3286+
HexagonalMesh* m = dynamic_cast<HexagonalMesh*>(model::meshes[index].get());
3287+
3288+
if (m->grid_.empty()) {
3289+
set_errmsg("Mesh parameters have not been set.");
3290+
return OPENMC_E_ALLOCATE;
3291+
}
3292+
3293+
*grid_z = m->grid_.data();
3294+
*nz = m->grid_.size();
3295+
*nr = m->num_rings_;
3296+
*origin = &m->origin_.x;
3297+
*pitch = m->pitch_;
3298+
*orient = (m->orientation_ == HexagonalMesh::Orientation::y) ? "y" : "x";
3299+
return 0;
3300+
}
3301+
32803302
#ifdef OPENMC_DAGMC_ENABLED
32813303

32823304
const std::string MOABMesh::mesh_lib_type = "moab";

0 commit comments

Comments
 (0)