Skip to content

Commit 3ff6b59

Browse files
authored
Allow Mesh.from_domain to use bounding boxes directly (#3828)
1 parent e130701 commit 3ff6b59

2 files changed

Lines changed: 49 additions & 25 deletions

File tree

openmc/mesh.py

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,7 +1188,7 @@ def from_rect_lattice(
11881188
@classmethod
11891189
def from_domain(
11901190
cls,
1191-
domain: HasBoundingBox,
1191+
domain: HasBoundingBox | BoundingBox,
11921192
dimension: Sequence[int] | int = 1000,
11931193
mesh_id: int | None = None,
11941194
name: str = ''
@@ -1197,10 +1197,12 @@ def from_domain(
11971197
11981198
Parameters
11991199
----------
1200-
domain : HasBoundingBox
1200+
domain : HasBoundingBox | openmc.BoundingBox
12011201
The object passed in will be used as a template for this mesh. The
12021202
bounding box of the property of the object passed will be used to
1203-
set the lower_left and upper_right and of the mesh instance
1203+
set the lower_left and upper_right and of the mesh instance.
1204+
Alternatively, a :class:`openmc.BoundingBox` can be passed
1205+
directly.
12041206
dimension : Iterable of int | int
12051207
The number of mesh cells in total or number of mesh cells in each
12061208
direction (x, y, z). If a single integer is provided, the domain
@@ -1217,21 +1219,26 @@ def from_domain(
12171219
RegularMesh instance
12181220
12191221
"""
1220-
if not hasattr(domain, 'bounding_box'):
1221-
raise TypeError("Domain must have a bounding_box property")
1222+
if isinstance(domain, BoundingBox):
1223+
bb = domain
1224+
elif hasattr(domain, 'bounding_box'):
1225+
bb = domain.bounding_box
1226+
else:
1227+
raise TypeError("Domain must be a BoundingBox or have a "
1228+
"bounding_box property")
12221229

12231230
mesh = cls(mesh_id=mesh_id, name=name)
1224-
mesh.lower_left = domain.bounding_box[0]
1225-
mesh.upper_right = domain.bounding_box[1]
1231+
mesh.lower_left = bb[0]
1232+
mesh.upper_right = bb[1]
12261233
if isinstance(dimension, int):
12271234
cv.check_greater_than("dimension", dimension, 1, equality=True)
12281235
# If a single integer is provided, divide the domain into that many
12291236
# mesh cells with roughly equal lengths in each direction
1230-
ideal_cube_volume = domain.bounding_box.volume / dimension
1237+
ideal_cube_volume = bb.volume / dimension
12311238
ideal_cube_size = ideal_cube_volume ** (1 / 3)
12321239
dimension = [
12331240
max(1, int(round(side / ideal_cube_size)))
1234-
for side in domain.bounding_box.width
1241+
for side in bb.width
12351242
]
12361243
mesh.dimension = dimension
12371244

@@ -1904,7 +1911,7 @@ def from_hdf5(cls, group: h5py.Group, mesh_id: int, name: str):
19041911
@classmethod
19051912
def from_domain(
19061913
cls,
1907-
domain: HasBoundingBox,
1914+
domain: HasBoundingBox | BoundingBox,
19081915
dimension: Sequence[int] = (10, 10, 10),
19091916
mesh_id: int | None = None,
19101917
phi_grid_bounds: Sequence[float] = (0.0, 2*pi),
@@ -1915,10 +1922,11 @@ def from_domain(
19151922
19161923
Parameters
19171924
----------
1918-
domain : HasBoundingBox
1925+
domain : HasBoundingBox | openmc.BoundingBox
19191926
The object passed in will be used as a template for this mesh. The
19201927
bounding box of the property of the object passed will be used to
1921-
set the r_grid, z_grid ranges.
1928+
set the r_grid, z_grid ranges. Alternatively, a
1929+
:class:`openmc.BoundingBox` can be passed directly.
19221930
dimension : Iterable of int
19231931
The number of equally spaced mesh cells in each direction (r_grid,
19241932
phi_grid, z_grid)
@@ -1939,11 +1947,13 @@ def from_domain(
19391947
CylindricalMesh instance
19401948
19411949
"""
1942-
if not hasattr(domain, 'bounding_box'):
1943-
raise TypeError("Domain must have a bounding_box property")
1944-
1945-
# loaded once to avoid recalculating bounding box
1946-
cached_bb = domain.bounding_box
1950+
if isinstance(domain, BoundingBox):
1951+
cached_bb = domain
1952+
elif hasattr(domain, 'bounding_box'):
1953+
cached_bb = domain.bounding_box
1954+
else:
1955+
raise TypeError("Domain must be a BoundingBox or have a "
1956+
"bounding_box property")
19471957

19481958
if enclose_domain:
19491959
outer_radius = 0.5 * np.linalg.norm(cached_bb.width[:2])
@@ -2290,7 +2300,7 @@ def from_hdf5(cls, group: h5py.Group, mesh_id: int, name: str):
22902300
@classmethod
22912301
def from_domain(
22922302
cls,
2293-
domain: HasBoundingBox,
2303+
domain: HasBoundingBox | BoundingBox,
22942304
dimension: Sequence[int] = (10, 10, 10),
22952305
mesh_id: int | None = None,
22962306
phi_grid_bounds: Sequence[float] = (0.0, 2*pi),
@@ -2302,10 +2312,11 @@ def from_domain(
23022312
23032313
Parameters
23042314
----------
2305-
domain : HasBoundingBox
2315+
domain : HasBoundingBox | openmc.BoundingBox
23062316
The object passed in will be used as a template for this mesh. The
23072317
bounding box of the property of the object passed will be used to
2308-
set the r_grid, phi_grid, and theta_grid ranges.
2318+
set the r_grid, phi_grid, and theta_grid ranges. Alternatively, a
2319+
:class:`openmc.BoundingBox` can be passed directly.
23092320
dimension : Iterable of int
23102321
The number of equally spaced mesh cells in each direction (r_grid,
23112322
phi_grid, theta_grid). Spacing is in angular space (radians) for
@@ -2330,11 +2341,13 @@ def from_domain(
23302341
SphericalMesh instance
23312342
23322343
"""
2333-
if not hasattr(domain, 'bounding_box'):
2334-
raise TypeError("Domain must have a bounding_box property")
2335-
2336-
# loaded once to avoid recalculating bounding box
2337-
cached_bb = domain.bounding_box
2344+
if isinstance(domain, BoundingBox):
2345+
cached_bb = domain
2346+
elif hasattr(domain, 'bounding_box'):
2347+
cached_bb = domain.bounding_box
2348+
else:
2349+
raise TypeError("Domain must be a BoundingBox or have a "
2350+
"bounding_box property")
23382351

23392352
if enclose_domain:
23402353
outer_radius = 0.5 * np.linalg.norm(cached_bb.width)

tests/unit_tests/test_mesh_from_domain.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,17 @@ def test_reg_mesh_from_cell():
1616
assert np.array_equal(mesh.upper_right, cell.bounding_box[1])
1717

1818

19+
def test_reg_mesh_from_bounding_box():
20+
"""Tests a RegularMesh can be made from a BoundingBox directly."""
21+
bb = openmc.BoundingBox([-8, -7, -5], [12, 13, 15])
22+
23+
mesh = openmc.RegularMesh.from_domain(domain=bb, dimension=[7, 11, 13])
24+
assert isinstance(mesh, openmc.RegularMesh)
25+
assert np.array_equal(mesh.dimension, (7, 11, 13))
26+
assert np.array_equal(mesh.lower_left, bb[0])
27+
assert np.array_equal(mesh.upper_right, bb[1])
28+
29+
1930
def test_cylindrical_mesh_from_cell():
2031
"""Tests a CylindricalMesh can be made from a Cell and the specified
2132
dimensions are propagated through."""

0 commit comments

Comments
 (0)