Merge pull request #2118 from shimwell/adding_dagmcuniverse_bounding_region

added DAGMCUniverse.bounding_region
This commit is contained in:
Patrick Shriwise 2022-07-25 15:30:21 -05:00 committed by GitHub
commit 584b47006c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 107 additions and 9 deletions

View file

@ -12,9 +12,12 @@ import numpy as np
import openmc
import openmc.checkvalue as cv
from ._xml import get_text
from .checkvalue import check_type, check_value
from .mixin import IDManagerMixin
from .plots import _SVG_COLORS
from .surface import _BOUNDARY_TYPES
class UniverseBase(ABC, IDManagerMixin):
@ -713,6 +716,78 @@ class DAGMCUniverse(UniverseBase):
dagmc_element.set('filename', self.filename)
xml_element.append(dagmc_element)
def bounding_region(self, bounded_type='box', boundary_type='vacuum'):
"""Creates a either a spherical or box shaped bounding region around
the DAGMC geometry.
Parameters
----------
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).
boundary_type : str
Boundary condition that defines the behavior for particles hitting
the surface. Defaults to vacuum boundary condition. Passed into the
surface construction.
Returns
-------
openmc.Region
Region instance
"""
check_type('boundary type', boundary_type, str)
check_value('boundary type', boundary_type, _BOUNDARY_TYPES)
check_type('bounded type', bounded_type, str)
check_value('bounded type', bounded_type, ('box', 'sphere'))
bounding_box = self.bounding_box
if bounded_type == 'sphere':
import math
bounding_box_center = (bounding_box[0] + bounding_box[1])/2
radius = math.dist(bounding_box[0], bounding_box[1])
bounding_surface = openmc.Sphere(
x0=bounding_box_center[0],
y0=bounding_box_center[1],
z0=bounding_box_center[2],
boundary_type=boundary_type,
r=radius,
)
return -bounding_surface
if bounded_type == 'box':
# defines plane surfaces for all six faces of the bounding box
lower_x = openmc.XPlane(bounding_box[0][0], boundary_type=boundary_type)
upper_x = openmc.XPlane(bounding_box[1][0], boundary_type=boundary_type)
lower_y = openmc.YPlane(bounding_box[0][1], boundary_type=boundary_type)
upper_y = openmc.YPlane(bounding_box[1][1], boundary_type=boundary_type)
lower_z = openmc.ZPlane(bounding_box[0][2], boundary_type=boundary_type)
upper_z = openmc.ZPlane(bounding_box[1][2], boundary_type=boundary_type)
return +lower_x & -upper_x & +lower_y & -upper_y & +lower_z & -upper_z
def bounded_universe(self, bounding_cell_id=10000, **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().
Parameters
----------
bounding_cell_id : int
The cell ID number to use for the bounding cell, defaults to 1000 to reduce
the chance of overlapping ID numbers with the DAGMC geometry.
Returns
-------
openmc.Universe
Universe instance
"""
bounding_cell = openmc.Cell(fill=self, cell_id =bounding_cell_id, region=self.bounding_region(**kwargs))
return openmc.Universe(cells=[bounding_cell])
@classmethod
def from_hdf5(cls, group):
"""Create DAGMC universe from HDF5 group

View file

@ -183,7 +183,9 @@ void DAGUniverse::init_geometry()
} else {
warning(fmt::format("DAGMC Cell IDs: {}", dagmc_ids_for_dim(3)));
fatal_error(fmt::format("Cell ID {} exists in both DAGMC Universe {} "
"and the CSG geometry.",
"and the CSG geometry. Setting auto_geom_ids "
"to True when initiating the DAGMC Universe may "
"resolve this issue",
c->id_, this->id_));
}

View file

@ -1,8 +1,8 @@
<?xml version='1.0' encoding='utf-8'?>
<geometry>
<cell fill="10" id="13" region="9 -10 11 -12 13 -14" universe="11" />
<cell fill="12" id="13" region="22 -23 24 -25 26 -27" universe="13" />
<dagmc_universe auto_geom_ids="true" filename="dagmc.h5m" id="9" />
<lattice id="10">
<lattice id="12">
<pitch>24.0 24.0</pitch>
<dimension>2 2</dimension>
<lower_left>-24.0 -24.0</lower_left>
@ -10,12 +10,12 @@
9 9
9 9 </universes>
</lattice>
<surface boundary="reflective" coeffs="-24.0" id="9" name="left" type="x-plane" />
<surface boundary="reflective" coeffs="24.0" id="10" name="right" type="x-plane" />
<surface boundary="reflective" coeffs="-24.0" id="11" name="front" type="y-plane" />
<surface boundary="reflective" coeffs="24.0" id="12" name="back" type="y-plane" />
<surface boundary="reflective" coeffs="-10.0" id="13" name="bottom" type="z-plane" />
<surface boundary="reflective" coeffs="10.0" id="14" name="top" type="z-plane" />
<surface boundary="reflective" coeffs="-24.0" id="22" name="left" type="x-plane" />
<surface boundary="reflective" coeffs="24.0" id="23" name="right" type="x-plane" />
<surface boundary="reflective" coeffs="-24.0" id="24" name="front" type="y-plane" />
<surface boundary="reflective" coeffs="24.0" id="25" name="back" type="y-plane" />
<surface boundary="reflective" coeffs="-10.0" id="26" name="bottom" type="z-plane" />
<surface boundary="reflective" coeffs="10.0" id="27" name="top" type="z-plane" />
</geometry>
<?xml version='1.0' encoding='utf-8'?>
<materials>

View file

@ -46,11 +46,32 @@ class DAGMCUniverseTest(PyAPITestHarness):
# create the DAGMC universe
pincell_univ = openmc.DAGMCUniverse(filename='dagmc.h5m', auto_geom_ids=True)
# creates another DAGMC universe, this time with within a bounded cell
bound_pincell_universe = openmc.DAGMCUniverse(filename='dagmc.h5m').bounded_universe()
# uses the bound_dag_cell as the root argument to test the type checks in openmc.Geometry
bound_pincell_geometry = openmc.Geometry(root=bound_pincell_universe)
# assigns the bound_dag_geometry to the model to test the type checks in model.Geometry setter
model.Geometry = bound_pincell_geometry
# checks that the bounding box is calculated correctly
bounding_box = pincell_univ.bounding_box
assert bounding_box[0].tolist() == [-25., -25., -25.]
assert bounding_box[1].tolist() == [25., 25., 25.]
# checks that the bounding region is six surfaces each with a vacuum boundary type
b_region = pincell_univ.bounding_region(bounded_type='box', boundary_type='vacuum')
assert isinstance(b_region, openmc.Region)
assert len(b_region.get_surfaces()) == 6
for surface in list(b_region.get_surfaces().values()):
assert surface.boundary_type == 'vacuum'
# checks that the bounding region is a single surface with a reflective boundary type
b_region = pincell_univ.bounding_region(bounded_type='sphere', boundary_type='reflective')
assert isinstance(b_region, openmc.Region)
assert len(b_region.get_surfaces()) == 1
for surface in list(b_region.get_surfaces().values()):
assert surface.boundary_type == 'reflective'
# create a 2 x 2 lattice using the DAGMC pincell
pitch = np.asarray((24.0, 24.0))
lattice = openmc.RectLattice()