Source code for openmdao.lib.datatypes.domain.zone
import copy
from openmdao.lib.datatypes.domain.flow import FlowSolution
from openmdao.lib.datatypes.domain.grid import GridCoordinates
CARTESIAN = 'Cartesian'
CYLINDRICAL = 'Cylindrical'
_COORD_SYSTEMS = (CARTESIAN, CYLINDRICAL)
[docs]class Zone(object):
""" One zone in a possibly multi-zone :class:`DomainObj`. """
def __init__(self):
self.grid_coordinates = GridCoordinates()
self.flow_solution = FlowSolution()
self.reference_state = None
self._coordinate_system = CARTESIAN
self.right_handed = True
self.symmetry = None
self.symmetry_axis = None
self.symmetry_instances = 1
@property
[docs] def shape(self):
""" Coordinate index limits, not including 'ghost/rind' planes. """
return self.grid_coordinates.shape
@property
[docs] def extent(self):
""" Coordinate ranges, not including 'ghost/rind' planes. """
return self.grid_coordinates.extent
def _get_coord_sys(self):
return self._coordinate_system
def _set_coord_sys(self, sys):
if sys in _COORD_SYSTEMS:
self._coordinate_system = sys
else:
raise ValueError('invalid coordinate system %r' % sys)
coordinate_system = property(_get_coord_sys, _set_coord_sys,
doc='Coordinate system in use.')
[docs] def copy(self):
""" Returns a deep copy of self. """
return copy.deepcopy(self)
[docs] def is_equivalent(self, other, logger, tolerance=0.):
"""
Test if self and `other` are equivalent.
other: :class:`Zone`
Zone to check against.
logger: :class:`Logger` or None
Used to log debug messages that will indicate what if anything is
not equivalent.
tolerance: float
The maximum relative difference in array values to be considered
equivalent.
"""
if not isinstance(other, Zone):
logger.debug('other is not a Zone object.')
return False
if self.coordinate_system != other.coordinate_system:
logger.debug('coordinate_systems are not equal.')
return False
if self.right_handed != other.right_handed:
logger.debug('handedness is not equal.')
return False
if self.symmetry != other.symmetry:
logger.debug('symmetry is not equal.')
return False
if self.symmetry_axis != other.symmetry_axis:
logger.debug('symmetry_axis is not equal.')
return False
if self.symmetry_instances != other.symmetry_instances:
logger.debug('symmetry_instances is not equal.')
return False
if not self.grid_coordinates.is_equivalent(other.grid_coordinates,
logger, tolerance):
return False
if not self.flow_solution.is_equivalent(other.flow_solution, logger,
tolerance):
return False
return True
[docs] def extend(self, axis, delta, grid_points, flow_points, normal=None):
"""
Construct a new :class:`Zone` by linearly extending the grid and
replicating the flow. Symmetry data is copied.
axis: 'i', 'j', or 'k'
Index axis to extend.
delta: float.
Fractional amount to move for each point. Multiplies the 'edge'
delta in the `axis` direction or the appropriate component of
`normal`. A negative value adds points before the current
zero-index of `axis`.
grid_points: int >= 0
Number of points to add in `axis` dimension.
flow_points: int >= 0
Number of points to add in `axis` dimension.
normal: float[]
For cases where only a single point exists in the `axis` direction,
this specifies the direction to move. If not specified, an
axis-aligned direction is selected based on minimum grid extent.
"""
zone = Zone()
if grid_points > 0:
zone.grid_coordinates = \
self.grid_coordinates.extend(axis, delta, grid_points, normal)
else:
zone.grid_coordinates = self.grid_coordinates.copy()
if flow_points > 0:
zone.flow_solution = \
self.flow_solution.extend(axis, delta, flow_points)
else:
zone.flow_solution = self.flow_solution.copy()
if self.reference_state is not None:
zone.reference_state = self.reference_state.copy()
zone.coordinate_system = self.coordinate_system
zone.right_handed = self.right_handed
zone.symmetry = self.symmetry
zone.symmetry_axis = self.symmetry_axis
zone.symmetry_instances = self.symmetry_instances
return zone
[docs] def make_cartesian(self, axis='z'):
"""
Convert to Cartesian coordinate system.
axis: string
Specifies which is the cylinder axis ('z' or 'x').
"""
if self.coordinate_system != CARTESIAN:
self.flow_solution.make_cartesian(self.grid_coordinates, axis)
self.grid_coordinates.make_cartesian(axis)
self.coordinate_system = CARTESIAN
[docs] def make_cylindrical(self, axis='z'):
"""
Convert to cylindrical coordinate system.
axis: string
Specifies which is the cylinder axis ('z' or 'x').
"""
if self.coordinate_system != CYLINDRICAL:
self.grid_coordinates.make_cylindrical(axis)
self.flow_solution.make_cylindrical(self.grid_coordinates, axis)
self.coordinate_system = CYLINDRICAL
[docs] def make_left_handed(self):
""" Convert to left-handed coordinate system. """
if self.right_handed:
self.grid_coordinates.flip_z()
self.flow_solution.flip_z()
self.right_handed = False
[docs] def make_right_handed(self):
""" Convert to right-handed coordinate system. """
if not self.right_handed:
self.grid_coordinates.flip_z()
self.flow_solution.flip_z()
self.right_handed = True
[docs] def translate(self, delta_x, delta_y, delta_z):
"""
Translate coordinates.
delta_x, delta_y, delta_z: float
Amount of translation along the corresponding axis.
"""
if self.coordinate_system == CARTESIAN:
self.grid_coordinates.translate(delta_x, delta_y, delta_z)
else:
raise RuntimeError('Zone not in cartesian coordinates')
[docs] def rotate_about_x(self, deg):
"""
Rotate about the X axis.
deg: float (degrees)
Amount of rotation.
"""
if self.coordinate_system == CARTESIAN:
self.grid_coordinates.rotate_about_x(deg)
self.flow_solution.rotate_about_x(deg)
else:
raise RuntimeError('Zone not in cartesian coordinates')
[docs] def rotate_about_y(self, deg):
"""
Rotate about the Y axis.
deg: float (degrees)
Amount of rotation.
"""
if self.coordinate_system == CARTESIAN:
self.grid_coordinates.rotate_about_y(deg)
self.flow_solution.rotate_about_y(deg)
else:
raise RuntimeError('Zone not in cartesian coordinates')
[docs] def rotate_about_z(self, deg):
"""
Rotate about the Z axis.
deg: float (degrees)
Amount of rotation.
"""
if self.coordinate_system == CARTESIAN:
self.grid_coordinates.rotate_about_z(deg)
self.flow_solution.rotate_about_z(deg)
else:
raise RuntimeError('Zone not in cartesian coordinates')
[docs] def demote(self):
""" Demote from N-dimensional to N-1 dimensional index space. """
self.grid_coordinates.demote()
self.flow_solution.demote()