Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding wedge shaped option to DAGMCUniverse.bounded_universe() #3236

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 139 additions & 10 deletions openmc/universe.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import openmc
import openmc.checkvalue as cv
from ._xml import get_text
from .checkvalue import check_type, check_value
from .checkvalue import check_type, check_value, check_iterable_type
from .mixin import IDManagerMixin
from .surface import _BOUNDARY_TYPES
from .utility_funcs import input_path
Expand Down Expand Up @@ -995,11 +995,11 @@ def bounding_region(
Region instance
"""

check_type('boundary type', boundary_type, str)
check_value('boundary type', boundary_type, _BOUNDARY_TYPES)
check_type('starting surface id', starting_id, Integral)
check_type('bounded type', bounded_type, str)
check_value('bounded type', bounded_type, ('box', 'sphere'))
check_type("boundary type", boundary_type, str)
check_value("boundary type", boundary_type, _BOUNDARY_TYPES)
check_type("starting surface id", starting_id, Integral)
check_type("bounded type", bounded_type, str)
check_value("bounded type", bounded_type, ("box", "sphere", "wedge"))

bbox = self.bounding_box.expand(padding_distance, True)

Expand Down Expand Up @@ -1032,25 +1032,154 @@ def bounding_region(

return region

def bounded_universe(self, bounding_cell_id=10000, **kwargs):
def bounding_wedge_region(
self,
boundary_type_angled_planes: str = "reflective",
boundary_type_others: str = "vacuum",
starting_id: int = 10000,
padding_distance: float = 0.0,
wedge_angles: Iterable[float] = (0, 180),
shimwell marked this conversation as resolved.
Show resolved Hide resolved
):
"""
Create a region bounded by a Z axis aligned cylindrical surface, two
Z planes and two angled planar surfaces forming a wedge. Assumes the
geometry is centered at the origin.

Parameters
----------
boundary_type_angled_planes : str
Boundary condition that defines the behavior for particles hitting
the plane surfaces on the angled sides of the wedge. Defaults to
'reflective' boundary condition. Passed into the surface
construction.
boundary_type_others : str
Boundary condition that defines the behavior for particles hitting
the cylindrical surface or the upper and lower planes. Defaults to
'vacuum' boundary condition. Passed into the surface construction.
starting_id : int
Starting ID of the surface(s) used in the region. For bounded_type
'box', the next 5 IDs will also be used. Defaults to 10000 to reduce
the chance of an overlap of surface IDs with the DAGMC geometry.
padding_distance : float
Distance between the bounding region surfaces and the minimal
bounding box. Allows for the region to be larger than the DAGMC
geometry. Only changes the cylindrical surface radius and the upper
and lower Z plane surfaces z0 values.
wedge_angles : Iterable[float]
Angles (in degrees) defining the angles of the side planes used for
the wedge. Default is (0, 180).

Returns
-------
openmc.Region
Region bounded by the cylindrical surface and the two planar surfaces.
"""

check_value("boundary_type_others", boundary_type_others, _BOUNDARY_TYPES)
check_value(
"boundary_type_angled_planes", boundary_type_angled_planes, _BOUNDARY_TYPES
)
check_type("starting surface id", starting_id, Integral)
check_type("padding distance", padding_distance, float)
# check_iterable_type('wedge_angles', wedge_angles, float)

bbox = self.bounding_box.expand(padding_distance, True)

radius_upper_right = np.linalg.norm(
np.array(bbox[0][0], bbox[0][1]) - np.array([0.0, 0.0])
)
radius_lower_left = np.linalg.norm(
np.array(bbox[1][0], bbox[1][1]) - np.array([0.0, 0.0])
)
radius = max(radius_upper_right, radius_lower_left)
Comment on lines +1088 to +1094
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
radius_upper_right = np.linalg.norm(
np.array(bbox[0][0], bbox[0][1]) - np.array([0.0, 0.0])
)
radius_lower_left = np.linalg.norm(
np.array(bbox[1][0], bbox[1][1]) - np.array([0.0, 0.0])
)
radius = max(radius_upper_right, radius_lower_left)
radius = max(abs(bbox[0][0]), abs(bbox[0][1]), abs(bbox[1][0]), abs(bbox[1][1]))

I think this can be simplified in this cylindrical surface case


cylinder_surface = openmc.ZCylinder(
r=radius, surface_id=starting_id, boundary_type=boundary_type_others
)

wedge_angle_surf_1 = openmc.Plane(
a=math.sin(math.radians(wedge_angles[0])),
b=-math.cos(math.radians(wedge_angles[0])),
c=0.0,
d=0.0,
surface_id=starting_id + 1,
boundary_type=boundary_type_angled_planes,
)

wedge_angle_surf_2 = openmc.Plane(
a=math.sin(math.radians(wedge_angles[1])),
b=-math.cos(math.radians(wedge_angles[1])),
c=0.0,
d=0.0,
surface_id=starting_id + 2,
boundary_type=boundary_type_angled_planes,
)

lower_z = openmc.ZPlane(
bbox[0][2], boundary_type=boundary_type_others, surface_id=starting_id + 4
)
upper_z = openmc.ZPlane(
bbox[1][2], boundary_type=boundary_type_others, surface_id=starting_id + 5
)

if wedge_angles[1] - wedge_angles[0] >= 180.0:
region = (
-cylinder_surface
& +lower_z
& -upper_z
& (-wedge_angle_surf_1 | +wedge_angle_surf_2)
)
else:
region = (
-cylinder_surface
& +lower_z
& -upper_z
& -wedge_angle_surf_1
& +wedge_angle_surf_2
)

return region

def bounded_universe(self, bounding_cell_id=10000, bounded_type="box", **kwargs):
"""Returns an openmc.Universe filled with this DAGMCUniverse and bounded
with a cell. Defaults to a box cell with a vacuum surface however this
can be changed using the kwargs which are passed directly to
DAGMCUniverse.bounding_region().
either DAGMCUniverse.bounding_region() for bounded_type 'box' or
'sphere' and passed to DAGMCUniverse.bounding_wedge_region() for
bounded_type 'wedge'.

Parameters
----------
bounding_cell_id : int
The cell ID number to use for the bounding cell, defaults to 10000 to reduce
the chance of overlapping ID numbers with the DAGMC geometry.
bounded_type : str
The type of bounding surface(s) to use when constructing the region.
Options include a single spherical surface (sphere) or a rectangle
made from six planes (box) or a (wedge) shape made from a
cylindrical surface and four planes.

Returns
-------
openmc.Universe
Universe instance
"""
bounding_cell = openmc.Cell(
fill=self, cell_id=bounding_cell_id, region=self.bounding_region(**kwargs))

check_value("bounded type", bounded_type, ("box", "sphere", "wedge"))
if bounded_type in ["box", "sphere"]:
bounding_cell = openmc.Cell(
fill=self,
cell_id=bounding_cell_id,
region=self.bounding_region(bounded_type=bounded_type, **kwargs),
)
else: # bounded_type is wedge
# Remove 'bounded_type' from kwargs before passing to bounding_wedge_region
kwargs.pop("bounded_type", None)
bounding_cell = openmc.Cell(
fill=self,
cell_id=bounding_cell_id,
region=self.bounding_wedge_region(**kwargs),
)
return openmc.Universe(cells=[bounding_cell])

@classmethod
Expand Down
37 changes: 37 additions & 0 deletions tests/unit_tests/dagmc/test_bounds.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,43 @@ def test_bounding_region(request):
larger_region = u.bounding_region(bounded_type="sphere", padding_distance=10)
assert larger_region.surface.r > region.surface.r

# angle less than 180 so union not used for surfaces
region = u.bounding_wedge_region(wedge_angles=(0, 90))
assert isinstance(region, openmc.Region)
assert len(region) == 5
assert region[0].surface.type == "z-cylinder"
assert region[1].surface.type == "z-plane"
assert region[1].surface.z0 == -25.0
assert region[2].surface.type == "z-plane"
assert region[2].surface.z0 == 25.0
assert region[3].surface.type == "plane"
assert region[4].surface.type == "plane"
assert region[0].surface.boundary_type == "vacuum"
assert region[1].surface.boundary_type == "vacuum"
assert region[2].surface.boundary_type == "vacuum"
assert region[3].surface.boundary_type == "reflective"
assert region[4].surface.boundary_type == "reflective"
# angle above 180 so union used for surfaces
larger_region = u.bounding_wedge_region(
wedge_angles=(0, 200), padding_distance=10.0
)
assert larger_region[0].surface.r > region[0].surface.r
assert larger_region[1].surface.z0 == -35.0
assert larger_region[2].surface.z0 == 35.0
assert len(larger_region) == 4
# angle above 180 (by default) so union used for surfaces
region = u.bounding_wedge_region(boundary_type_others="periodic")
assert region[0].surface.boundary_type == "periodic"
assert region[1].surface.boundary_type == "periodic"
assert region[2].surface.boundary_type == "periodic"
assert len(region) == 4
# angle above 180 (by default) so union used for surfaces
region = u.bounding_wedge_region(boundary_type_angled_planes="white")
assert region[0].surface.boundary_type == "vacuum"
assert region[1].surface.boundary_type == "vacuum"
assert region[2].surface.boundary_type == "vacuum"
assert len(region) == 4


def test_bounded_universe(request):
"""Checks that the DAGMCUniverse.bounded_universe() returns a
Expand Down
Loading