automatically finding appropriate dimension when making regular mesh from domain (#3468)

This commit is contained in:
Jonathan Shimwell 2025-07-18 08:46:13 +02:00 committed by GitHub
parent bca818ced6
commit 4483583ddd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 40 additions and 3 deletions

View file

@ -1094,7 +1094,7 @@ class RegularMesh(StructuredMesh):
def from_domain(
cls,
domain: HasBoundingBox,
dimension: Sequence[int] = (10, 10, 10),
dimension: Sequence[int] | int = 1000,
mesh_id: int | None = None,
name: str = ''
):
@ -1106,8 +1106,11 @@ class RegularMesh(StructuredMesh):
The object passed in will be used as a template for this mesh. The
bounding box of the property of the object passed will be used to
set the lower_left and upper_right and of the mesh instance
dimension : Iterable of int
The number of mesh cells in each direction (x, y, z).
dimension : Iterable of int | int
The number of mesh cells in total or number of mesh cells in each
direction (x, y, z). If a single integer is provided, the domain
will will be divided into that many mesh cells with roughly equal
lengths in each direction (cubes).
mesh_id : int
Unique identifier for the mesh
name : str
@ -1125,6 +1128,16 @@ class RegularMesh(StructuredMesh):
mesh = cls(mesh_id=mesh_id, name=name)
mesh.lower_left = domain.bounding_box[0]
mesh.upper_right = domain.bounding_box[1]
if isinstance(dimension, int):
cv.check_greater_than("dimension", dimension, 1, equality=True)
# If a single integer is provided, divide the domain into that many
# mesh cells with roughly equal lengths in each direction
ideal_cube_volume = domain.bounding_box.volume / dimension
ideal_cube_size = ideal_cube_volume ** (1 / 3)
dimension = [
max(1, int(round(side / ideal_cube_size)))
for side in domain.bounding_box.width
]
mesh.dimension = dimension
return mesh

View file

@ -147,3 +147,27 @@ def test_reg_mesh_from_geometry():
def test_error_from_unsupported_object():
with pytest.raises(TypeError):
openmc.RegularMesh.from_domain("vacuum energy")
def test_regularmesh_from_domain_error_from_small_dimensions():
surface = openmc.Sphere(r=20)
cell = openmc.Cell(region=-surface)
with pytest.raises(
ValueError, match='Unable to set "dimension" to "-2" since it is less than "1"'
):
openmc.RegularMesh.from_domain(domain=cell, dimension=-2)
def test_dimensions_from_domain_dimensions_from_int():
region = openmc.model.RectangularParallelepiped(
xmin=-100,
xmax=150,
ymin=-50,
ymax=200,
zmin=300,
zmax=400,
boundary_type="vacuum",
)
cell = openmc.Cell(region=-region)
mesh = openmc.RegularMesh.from_domain(domain=cell, dimension=1000)
assert mesh.dimension == (14, 14, 5)