Source code for g3d.mesh.geo.coord

"""mesh building block - Coord class definition"""
import os
from typing import Tuple, Any

if os.environ.get('__USE_CUDA', '0') == '1':
    import cupy as np
    from cupy import ndarray
else:
    import numpy as np
    from numpy import ndarray

from g3d.defs import G3DWorld
from g3d.defs import AngleType
from g3d.defs import G3DEntity
from g3d.defs import FunctionByPass


[docs] class Coord(G3DEntity): def __init__(self, *args: Any, **kwargs: Any) -> None: self._spacing = -1 self._ialt = AngleType.UNDEFINED self._alpha = 0. self._beta = 0. self._shape_factor = None self._angle_dim = AngleType.DEGREES self._x = 0. self._y = 0. self._z = 0. super().__init__(*args, **kwargs) def _set_default(self) -> None: super()._set_default() self._tag = 'g3d_coord' self.set_coordinates(0., 0., 0.) def _set_from_args(self, *args: Any, **kwargs: Any) -> ndarray: bps = self._get_function_evaluate_status(**kwargs) if bps is FunctionByPass.SELF: args_stat = np.ones(len(args)) else: args_stat = super()._set_from_args(*args) if bps in [FunctionByPass.EVALUATE, FunctionByPass.SELF]: if np.sum(args_stat) > 0: coord_data = [] for i in range(len(args)): if args_stat[i] == 1: arg = args[i] if type(arg) is Coord: # if caught by a super class, the child class instance of copy will be used args_stat[i] = 0 self.copy_coordinates(arg) for key, value in kwargs.items(): if key == 'copy_settings': if value: # copy settings from Coord self.copy_settings(arg) elif type(arg) in [float, np.float64, np.float32, int, np.int64, np.int32]: args_stat[i] = 0 coord_data.append(np.float64(arg)) elif type(arg) is list: args_stat[i] = 0 if self._list_is_all_floats(arg) and len(arg) > 0: self._x = arg[0] if len(arg) > 1: self._y = arg[1] if len(arg) > 2: self._z = arg[2] else: print(arg, type(arg)) if len(coord_data) > 0: # will be caught by the for-loop below in a sub call to _set_from_args self._set_from_args(coord_data, bps=FunctionByPass.SELF) return args_stat
[docs] def set_coordinates(self, xs: float, ys: float, zs: float) -> None: """ :param xs: :param ys: :param zs: """ self._x = xs self._y = ys self._z = zs
[docs] def set_from_key_value(self, key: str, value: Any) -> bool: if super().set_from_key_value(key, value): return True elif key == 'spacing': self._spacing = value return True elif key == 'ialt': self._ialt = value return True elif key == 'alpha': self._alpha = value return True elif key == 'beta': self._beta = value return True elif key == 'shape_factor': self._shape_factor = value return True elif key == 'angle_dim': self._angle_dim = value return True elif key == 'copy_settings': return True elif key == 'x': self._x = value return True elif key == 'y': self._y = value return True elif key == 'z': self._z = value return True return False
@property def x(self) -> float: """ :return: """ return self._x @x.setter def x(self, val: float) -> None: self._x = val @property def y(self) -> float: """ :return: """ return self._y @y.setter def y(self, val: float) -> None: self._y = val @property def z(self) -> float: """ :return: """ return self._z @z.setter def z(self, val: float) -> None: self._z = val @property def spacing(self) -> float: """ :return: """ return self._spacing @spacing.setter def spacing(self, val: float) -> None: self._spacing = val @property def ialt(self) -> Any: """ :return: """ return self._ialt @ialt.setter def ialt(self, val: Any) -> None: if type(val) is AngleType: self._ialt = val @property def alpha(self) -> float: """ :return: """ return self._alpha @alpha.setter def alpha(self, val: float) -> None: self._alpha = val @property def beta(self) -> float: """ :return: """ return self._beta @beta.setter def beta(self, val: float) -> None: self._beta = val @property def shape_factor(self) -> float: """ :return: """ return self._shape_factor @shape_factor.setter def shape_factor(self, val: float) -> None: self._shape_factor = val @property def angle_dim(self) -> Any: """ :return: """ return self._angle_dim @angle_dim.setter def angle_dim(self, val: Any) -> None: if type(val) is AngleType: self._angle_dim = val
[docs] def copy(self, c: 'Coord', **kwargs: Any) -> None: self.copy_coordinates(c) if len(kwargs) != 0: g3d_world = G3DWorld() for key, value in kwargs.items(): if g3d_world.display.verbose: print('%s == %s' % (key, str(value))) if key == 'copy_settings': if value: self.copy_settings(c) else: print('warning! parameter %s is not defined' % key)
[docs] def copy_coordinates(self, c: 'Coord') -> None: """ :param c: """ self._x = c.x self._y = c.y self._z = c.z
[docs] def copy_settings(self, c: 'Coord') -> None: """ :param c: """ super().copy(c) self._spacing = c.spacing self._ialt = c.ialt self._alpha = c.alpha self._beta = c.beta self._shape_factor = c.shape_factor self._angle_dim = c.angle_dim
[docs] def subtract(self, c: 'Coord') -> 'Coord': """ :param c: :return: """ self._x -= c.x self._y -= c.y self._z -= c.z return self
[docs] def add(self, c: 'Coord') -> 'Coord': """ :param c: :return: """ self._x += c.x self._y += c.y self._z += c.z return self
[docs] def multiply(self, c: 'Coord') -> 'Coord': """ :param c: :return: """ self._x *= c.x self._y *= c.y self._z *= c.z return self
[docs] def divide(self, c: 'Coord') -> 'Coord': """ :param c: :return: """ self._x /= c.x self._y /= c.y self._z /= c.z return self
[docs] def length(self) -> float: """ :return: """ return np.sqrt(self._x ** 2 + self._y ** 2 + self._z ** 2)
[docs] def scale(self, f: float) -> 'Coord': """ :param f: :return: """ self._x *= f self._y *= f self._z *= f return self
[docs] def get_xyz(self) -> Tuple[float, float, float]: """ :return: """ return self._x, self._y, self._z
[docs] def get_array(self) -> ndarray: """ :return: """ return np.array([self._x, self._y, self._z])
[docs] def print(self, **kwargs: Any) -> None: print_settings = False for key, value in kwargs.items(): if key == 'print_settings': print_settings = value super().print() print('coordinates:') print(' [x, y, z] = [%f, %f, %f]' % (self._x, self._y, self._z)) if print_settings: print('settings:') print(' cell spacing: %f' % self._spacing) print(' angle dimension: %s' % self._angle_dim.name) if self._ialt == AngleType.IALT_1 or self._ialt == AngleType.IALT_2 or self._ialt == AngleType.IALT_3: print(' ialt: %s' % self._ialt.name) alpha = self._alpha beta = self._beta if self._angle_dim == AngleType.RADIANS: alpha *= 180. / np.pi beta *= 180. / np.pi print(' alpha: %f degrees' % alpha) print(' beta: %f degrees' % beta) if self._shape_factor is not None: print(' shape factor: %f' % float(self._shape_factor))
[docs] def rotate(self, **kwargs: Any) -> None: """ :param kwargs: :return: """ alpha = 0. beta = 0. gamma = 0. angle_dim = AngleType.DEGREES if len(kwargs) != 0: g3d_world = G3DWorld() for key, value in kwargs.items(): if g3d_world.display.verbose: print('%s == %s' % (key, str(value))) if key == 'alpha': alpha = value elif key == 'beta': beta = value elif key == 'gamma': gamma = value elif key == 'angle_dim': angle_dim = value else: print('warning! parameter %s is not defined' % key) if alpha == 0. and beta == 0. and gamma == 0.: print('warning! no rotation angle specified') return if angle_dim == AngleType.DEGREES: alpha *= np.pi / 180. beta *= np.pi / 180. gamma *= np.pi / 180. eps = 1.e-6 csa = np.cos(alpha) ssa = np.sin(alpha) csb = np.cos(beta) ssb = np.sin(beta) csg = np.cos(gamma) ssg = np.sin(gamma) if np.abs(alpha) > eps: yy = self._y zz = self._z self._y = csa * yy - ssa * zz self._z = ssa * yy + csa * zz if np.abs(beta) > eps: xx = self._x zz = self._z self._z = csb * zz + ssb * xx self._x = -ssb * zz + csb * xx if np.abs(gamma) > eps: xx = self._x yy = self._y self._x = csg * xx - ssg * yy self._y = ssg * xx + csg * yy
[docs] def shift(self, **kwargs: Any) -> None: """ :param kwargs: :return: """ x_shift = 0. y_shift = 0. z_shift = 0. if len(kwargs) != 0: g3d_world = G3DWorld() for key, value in kwargs.items(): if g3d_world.display.verbose: print('%s == %s' % (key, str(value))) if key == 'x_shift': x_shift = value elif key == 'y_shift': y_shift = value elif key == 'z_shift': z_shift = value else: print('warning! parameter %s is not defined' % key) if x_shift == 0. and y_shift == 0. and z_shift == 0.: print('warning! no shift specified') return self._x += x_shift self._y += y_shift self._z += z_shift
[docs] def get_delta(self, c: 'Coord') -> Tuple[float, float, float]: """ :param c: :return: """ return c.x - self._x, c.y - self._y, c.z - self._z
[docs] def get_dist(self, c: 'Coord') -> float: """ :param c: :return: """ dx, dy, dz = self.get_delta(c) return np.sqrt(dx ** 2 + dy ** 2 + dz ** 2)
[docs] def get_angle(self, c: 'Coord', **kwargs: Any) -> Tuple[float, float]: """ :param c: :param kwargs: :return: """ # ialt=IALT_1 # alpha: angle between vector and x-axis # beta: angle between projection of vector on yz-plane and y-axis (positive towards z-axis) # # ialt=IALT_2 # alpha: angle between vector and y-axis # beta: angle between projection of vector on xz-plane and z-axis (positive towards x-axis) # # ialt=IALT_3 # alpha: angle between vector and z-axis # beta: angle between projection of vector on xy-plane and x-axis (positive towards y-axis) ialt = AngleType.IALT_1 angle_dim = AngleType.DEGREES if len(kwargs) != 0: g3d_world = G3DWorld() for key, value in kwargs.items(): if g3d_world.display.verbose: print('%s == %s' % (key, str(value))) if key == 'ialt': ialt = value elif key == 'angle_dim': angle_dim = value else: if key != 'direction': print('warning! parameter %s is not defined' % key) alpha = 0. beta = 0. dx, dy, dz = self.get_delta(c) if ialt is AngleType.IALT_1: beta = np.arctan2(dz, dy) alpha = np.arctan2(dy / np.cos(beta), dx) elif ialt is AngleType.IALT_2: beta = np.arctan2(dx, dz) alpha = np.arctan2(dz / np.cos(beta), dy) elif ialt is AngleType.IALT_3: beta = np.arctan2(dy, dx) alpha = np.arctan2(dx / np.cos(beta), dz) if angle_dim is AngleType.DEGREES: alpha *= (180. / np.pi) beta *= (180. / np.pi) return alpha, beta
[docs] def scatter_XY(self, plt: Any, m: str = 'o') -> None: """ :param plt: :param m: """ plt.scatter(self._x, self._y, marker=m)
[docs] def scatter_XZ(self, plt: Any, m: str = 'o') -> None: """ :param plt: :param m: """ plt.scatter(self._x, self._z, marker=m)
[docs] def scatter_YZ(self, plt: Any, m: str = 'o') -> None: """ :param plt: :param m: """ plt.scatter(self._y, self._z, marker=m)