Source code for openmc.model.surface_composite

from abc import ABC, abstractmethod
from copy import copy

import openmc
from openmc.checkvalue import check_greater_than, check_value


class CompositeSurface(ABC):
    """Multiple primitive surfaces combined into a composite surface"""

    def translate(self, vector, inplace=False):
        surf = self if inplace else copy(self)
        for name in self._surface_names:
            s = getattr(surf, name)
            setattr(surf, name, s.translate(vector, inplace))
        return surf

    def rotate(self, rotation, pivot=(0., 0., 0.), order='xyz', inplace=False):
        surf = copy(self)
        for name in self._surface_names:
            s = getattr(surf, name)
            setattr(surf, name, s.rotate(rotation, pivot, order, inplace))
        return surf

    @property
    def boundary_type(self):
        return getattr(self, self._surface_names[0]).boundary_type

    @boundary_type.setter
    def boundary_type(self, boundary_type):
        # Set boundary type on underlying surfaces, but not for ambiguity plane
        # on one-sided cones
        for name in self._surface_names:
            if name != 'plane':
                getattr(self, name).boundary_type = boundary_type

    def __repr__(self):
        return "<{} at 0x{:x}>".format(type(self).__name__, id(self))

    @property
    @abstractmethod
    def _surface_names(self):
        """Iterable of attribute names corresponding to underlying surfaces."""

    @abstractmethod
    def __pos__(self):
        """Return the positive half-space of the composite surface."""

    @abstractmethod
    def __neg__(self):
        """Return the negative half-space of the composite surface."""


