make theta1,theta2 formulation the default; add alternate constructor for theta,alpha formulation

This commit is contained in:
yardasol 2022-04-27 12:56:39 -05:00
parent fc3809c2df
commit 51e5d1ccd2
2 changed files with 106 additions and 32 deletions

View file

@ -66,26 +66,27 @@ class CylinderSector(CompositeSurface):
Parameters
----------
center : iterable of float
Coordinate for central axes of cylinders in the (y, z), (z, x), or (x, y)
basis. Defaults to (0,0).
r1 : float
Inner radius of sector. Must be less than r2.
r2 : float
Outer radius of sector. Must be greater than r1.
central_angle : float
Central angle, :math:`\\theta`, of the sector in degrees. Must be
greater that 0 and less than 360.
ccw_offset : float
Angular offset, :math:`\\alpha`, of the clockwise-most side of the
sector in degrees. The offset is in the counter-clockwise direction
with respect to the first basis axis (+y, +z, or +x). Note that
negative values translate to an offset in the clockwise direction.
theta1 : float
Clockwise-most bound of sector in degrees. Assumed to be in the
counterclockwise direction with respect to the first basis axis
(+y, +z, or +x). Must be less than :attr:`theta2`.
theta2 : float
Counterclockwise-most bound of sector in degrees. Assumed to be in the
counterclockwise direction with respect to the first basis axis
(+y, +z, or +x). Must be greater than :attr:`theta1`.
center : iterable of float
Coordinate for central axes of cylinders in the (y, z), (z, x), or (x, y)
basis. Defaults to (0,0).
axis : {'x', 'y', 'z'}
Central axis of the cylinders defining the inner and outer surfaces of
the sector. Defaults to 'z'.
**kwargs
Keyword arguments passed to underlying plane classes.
kwargs : dict
Keyword arguments passed to the :class:`Cylinder` and :class:`Plane` constructors.
Attributes
----------
@ -94,32 +95,34 @@ class CylinderSector(CompositeSurface):
inner_cyl : openmc.ZCylinder, openmc.YCylinder, or openmc.XCylinder
Inner cylinder surface.
plane1 : openmc.Plane
Plane at angle :math:`\\phi_1 = \\alpha` relative to the first basis axis.
Plane at angle :math:`\\theta_1` relative to the first basis axis.
plane2 : openmc.Plane
Plane at angle :math:`\\phi_2 = \\alpha + \\theta` relative to the first
basis axis.
Plane at angle :math:`\\theta_2` relative to the first basis axis.
"""
_surface_names = ('outer_cyl', 'inner_cyl', 'plane1', 'plane2')
def __init__(self,
center,
r1,
r2,
central_angle,
ccw_offset,
theta1,
theta2,
center=(0.,0.),
axis='z',
**kwargs):
if r2 <= r1 * sqrt(2):
raise ValueError(f'r2 must be greater than r1.')
if central_angle >= 360. or central_angle <= 0:
raise ValueError(f'theta must be less than 360.')
if theta2 <= theta1:
raise ValueError(f'theta2 must be greater than theta1.')
phi1 = pi / 180 * ccw_offset
phi2 = pi / 180 * (ccw_offset + central_angle)
self._theta1 = theta1
self._theta2 = theta2
phi1 = pi / 180 * theta1
phi2 = pi / 180 * theta2
# Coords for axis-perpendicular planes
p1 = np.array([0., 0., 1.])
@ -152,6 +155,59 @@ class CylinderSector(CompositeSurface):
self.plane2 = openmc.Plane.from_points(p1, p2_plane2, p3_plane2,
**kwargs)
@classmethod
def from_theta_alpha(cls,
r1,
r2,
theta,
alpha,
center = (0.,0.),
axis='z',
**kwargs):
"""Alternate constructor for :attr:`CylinderSector`. Returns an
:attr:`CylinderSector` object based on a central angle :math:`\\theta`
and an angular offset :math:`\\alpha`. Note that
:math:`\\theta_1 = \\alpha` and :math:`\\theta_2 = \\alpha + \\theta`.
Parameters
----------
r1 : float
Inner radius of sector. Must be less than r2.
r2 : float
Outer radius of sector. Must be greater than r1.
theta : float
Central angle, :math:`\\theta`, of the sector in degrees. Must be
greater that 0 and less than 360.
alpha : float
Angular offset, :math:`\\alpha`, of sector in degrees.
The offset is in the counter-clockwise direction
with respect to the first basis axis (+y, +z, or +x). Note that
negative values translate to an offset in the clockwise direction.
center : iterable of float
Coordinate for central axes of cylinders in the (y, z), (z, x), or (x, y)
basis. Defaults to (0,0).
axis : {'x', 'y', 'z'}
Central axis of the cylinders defining the inner and outer surfaces of
the sector. Defaults to 'z'.
kwargs : dict
Keyword arguments passed to the :class:`Cylinder` and :class:`Plane` constructors.
Returns
-------
CylinderSector
CylinderSector with the given central angle at the given
offset.
"""
if theta >= 360. or theta <= 0:
raise ValueError(f'theta must be less than 360 and greater than 0.')
theta1 = alpha
theta2 = alpha + theta
return cls(r1, r2, theta1, theta2, center=center, axis=axis, **kwargs)
def __neg__(self):
return -self.outer_cyl & +self.inner_cyl & -self.plane1 & +self.plane2

View file

@ -161,12 +161,11 @@ def test_cone_one_sided(axis, point_pos, point_neg, ll_true):
]
)
def test_cylinder_sector(axis, indices):
center = [0., 0.]
r1, r2 = 0.5, 1.5
d = (r2 - r1) / 2
central_angle = 120.
ccw_offset = -60.
s = openmc.model.CylinderSector(center, r1, r2, central_angle, ccw_offset,
phi1 = -60.
phi2 = 60
s = openmc.model.CylinderSector(r1, r2, phi1, phi2,
axis=axis.lower())
assert isinstance(s.outer_cyl, getattr(openmc, axis + "Cylinder"))
assert isinstance(s.inner_cyl, getattr(openmc, axis + "Cylinder"))
@ -206,18 +205,37 @@ def test_cylinder_sector(axis, indices):
# Check invalid r1, r2 combinations
with pytest.raises(ValueError):
openmc.model.CylinderSector(center, 10., 1., central_angle, ccw_offset)
openmc.model.CylinderSector(r2, r1, phi1, phi2)
# Check invalid sector width
# Check invalid angles
with pytest.raises(ValueError):
openmc.model.CylinderSector(center, 1., 10., 360, ccw_offset)
with pytest.raises(ValueError):
openmc.model.CylinderSector(center, 1., 10., -1, ccw_offset)
openmc.model.CylinderSector(r1, r2, phi2, phi1)
# Make sure repr works
repr(s)
def test_cylinder_sector_from_theta_alpha():
r1, r2 = 0.5, 1.5
d = (r2 - r1) / 2
theta = 120.
alpha = -60.
s = openmc.model.CylinderSector.from_theta_alpha(r1,
r2,
theta,
alpha)
# Check that the angles are correct
assert s._theta1 == alpha
assert s._theta2 == alpha + theta
# Check invalid sector width
with pytest.raises(ValueError):
openmc.model.CylinderSector.from_theta_alpha(r1, r2, 360, alpha)
with pytest.raises(ValueError):
openmc.model.CylinderSector.from_theta_alpha(r1, r2, -1, alpha)
@pytest.mark.parametrize(
"axis, plane_tb, plane_lr, axis_idx", [
("x", "Z", "Y", 0),