Implement CruciformPrism composite surface

This commit is contained in:
Paul Romano 2023-04-04 22:49:11 +02:00
parent e49c2c7d29
commit 95e3f94630
3 changed files with 137 additions and 2 deletions

View file

@ -630,7 +630,7 @@ class ZConeOneSided(CompositeSurface):
class Polygon(CompositeSurface):
"""Create a polygon composite surface from a path of closed points.
"""Polygon formed from a path of closed points.
.. versionadded:: 0.13.3
@ -1079,3 +1079,75 @@ class Polygon(CompositeSurface):
disp_vec = distance / costheta * unit_nvec
return type(self)(self.points + disp_vec, basis=self.basis)
class CruciformPrism(CompositeSurface):
"""Generalized cruciform prism
This surface represents a prism parallel to an axis formed by planes at
multiple distances from the center. Equivalent to the 'gcross' derived
surface in Serpent.
.. versionadded:: 0.13.4
Parameters
----------
distances : iterable of float
A monotonically increasing (or decreasing) iterable of distances in [cm]
that form the planes of the generalized cruciform.
center : iterable of float
The center of the prism in the two non-parallel axes (e.g., (x, y) when
axis is 'z') in [cm]
axis : {'x', 'y', 'z'}
Axis to which the prism is parallel
**kwargs
Keyword arguments passed to underlying plane classes
"""
def __init__(self, distances, center=(0., 0.), axis='z', **kwargs):
x0, y0 = center
self.distances = distances
if axis == 'x':
cls_horizontal = openmc.YPlane
cls_vertical = openmc.ZPlane
elif axis == 'y':
cls_horizontal = openmc.XPlane
cls_vertical = openmc.ZPlane
elif axis == 'z':
cls_horizontal = openmc.XPlane
cls_vertical = openmc.YPlane
else:
raise ValueError("axis must be 'x', 'y', or 'z'")
# Create each planar surface
surfnames = []
for i, d in enumerate(distances):
setattr(self, f'hmin{i}', cls_horizontal(x0 - d, **kwargs))
setattr(self, f'hmax{i}', cls_horizontal(x0 + d, **kwargs))
setattr(self, f'vmin{i}', cls_vertical(y0 - d, **kwargs))
setattr(self, f'vmax{i}', cls_vertical(y0 + d, **kwargs))
surfnames.extend([f'hmin{i}', f'hmax{i}', f'vmin{i}', f'vmax{i}'])
# Set _surfnames to satisfy CompositeSurface protocol
self._surfnames = tuple(surfnames)
@property
def _surface_names(self):
return self._surfnames
def __neg__(self):
n = len(self.distances)
regions = []
for i in range(n):
regions.append(
+getattr(self, f'hmin{i}') &
-getattr(self, f'hmax{i}') &
+getattr(self, f'vmin{n-1-i}') &
-getattr(self, f'vmax{n-1-i}')
)
return openmc.Union(regions)
def __pos__(self):
return ~(-self)