[docs]class RightCircularCylinder(CompositeSurface): """Right circular cylinder composite surface A right circular cylinder is composed of a cylinder and two planar surface perpendicular to the axis of the cylinder. This class acts as a proper surface, meaning that unary `+` and `-` operators applied to it will produce a half-space. The negative side is defined to be the region inside of the right circular cylinder. .. versionadded:: 0.12 Parameters ---------- center_base : iterable of float Cartesian coordinate of the center of the base of the cylinder height : float Height of the cylinder radius : float Radius of the cylinder axis : {'x', 'y', 'z'} Axis of the cylinder **kwargs Keyword arguments passed to underlying cylinder and plane classes Attributes ---------- cyl : openmc.Cylinder Underlying cylinder surface bottom : openmc.Plane Bottom planar surface of the cylinder top : openmc.Plane Top planar surface of the cylinder """ _surface_names = ('cyl', 'bottom', 'top') def __init__(self, center_base, height, radius, axis='z', **kwargs): cx, cy, cz = center_base check_greater_than('cylinder height', height, 0.0) check_greater_than('cylinder radius', radius, 0.0) check_value('cylinder axis', axis, ('x', 'y', 'z')) if axis == 'x': self.cyl = openmc.XCylinder(y0=cy, z0=cz, r=radius, **kwargs) self.bottom = openmc.XPlane(x0=cx, **kwargs) self.top = openmc.XPlane(x0=cx + height, **kwargs) elif axis == 'y': self.cyl = openmc.YCylinder(x0=cx, z0=cz, r=radius, **kwargs) self.bottom = openmc.YPlane(y0=cy, **kwargs) self.top = openmc.YPlane(y0=cy + height, **kwargs) elif axis == 'z': self.cyl = openmc.ZCylinder(x0=cx, y0=cy, r=radius, **kwargs) self.bottom = openmc.ZPlane(z0=cz, **kwargs) self.top = openmc.ZPlane(z0=cz + height, **kwargs) def __neg__(self): return -self.cyl & +self.bottom & -self.top def __pos__(self): return +self.cyl | -self.bottom | +self.top
[docs]class RectangularParallelepiped(CompositeSurface): """Rectangular parallelpiped composite surface A rectangular parallelpiped is composed of six planar surfaces. This class acts as a proper surface, meaning that unary `+` and `-` operators applied to it will produce a half-space. The negative side is defined to be the region inside of the rectangular parallelpiped. .. versionadded:: 0.12 Parameters ---------- xmin, xmax : float Minimum and maximum x coordinates of the parallelepiped ymin, ymax : float Minimum and maximum y coordinates of the parallelepiped zmin, zmax : float Minimum and maximum z coordinates of the parallelepiped **kwargs Keyword arguments passed to underlying plane classes Attributes ---------- xmin, xmax : openmc.XPlane Sides of the parallelepiped ymin, ymax : openmc.YPlane Sides of the parallelepiped zmin, zmax : openmc.ZPlane Sides of the parallelepiped """ _surface_names = ('xmin', 'xmax', 'ymin', 'ymax', 'zmin', 'zmax') def __init__(self, xmin, xmax, ymin, ymax, zmin, zmax, **kwargs): if xmin >= xmax: raise ValueError('xmin must be less than xmax') if ymin >= ymax: raise ValueError('ymin must be less than ymax') if zmin >= zmax: raise ValueError('zmin must be less than zmax') self.xmin = openmc.XPlane(x0=xmin, **kwargs) self.xmax = openmc.XPlane(x0=xmax, **kwargs) self.ymin = openmc.YPlane(y0=ymin, **kwargs) self.ymax = openmc.YPlane(y0=ymax, **kwargs) self.zmin = openmc.ZPlane(z0=zmin, **kwargs) self.zmax = openmc.ZPlane(z0=zmax, **kwargs) def __neg__(self): return +self.xmin & -self.xmax & +self.ymin & -self.ymax & +self.zmin & -self.zmax def __pos__(self): return -self.xmin | +self.xmax | -self.ymin | +self.ymax | -self.zmin | +self.zmax
[docs]class XConeOneSided(CompositeSurface): """One-sided cone parallel the x-axis A one-sided cone is composed of a normal cone surface and an "ambiguity" surface that eliminates the ambiguity as to which region of space is included. This class acts as a proper surface, meaning that unary `+` and `-` operators applied to it will produce a half-space. The negative side is defined to be the region inside of the cone. .. versionadded:: 0.12 Parameters ---------- x0 : float, optional x-coordinate of the apex. Defaults to 0. y0 : float, optional y-coordinate of the apex. Defaults to 0. z0 : float, optional z-coordinate of the apex. Defaults to 0. r2 : float, optional Parameter related to the aperature. Defaults to 1. up : bool Whether to select the side of the cone that extends to infinity in the positive direction of the coordinate axis (the positive half-space of the ambiguity plane) **kwargs Keyword arguments passed to underlying plane classes Attributes ---------- cone : openmc.XCone Regular two-sided cone plane : openmc.XPlane Ambiguity surface up : bool Whether to select the side of the cone that extends to infinity in the positive direction of the coordinate axis (the positive half-space of the ambiguity plane) """ _surface_names = ('cone', 'plane') def __init__(self, x0=0., y0=0., z0=0., r2=1., up=True, **kwargs): check_greater_than('cone R^2', r2, 0.0) self.cone = openmc.XCone(x0, y0, z0, r2, **kwargs) self.plane = openmc.XPlane(x0) self.up = up def __neg__(self): return -self.cone & (+self.plane if self.up else -self.plane) def __pos__(self): if self.up: return (+self.cone & +self.plane) | -self.plane else: return (+self.cone & -self.plane) | +self.plane
[docs]class YConeOneSided(CompositeSurface): """One-sided cone parallel the y-axis A one-sided cone is composed of a normal cone surface and an "ambiguity" surface that eliminates the ambiguity as to which region of space is included. This class acts as a proper surface, meaning that unary `+` and `-` operators applied to it will produce a half-space. The negative side is defined to be the region inside of the cone. .. versionadded:: 0.12 Parameters ---------- x0 : float, optional x-coordinate of the apex. Defaults to 0. y0 : float, optional y-coordinate of the apex. Defaults to 0. z0 : float, optional z-coordinate of the apex. Defaults to 0. r2 : float, optional Parameter related to the aperature. Defaults to 1. up : bool Whether to select the side of the cone that extends to infinity in the positive direction of the coordinate axis (the positive half-space of the ambiguity plane) **kwargs Keyword arguments passed to underlying plane classes Attributes ---------- cone : openmc.YCone Regular two-sided cone plane : openmc.YPlane Ambiguity surface up : bool Whether to select the side of the cone that extends to infinity in the positive direction of the coordinate axis (the positive half-space of the ambiguity plane) """ _surface_names = ('cone', 'plane') def __init__(self, x0=0., y0=0., z0=0., r2=1., up=True, **kwargs): check_greater_than('cone R^2', r2, 0.0) self.cone = openmc.YCone(x0, y0, z0, r2, **kwargs) self.plane = openmc.YPlane(y0) self.up = up __neg__ = XConeOneSided.__neg__ __pos__ = XConeOneSided.__pos__
[docs]class ZConeOneSided(CompositeSurface): """One-sided cone parallel the z-axis A one-sided cone is composed of a normal cone surface and an "ambiguity" surface that eliminates the ambiguity as to which region of space is included. This class acts as a proper surface, meaning that unary `+` and `-` operators applied to it will produce a half-space. The negative side is defined to be the region inside of the cone. .. versionadded:: 0.12 Parameters ---------- x0 : float, optional x-coordinate of the apex. Defaults to 0. y0 : float, optional y-coordinate of the apex. Defaults to 0. z0 : float, optional z-coordinate of the apex. Defaults to 0. r2 : float, optional Parameter related to the aperature. Defaults to 1. up : bool Whether to select the side of the cone that extends to infinity in the positive direction of the coordinate axis (the positive half-space of the ambiguity plane) **kwargs Keyword arguments passed to underlying plane classes Attributes ---------- cone : openmc.ZCone Regular two-sided cone plane : openmc.ZPlane Ambiguity surface up : bool Whether to select the side of the cone that extends to infinity in the positive direction of the coordinate axis (the positive half-space of the ambiguity plane) """ _surface_names = ('cone', 'plane') def __init__(self, x0=0., y0=0., z0=0., r2=1., up=True, **kwargs): check_greater_than('cone R^2', r2, 0.0) self.cone = openmc.ZCone(x0, y0, z0, r2, **kwargs) self.plane = openmc.ZPlane(z0) self.up = up __neg__ = XConeOneSided.__neg__ __pos__ = XConeOneSided.__pos__