Implement SurfaceCoefficient descriptor to simplify property generation

This commit is contained in:
Paul Romano 2020-03-05 19:25:54 -06:00
parent 3fc25be950
commit 7559ae9a80

View file

@ -27,6 +27,29 @@ will not accept positional parameters for superclass arguments.\
"""
class SurfaceCoefficient:
"""Descriptor class for surface coefficients.
Parameters
-----------
symbol : str
Name of the coefficient
"""
def __init__(self, symbol):
self.symbol = symbol
def __get__(self, instance, owner=None):
if instance is None:
return self
else:
return instance._coefficients[self.symbol]
def __set__(self, instance, value):
check_type('{} coefficient'.format(self.symbol), value, Real)
instance._coefficients[self.symbol] = value
def _future_kwargs_warning_helper(cls, *args, **kwargs):
# Warn if Surface parameters are passed by position, not by keyword
argsdict = dict(zip(('boundary_type', 'name', 'surface_id'), args))
@ -484,7 +507,7 @@ class PlaneMixin(metaclass=ABCMeta):
if np.any(np.isclose(np.abs(nhat), 1., rtol=0., atol=self._atol)):
sign = nhat.sum()
a, b, c, d = self._get_base_coeffs()
vals = [d/val if not np.isclose(val, 0., rtol=0., atol=self._atol)
vals = [d/val if not np.isclose(val, 0., rtol=0., atol=self._atol)
else np.nan for val in (a, b, c)]
if side == '-':
if sign > 0:
@ -674,41 +697,10 @@ class Plane(PlaneMixin, Surface):
return True
return NotImplemented
@property
def a(self):
return self.coefficients['a']
@property
def b(self):
return self.coefficients['b']
@property
def c(self):
return self.coefficients['c']
@property
def d(self):
return self.coefficients['d']
@a.setter
def a(self, a):
check_type('A coefficient', a, Real)
self._coefficients['a'] = a
@b.setter
def b(self, b):
check_type('B coefficient', b, Real)
self._coefficients['b'] = b
@c.setter
def c(self, c):
check_type('C coefficient', c, Real)
self._coefficients['c'] = c
@d.setter
def d(self, d):
check_type('D coefficient', d, Real)
self._coefficients['d'] = d
a = SurfaceCoefficient('a')
b = SurfaceCoefficient('b')
c = SurfaceCoefficient('c')
d = SurfaceCoefficient('d')
@classmethod
def from_points(cls, p1, p2, p3, **kwargs):
@ -792,9 +784,7 @@ class XPlane(PlaneMixin, Surface):
super().__init__(**kwargs)
self.x0 = x0
@property
def x0(self):
return self.coefficients['x0']
x0 = SurfaceCoefficient('x0')
@property
def a(self):
@ -812,11 +802,6 @@ class XPlane(PlaneMixin, Surface):
def d(self):
return self.x0
@x0.setter
def x0(self, x0):
check_type('x0 coefficient', x0, Real)
self._coefficients['x0'] = x0
def evaluate(self, point):
return point[0] - self.x0
@ -870,9 +855,7 @@ class YPlane(PlaneMixin, Surface):
super().__init__(**kwargs)
self.y0 = y0
@property
def y0(self):
return self.coefficients['y0']
y0 = SurfaceCoefficient('y0')
@property
def a(self):
@ -890,11 +873,6 @@ class YPlane(PlaneMixin, Surface):
def d(self):
return self.y0
@y0.setter
def y0(self, y0):
check_type('y0 coefficient', y0, Real)
self._coefficients['y0'] = y0
def evaluate(self, point):
return point[1] - self.y0
@ -948,9 +926,7 @@ class ZPlane(PlaneMixin, Surface):
super().__init__(**kwargs)
self.z0 = z0
@property
def z0(self):
return self.coefficients['z0']
z0 = SurfaceCoefficient('z0')
@property
def a(self):
@ -968,11 +944,6 @@ class ZPlane(PlaneMixin, Surface):
def d(self):
return self.z0
@z0.setter
def z0(self, z0):
check_type('z0 coefficient', z0, Real)
self._coefficients['z0'] = z0
def evaluate(self, point):
return point[2] - self.z0
@ -1095,7 +1066,7 @@ class QuadricMixin(metaclass=ABCMeta):
return surf
def rotate(self, rotation, pivot=(0., 0., 0.), order='xyz', inplace=False):
# Get pivot and rotation matrix
# Get pivot and rotation matrix
pivot = np.asarray(pivot)
rotation = np.asarray(rotation, dtype=float)
@ -1225,68 +1196,13 @@ class Cylinder(QuadricMixin, Surface):
return True
return NotImplemented
@property
def x0(self):
return self.coefficients['x0']
@property
def y0(self):
return self.coefficients['y0']
@property
def z0(self):
return self.coefficients['z0']
@property
def r(self):
return self.coefficients['r']
@property
def dx(self):
return self.coefficients['dx']
@property
def dy(self):
return self.coefficients['dy']
@property
def dz(self):
return self.coefficients['dz']
@x0.setter
def x0(self, x0):
check_type('x0 coefficient', x0, Real)
self._coefficients['x0'] = x0
@y0.setter
def y0(self, y0):
check_type('y0 coefficient', y0, Real)
self._coefficients['y0'] = y0
@z0.setter
def z0(self, z0):
check_type('z0 coefficient', z0, Real)
self._coefficients['z0'] = z0
@r.setter
def r(self, r):
check_type('r coefficient', r, Real)
self._coefficients['r'] = r
@dx.setter
def dx(self, dx):
check_type('dx coefficient', dx, Real)
self._coefficients['dx'] = dx
@dy.setter
def dy(self, dy):
check_type('dy coefficient', dy, Real)
self._coefficients['dy'] = dy
@dz.setter
def dz(self, dz):
check_type('dz coefficient', dz, Real)
self._coefficients['dz'] = dz
x0 = SurfaceCoefficient('x0')
y0 = SurfaceCoefficient('y0')
z0 = SurfaceCoefficient('z0')
r = SurfaceCoefficient('r')
dx = SurfaceCoefficient('dx')
dy = SurfaceCoefficient('dy')
dz = SurfaceCoefficient('dz')
def bounding_box(self, side):
if side == '-':
@ -1305,7 +1221,7 @@ class Cylinder(QuadricMixin, Surface):
# Get x, y, z coordinates of two points
x1, y1, z1 = self._origin
x2, y2, z2 = self._origin + self._axis
r = self.r
r = self.r
# Define intermediate terms
dx = x2 - x1
@ -1375,7 +1291,7 @@ class Cylinder(QuadricMixin, Surface):
with catch_warnings():
simplefilter('ignore', IDWarning)
kwargs = {'boundary_type': self.boundary_type, 'name': self.name,
'surface_id': self.id}
'surface_id': self.id}
quad_rep = Quadric(*self._get_base_coeffs(), **kwargs)
return quad_rep.to_xml_element()
@ -1440,17 +1356,9 @@ class XCylinder(QuadricMixin, Surface):
for key, val in zip(self._coeff_keys, (y0, z0, r)):
setattr(self, key, val)
@property
def y0(self):
return self.coefficients['y0']
@property
def z0(self):
return self.coefficients['z0']
@property
def r(self):
return self.coefficients['r']
y0 = SurfaceCoefficient('y0')
z0 = SurfaceCoefficient('z0')
r = SurfaceCoefficient('r')
@property
def x0(self):
@ -1468,21 +1376,6 @@ class XCylinder(QuadricMixin, Surface):
def dz(self):
return 0.
@y0.setter
def y0(self, y0):
check_type('y0 coefficient', y0, Real)
self._coefficients['y0'] = y0
@z0.setter
def z0(self, z0):
check_type('z0 coefficient', z0, Real)
self._coefficients['z0'] = z0
@r.setter
def r(self, r):
check_type('r coefficient', r, Real)
self._coefficients['r'] = r
def _get_base_coeffs(self):
y0, z0, r = self.y0, self.z0, self.r
@ -1566,17 +1459,9 @@ class YCylinder(QuadricMixin, Surface):
for key, val in zip(self._coeff_keys, (x0, z0, r)):
setattr(self, key, val)
@property
def x0(self):
return self.coefficients['x0']
@property
def z0(self):
return self.coefficients['z0']
@property
def r(self):
return self.coefficients['r']
x0 = SurfaceCoefficient('x0')
z0 = SurfaceCoefficient('z0')
r = SurfaceCoefficient('r')
@property
def y0(self):
@ -1594,21 +1479,6 @@ class YCylinder(QuadricMixin, Surface):
def dz(self):
return 0.
@x0.setter
def x0(self, x0):
check_type('x0 coefficient', x0, Real)
self._coefficients['x0'] = x0
@z0.setter
def z0(self, z0):
check_type('z0 coefficient', z0, Real)
self._coefficients['z0'] = z0
@r.setter
def r(self, r):
check_type('r coefficient', r, Real)
self._coefficients['r'] = r
def _get_base_coeffs(self):
x0, z0, r = self.x0, self.z0, self.r
@ -1692,17 +1562,9 @@ class ZCylinder(QuadricMixin, Surface):
for key, val in zip(self._coeff_keys, (x0, y0, r)):
setattr(self, key, val)
@property
def x0(self):
return self.coefficients['x0']
@property
def y0(self):
return self.coefficients['y0']
@property
def r(self):
return self.coefficients['r']
x0 = SurfaceCoefficient('x0')
y0 = SurfaceCoefficient('y0')
r = SurfaceCoefficient('r')
@property
def z0(self):
@ -1720,21 +1582,6 @@ class ZCylinder(QuadricMixin, Surface):
def dz(self):
return 1.
@x0.setter
def x0(self, x0):
check_type('x0 coefficient', x0, Real)
self._coefficients['x0'] = x0
@y0.setter
def y0(self, y0):
check_type('y0 coefficient', y0, Real)
self._coefficients['y0'] = y0
@r.setter
def r(self, r):
check_type('r coefficient', r, Real)
self._coefficients['r'] = r
def _get_base_coeffs(self):
x0, y0, r = self.x0, self.y0, self.r
@ -1820,41 +1667,10 @@ class Sphere(QuadricMixin, Surface):
for key, val in zip(self._coeff_keys, (x0, y0, z0, r)):
setattr(self, key, val)
@property
def x0(self):
return self.coefficients['x0']
@property
def y0(self):
return self.coefficients['y0']
@property
def z0(self):
return self.coefficients['z0']
@property
def r(self):
return self.coefficients['r']
@x0.setter
def x0(self, x0):
check_type('x0 coefficient', x0, Real)
self._coefficients['x0'] = x0
@y0.setter
def y0(self, y0):
check_type('y0 coefficient', y0, Real)
self._coefficients['y0'] = y0
@z0.setter
def z0(self, z0):
check_type('z0 coefficient', z0, Real)
self._coefficients['z0'] = z0
@r.setter
def r(self, r):
check_type('r coefficient', r, Real)
self._coefficients['r'] = r
x0 = SurfaceCoefficient('x0')
y0 = SurfaceCoefficient('y0')
z0 = SurfaceCoefficient('z0')
r = SurfaceCoefficient('r')
def _get_base_coeffs(self):
x0, y0, z0, r = self.x0, self.y0, self.z0, self.r
@ -1966,68 +1782,13 @@ class Cone(QuadricMixin, Surface):
return True
return NotImplemented
@property
def x0(self):
return self.coefficients['x0']
@property
def y0(self):
return self.coefficients['y0']
@property
def z0(self):
return self.coefficients['z0']
@property
def r2(self):
return self.coefficients['r2']
@property
def dx(self):
return self.coefficients['dx']
@property
def dy(self):
return self.coefficients['dy']
@property
def dz(self):
return self.coefficients['dz']
@x0.setter
def x0(self, x0):
check_type('x0 coefficient', x0, Real)
self._coefficients['x0'] = x0
@y0.setter
def y0(self, y0):
check_type('y0 coefficient', y0, Real)
self._coefficients['y0'] = y0
@z0.setter
def z0(self, z0):
check_type('z0 coefficient', z0, Real)
self._coefficients['z0'] = z0
@r2.setter
def r2(self, r2):
check_type('r^2 coefficient', r2, Real)
self._coefficients['r2'] = r2
@dx.setter
def dx(self, dx):
check_type('dx coefficient', dx, Real)
self._coefficients['dx'] = dx
@dy.setter
def dy(self, dy):
check_type('dy coefficient', dy, Real)
self._coefficients['dy'] = dy
@dz.setter
def dz(self, dz):
check_type('dz coefficient', dz, Real)
self._coefficients['dz'] = dz
x0 = SurfaceCoefficient('x0')
y0 = SurfaceCoefficient('y0')
z0 = SurfaceCoefficient('z0')
r2 = SurfaceCoefficient('r2')
dx = SurfaceCoefficient('dx')
dy = SurfaceCoefficient('dy')
dz = SurfaceCoefficient('dz')
def _get_base_coeffs(self):
# The equation for a general cone with vertex at point p = (x0, y0, z0)
@ -2074,7 +1835,7 @@ class Cone(QuadricMixin, Surface):
with catch_warnings():
simplefilter('ignore', IDWarning)
kwargs = {'boundary_type': self.boundary_type, 'name': self.name,
'surface_id': self.id}
'surface_id': self.id}
quad_rep = Quadric(*self._get_base_coeffs(), **kwargs)
return quad_rep.to_xml_element()
@ -2142,21 +1903,10 @@ class XCone(QuadricMixin, Surface):
for key, val in zip(self._coeff_keys, (x0, y0, z0, r2)):
setattr(self, key, val)
@property
def x0(self):
return self.coefficients['x0']
@property
def y0(self):
return self.coefficients['y0']
@property
def z0(self):
return self.coefficients['z0']
@property
def r2(self):
return self.coefficients['r2']
x0 = SurfaceCoefficient('x0')
y0 = SurfaceCoefficient('y0')
z0 = SurfaceCoefficient('z0')
r2 = SurfaceCoefficient('r2')
@property
def dx(self):
@ -2170,26 +1920,6 @@ class XCone(QuadricMixin, Surface):
def dz(self):
return 0.
@x0.setter
def x0(self, x0):
check_type('x0 coefficient', x0, Real)
self._coefficients['x0'] = x0
@y0.setter
def y0(self, y0):
check_type('y0 coefficient', y0, Real)
self._coefficients['y0'] = y0
@z0.setter
def z0(self, z0):
check_type('z0 coefficient', z0, Real)
self._coefficients['z0'] = z0
@r2.setter
def r2(self, r2):
check_type('r^2 coefficient', r2, Real)
self._coefficients['r2'] = r2
def _get_base_coeffs(self):
x0, y0, z0, r2 = self.x0, self.y0, self.z0, self.r2
@ -2271,21 +2001,10 @@ class YCone(QuadricMixin, Surface):
for key, val in zip(self._coeff_keys, (x0, y0, z0, r2)):
setattr(self, key, val)
@property
def x0(self):
return self.coefficients['x0']
@property
def y0(self):
return self.coefficients['y0']
@property
def z0(self):
return self.coefficients['z0']
@property
def r2(self):
return self.coefficients['r2']
x0 = SurfaceCoefficient('x0')
y0 = SurfaceCoefficient('y0')
z0 = SurfaceCoefficient('z0')
r2 = SurfaceCoefficient('r2')
@property
def dx(self):
@ -2299,26 +2018,6 @@ class YCone(QuadricMixin, Surface):
def dz(self):
return 0.
@x0.setter
def x0(self, x0):
check_type('x0 coefficient', x0, Real)
self._coefficients['x0'] = x0
@y0.setter
def y0(self, y0):
check_type('y0 coefficient', y0, Real)
self._coefficients['y0'] = y0
@z0.setter
def z0(self, z0):
check_type('z0 coefficient', z0, Real)
self._coefficients['z0'] = z0
@r2.setter
def r2(self, r2):
check_type('r^2 coefficient', r2, Real)
self._coefficients['r2'] = r2
def _get_base_coeffs(self):
x0, y0, z0, r2 = self.x0, self.y0, self.z0, self.r2
@ -2400,21 +2099,10 @@ class ZCone(QuadricMixin, Surface):
for key, val in zip(self._coeff_keys, (x0, y0, z0, r2)):
setattr(self, key, val)
@property
def x0(self):
return self.coefficients['x0']
@property
def y0(self):
return self.coefficients['y0']
@property
def z0(self):
return self.coefficients['z0']
@property
def r2(self):
return self.coefficients['r2']
x0 = SurfaceCoefficient('x0')
y0 = SurfaceCoefficient('y0')
z0 = SurfaceCoefficient('z0')
r2 = SurfaceCoefficient('r2')
@property
def dx(self):
@ -2428,26 +2116,6 @@ class ZCone(QuadricMixin, Surface):
def dz(self):
return 1.
@x0.setter
def x0(self, x0):
check_type('x0 coefficient', x0, Real)
self._coefficients['x0'] = x0
@y0.setter
def y0(self, y0):
check_type('y0 coefficient', y0, Real)
self._coefficients['y0'] = y0
@z0.setter
def z0(self, z0):
check_type('z0 coefficient', z0, Real)
self._coefficients['z0'] = z0
@r2.setter
def r2(self, r2):
check_type('r^2 coefficient', r2, Real)
self._coefficients['r2'] = r2
def _get_base_coeffs(self):
x0, y0, z0, r2 = self.x0, self.y0, self.z0, self.r2
@ -2513,95 +2181,16 @@ class Quadric(QuadricMixin, Surface):
for key, val in zip(self._coeff_keys, (a, b, c, d, e, f, g, h, j, k)):
setattr(self, key, val)
@property
def a(self):
return self.coefficients['a']
@property
def b(self):
return self.coefficients['b']
@property
def c(self):
return self.coefficients['c']
@property
def d(self):
return self.coefficients['d']
@property
def e(self):
return self.coefficients['e']
@property
def f(self):
return self.coefficients['f']
@property
def g(self):
return self.coefficients['g']
@property
def h(self):
return self.coefficients['h']
@property
def j(self):
return self.coefficients['j']
@property
def k(self):
return self.coefficients['k']
@a.setter
def a(self, a):
check_type('a coefficient', a, Real)
self._coefficients['a'] = a
@b.setter
def b(self, b):
check_type('b coefficient', b, Real)
self._coefficients['b'] = b
@c.setter
def c(self, c):
check_type('c coefficient', c, Real)
self._coefficients['c'] = c
@d.setter
def d(self, d):
check_type('d coefficient', d, Real)
self._coefficients['d'] = d
@e.setter
def e(self, e):
check_type('e coefficient', e, Real)
self._coefficients['e'] = e
@f.setter
def f(self, f):
check_type('f coefficient', f, Real)
self._coefficients['f'] = f
@g.setter
def g(self, g):
check_type('g coefficient', g, Real)
self._coefficients['g'] = g
@h.setter
def h(self, h):
check_type('h coefficient', h, Real)
self._coefficients['h'] = h
@j.setter
def j(self, j):
check_type('j coefficient', j, Real)
self._coefficients['j'] = j
@k.setter
def k(self, k):
check_type('k coefficient', k, Real)
self._coefficients['k'] = k
a = SurfaceCoefficient('a')
b = SurfaceCoefficient('b')
c = SurfaceCoefficient('c')
d = SurfaceCoefficient('d')
e = SurfaceCoefficient('e')
f = SurfaceCoefficient('f')
g = SurfaceCoefficient('g')
h = SurfaceCoefficient('h')
j = SurfaceCoefficient('j')
k = SurfaceCoefficient('k')
def _get_base_coeffs(self):
return tuple(getattr(self, c) for c in self._coeff_keys)
@ -2734,7 +2323,7 @@ class Halfspace(Region):
Parameters
----------
redundant_surfaces : dict
Dictionary mapping redundant surface IDs to surface IDs for the
Dictionary mapping redundant surface IDs to surface IDs for the
:class:`openmc.Surface` instances that should replace them.
"""