diff --git a/openmc/mesh.py b/openmc/mesh.py index a4c50a608..d4db5011b 100644 --- a/openmc/mesh.py +++ b/openmc/mesh.py @@ -514,7 +514,7 @@ class RegularMesh(StructuredMesh): def from_domain( cls, domain, - dimension=[100, 100, 100], + dimension=(10, 10, 10), mesh_id=None, name='' ): @@ -1137,6 +1137,76 @@ class CylindricalMesh(StructuredMesh): return mesh + @classmethod + def from_domain( + cls, + domain, + dimension=(10, 10, 10), + mesh_id=None, + phi_grid_bounds=(0.0, 2*pi), + name='' + ): + """Creates a regular CylindricalMesh from an existing openmc domain. + + Parameters + ---------- + domain : openmc.Cell or openmc.Region or openmc.Universe or openmc.Geometry + 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 r_grid, z_grid ranges. + dimension : Iterable of int + The number of equally spaced mesh cells in each direction (r_grid, + phi_grid, z_grid) + mesh_id : int + Unique identifier for the mesh + phi_grid_bounds : numpy.ndarray + Mesh bounds points along the phi-axis in radians. The default value + is (0, 2π), i.e., the full phi range. + name : str + Name of the mesh + + Returns + ------- + openmc.RegularMesh + RegularMesh instance + + """ + cv.check_type( + "domain", + domain, + (openmc.Cell, openmc.Region, openmc.Universe, openmc.Geometry), + ) + + mesh = cls(mesh_id, name) + + # loaded once to avoid reading h5m file repeatedly + cached_bb = domain.bounding_box + max_bounding_box_radius = max( + [ + cached_bb[0][0], + cached_bb[0][1], + cached_bb[1][0], + cached_bb[1][1], + ] + ) + mesh.r_grid = np.linspace( + 0, + max_bounding_box_radius, + num=dimension[0]+1 + ) + mesh.phi_grid = np.linspace( + phi_grid_bounds[0], + phi_grid_bounds[1], + num=dimension[1]+1 + ) + mesh.z_grid = np.linspace( + cached_bb[0][2], + cached_bb[1][2], + num=dimension[2]+1 + ) + + return mesh + def to_xml_element(self): """Return XML representation of the mesh diff --git a/tests/unit_tests/test_mesh_from_domain.py b/tests/unit_tests/test_mesh_from_domain.py index ce27288ad..b4edae196 100644 --- a/tests/unit_tests/test_mesh_from_domain.py +++ b/tests/unit_tests/test_mesh_from_domain.py @@ -16,6 +16,22 @@ def test_reg_mesh_from_cell(): assert np.array_equal(mesh.upper_right, cell.bounding_box[1]) +def test_cylindrical_mesh_from_cell(): + """Tests a CylindricalMesh can be made from a Cell and the specified + dimensions are propagated through. Cell is not centralized""" + cy_surface = openmc.ZCylinder(r=50) + z_surface_1 = openmc.ZPlane(z0=30) + z_surface_2 = openmc.ZPlane(z0=0) + cell = openmc.Cell(region=-cy_surface & -z_surface_1 & +z_surface_2) + mesh = openmc.CylindricalMesh.from_domain(cell, dimension=[2, 4, 3]) + + assert isinstance(mesh, openmc.CylindricalMesh) + assert np.array_equal(mesh.dimension, (2, 4, 3)) + assert np.array_equal(mesh.r_grid, [0., 25., 50.]) + assert np.array_equal(mesh.phi_grid, [0., 0.5*np.pi, np.pi, 1.5*np.pi, 2.*np.pi]) + assert np.array_equal(mesh.z_grid, [0., 10., 20., 30.]) + + def test_reg_mesh_from_region(): """Tests a RegularMesh can be made from a Region and the default dimensions are propagated through. Region is not centralized""" @@ -24,28 +40,48 @@ def test_reg_mesh_from_region(): mesh = openmc.RegularMesh.from_domain(region) assert isinstance(mesh, openmc.RegularMesh) - assert np.array_equal(mesh.dimension, (100, 100, 100)) # default values + assert np.array_equal(mesh.dimension, (10, 10, 10)) # default values assert np.array_equal(mesh.lower_left, region.bounding_box[0]) assert np.array_equal(mesh.upper_right, region.bounding_box[1]) +def test_cylindrical_mesh_from_region(): + """Tests a CylindricalMesh can be made from a Region and the specified + dimensions and phi_grid_bounds are propagated through. Cell is centralized""" + cy_surface = openmc.ZCylinder(r=6) + z_surface_1 = openmc.ZPlane(z0=30) + z_surface_2 = openmc.ZPlane(z0=-30) + cell = openmc.Cell(region=-cy_surface & -z_surface_1 & +z_surface_2) + mesh = openmc.CylindricalMesh.from_domain( + cell, + dimension=(6, 2, 3), + phi_grid_bounds=(0., np.pi) + ) + + assert isinstance(mesh, openmc.CylindricalMesh) + assert np.array_equal(mesh.dimension, (6, 2, 3)) + assert np.array_equal(mesh.r_grid, [0., 1., 2., 3., 4., 5., 6.]) + assert np.array_equal(mesh.phi_grid, [0., 0.5*np.pi, np.pi]) + assert np.array_equal(mesh.z_grid, [-30., -10., 10., 30.]) + + def test_reg_mesh_from_universe(): - """Tests a RegularMesh can be made from a Universe and the default dimensions - are propagated through. Universe is centralized""" + """Tests a RegularMesh can be made from a Universe and the default + dimensions are propagated through. Universe is centralized""" surface = openmc.Sphere(r=42) cell = openmc.Cell(region=-surface) universe = openmc.Universe(cells=[cell]) mesh = openmc.RegularMesh.from_domain(universe) assert isinstance(mesh, openmc.RegularMesh) - assert np.array_equal(mesh.dimension, (100, 100, 100)) # default values + assert np.array_equal(mesh.dimension, (10, 10, 10)) # default values assert np.array_equal(mesh.lower_left, universe.bounding_box[0]) assert np.array_equal(mesh.upper_right, universe.bounding_box[1]) def test_reg_mesh_from_geometry(): - """Tests a RegularMesh can be made from a Geometry and the default dimensions - are propagated through. Geometry is centralized""" + """Tests a RegularMesh can be made from a Geometry and the default + dimensions are propagated through. Geometry is centralized""" surface = openmc.Sphere(r=42) cell = openmc.Cell(region=-surface) universe = openmc.Universe(cells=[cell]) @@ -53,7 +89,7 @@ def test_reg_mesh_from_geometry(): mesh = openmc.RegularMesh.from_domain(geometry) assert isinstance(mesh, openmc.RegularMesh) - assert np.array_equal(mesh.dimension, (100, 100, 100)) # default values + assert np.array_equal(mesh.dimension, (10, 10, 10)) # default values assert np.array_equal(mesh.lower_left, geometry.bounding_box[0]) assert np.array_equal(mesh.upper_right, geometry.bounding_box[1])