Source code for g3d.flow.placeholders.vgrad

"""Velocity gradients - flow field data placeholder (VGradField class definition)"""
from typing import Any, Union, Tuple

import os

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 GradientMode

from g3d.flow.placeholders import FlowDataPlaceHolder
from g3d.flow.vars import VGrad
from g3d.flow.placeholders import FMP


[docs] class VGradField(FlowDataPlaceHolder): """Definition of class VGradField, extends class FlowDataPlaceHolder""" def __init__(self, *args: Any, **kwargs: Any) -> None: self.__s_vel = np.zeros(0) self.__u_face = np.zeros(0) self.__v_face = np.zeros(0) self.__w_face = np.zeros(0) super().__init__(*args, **kwargs) @property def dudx(self) -> ndarray: """Velocity gradient component Returns ------- ndarray dudx array """ return self._dudx @property def dudy(self) -> ndarray: """Velocity gradient component Returns ------- ndarray dudy array """ return self._dudy @property def dudz(self) -> ndarray: """Velocity gradient component Returns ------- ndarray dudz array """ return self._dudz @property def dvdx(self) -> ndarray: """Velocity gradient component Returns ------- ndarray dvdx array """ return self._dvdx @property def dvdy(self) -> ndarray: """Velocity gradient component Returns ------- ndarray dvdy array """ return self._dvdy @property def dvdz(self) -> ndarray: """Velocity gradient component Returns ------- ndarray dvdz array """ return self._dvdz @property def dwdx(self) -> ndarray: """Velocity gradient component Returns ------- ndarray dwdx array """ return self._dwdx @property def dwdy(self) -> ndarray: """Velocity gradient component Returns ------- ndarray dwdy array """ return self._dwdy @property def dwdz(self) -> ndarray: """Velocity gradient component Returns ------- ndarray dwdz array """ return self._dwdz def _set_default(self) -> None: super()._set_default() self._tag = 'velocity gradients' def _define_variables(self) -> None: super()._define_variables() self._variables['dudx'] = {} self._variables['dudx']['longname'] = 'dudx' self._variables['dudx']['dimension'] = '1/s' self._variables['dudy'] = {} self._variables['dudy']['longname'] = 'dudy' self._variables['dudy']['dimension'] = '1/s' self._variables['dudz'] = {} self._variables['dudz']['longname'] = 'dudz' self._variables['dudz']['dimension'] = '1/s' self._variables['dvdx'] = {} self._variables['dvdx']['longname'] = 'dvdx' self._variables['dvdx']['dimension'] = '1/s' self._variables['dvdy'] = {} self._variables['dvdy']['longname'] = 'dvdy' self._variables['dvdy']['dimension'] = '1/s' self._variables['dvdz'] = {} self._variables['dvdz']['longname'] = 'dvdz' self._variables['dvdz']['dimension'] = '1/s' self._variables['dwdx'] = {} self._variables['dwdx']['longname'] = 'dwdx' self._variables['dwdx']['dimension'] = '1/s' self._variables['dwdy'] = {} self._variables['dwdy']['longname'] = 'dwdy' self._variables['dwdy']['dimension'] = '1/s' self._variables['dwdz'] = {} self._variables['dwdz']['longname'] = 'dwdz' self._variables['dwdz']['dimension'] = '1/s' def _allocate_placeholders(self) -> None: super()._allocate_placeholders() self._dudx = np.zeros(self._size) self._dudy = np.zeros(self._size) self._dudz = np.zeros(self._size) self._dvdx = np.zeros(self._size) self._dvdy = np.zeros(self._size) self._dvdz = np.zeros(self._size) self._dwdx = np.zeros(self._size) self._dwdy = np.zeros(self._size) self._dwdz = np.zeros(self._size) self._variables['dudx']['ref'] = self._dudx self._variables['dudy']['ref'] = self._dudy self._variables['dudz']['ref'] = self._dudz self._variables['dvdx']['ref'] = self._dvdx self._variables['dvdy']['ref'] = self._dvdy self._variables['dvdz']['ref'] = self._dvdz self._variables['dwdx']['ref'] = self._dwdx self._variables['dwdy']['ref'] = self._dwdy self._variables['dwdz']['ref'] = self._dwdz
[docs] def allocate_flux_molecule_placeholders(self, N: int = 0) -> None: """Allocates flux molecule data placeholders Parameters ---------- N: int : number of faces (Default value = 0) """ self.__s_vel = np.zeros(N) self.__u_face = np.zeros(N) self.__v_face = np.zeros(N) self.__w_face = np.zeros(N)
[docs] def set_values(self, dd: ndarray, idx: int = None) -> None: """Sets array values for all cells or cell with specified cell index to a set of initial values or data from provided array Parameters ---------- dd: ndarray : velocity gradient array (3x3) idx: int : cell index (Default value = None) """ if idx is None: idx1, idx2 = self.get_range() self._dudx[idx1:idx2] = dd[0][0] self._dudy[idx1:idx2] = dd[0][1] self._dudz[idx1:idx2] = dd[0][2] self._dvdx[idx1:idx2] = dd[1][0] self._dvdy[idx1:idx2] = dd[1][1] self._dvdz[idx1:idx2] = dd[1][2] self._dwdx[idx1:idx2] = dd[2][0] self._dwdy[idx1:idx2] = dd[2][1] self._dwdz[idx1:idx2] = dd[2][2] else: self._dudx[idx] = dd[0][0] self._dudy[idx] = dd[0][1] self._dudz[idx] = dd[0][2] self._dvdx[idx] = dd[1][0] self._dvdy[idx] = dd[1][1] self._dvdz[idx] = dd[1][2] self._dwdx[idx] = dd[2][0] self._dwdy[idx] = dd[2][1] self._dwdz[idx] = dd[2][2]
[docs] def get_VGrad(self, idx: int) -> ndarray: """Gets velocity gradients for specified cell index Parameters ---------- idx: int : cell index """ dd = np.zeros((3, 3)) dd[0][0] = self._dudx[idx] dd[0][1] = self._dudy[idx] dd[0][2] = self._dudz[idx] dd[1][0] = self._dvdx[idx] dd[1][1] = self._dvdy[idx] dd[1][2] = self._dvdz[idx] dd[2][0] = self._dwdx[idx] dd[2][1] = self._dwdy[idx] dd[2][2] = self._dwdz[idx] return dd
[docs] def set_from_VGrad(self, vgrad: VGrad) -> None: """Sets data from prototype VGrad object Parameters ---------- vgrad: VGrad : instance of velocity gradient VGrad object """ idx1, idx2 = self.get_range() self._dudx[idx1:idx2] = vgrad.dudx self._dudy[idx1:idx2] = vgrad.dudy self._dudz[idx1:idx2] = vgrad.dudz self._dvdx[idx1:idx2] = vgrad.dvdx self._dvdy[idx1:idx2] = vgrad.dvdy self._dvdz[idx1:idx2] = vgrad.dvdz self._dwdx[idx1:idx2] = vgrad.dwdx self._dwdy[idx1:idx2] = vgrad.dwdy self._dwdz[idx1:idx2] = vgrad.dwdz
[docs] def set_from_arrays(self, dudx: ndarray, dudy: ndarray, dudz: ndarray, dvdx: ndarray, dvdy: ndarray, dvdz: ndarray, dwdx: ndarray, dwdy: ndarray, dwdz: ndarray) -> None: """Sets velocity gradient values from provided arrays Parameters ---------- dudx: ndarray : dudx array dudy: ndarray : dudy array dudz: ndarray : dudz array dvdx: ndarray : dvdx array dvdy: ndarray : dvdy array dvdz: ndarray : dvdz array dwdx: ndarray : dwdx array dwdy: ndarray : dwdy array dwdz: ndarray : dwdz array """ idx1, idx2 = self.get_range() self._dudx[idx1:idx2] = dudx[idx1:idx2] self._dudy[idx1:idx2] = dudy[idx1:idx2] self._dudz[idx1:idx2] = dudz[idx1:idx2] self._dvdx[idx1:idx2] = dvdx[idx1:idx2] self._dvdy[idx1:idx2] = dvdy[idx1:idx2] self._dvdz[idx1:idx2] = dvdz[idx1:idx2] self._dwdx[idx1:idx2] = dwdx[idx1:idx2] self._dwdy[idx1:idx2] = dwdy[idx1:idx2] self._dwdz[idx1:idx2] = dwdz[idx1:idx2]
[docs] def get_arrays(self) -> Tuple[ndarray, ...]: """Gets velocity gradient arrays Returns ------- tuple tuple of ndarray (dudx, dudy, dudz, dvdx, dvdy, dvdz, dwdx, dwdy, dwdz) """ idx1, idx2 = self.get_range() return ( self._dudx[idx1:idx2], self._dudy[idx1:idx2], self._dudz[idx1:idx2], self._dvdx[idx1:idx2], self._dvdy[idx1:idx2], self._dvdz[idx1:idx2], self._dwdx[idx1:idx2], self._dwdy[idx1:idx2], self._dwdz[idx1:idx2])
[docs] def get_arrays_with_ghosts(self) -> Tuple[ndarray, ...]: """Gets velocity gradient arrays including ghost values Returns ------- tuple tuple of ndarray (dudx, dudy, dudz, dvdx, dvdy, dvdz, dwdx, dwdy, dwdz) """ return ( self._dudx, self._dudy, self._dudz, self._dvdx, self._dvdy, self._dvdz, self._dwdx, self._dwdy, self._dwdz)
[docs] def set_from_gradient_field(self, v: 'VGradField') -> None: """Sets velocity gradient values from prototype VGradField object Parameters ---------- v: VGradField : prototype VGradField object """ dudx, dudy, dudz, dvdx, dvdy, dvdz, dwdx, dwdy, dwdz = v.get_arrays() self.set_from_arrays(dudx, dudy, dudz, dvdx, dvdy, dvdz, dwdx, dwdy, dwdz)
[docs] def get_divergence(self, idx: int) -> float: """Extracts the divergence of the velocity field for specified cell index Parameters ---------- idx: int : cell index Returns ------- float divergence of velocity field """ return self._dudx[idx] + self._dvdy[idx] + self._dwdz[idx]
[docs] def get_vorticity(self, idx: int) -> ndarray: """Extracts the vorticity vector for specified cell index Parameters ---------- idx: int : cell index Returns ------- ndarray vorticity vector """ v = np.zeros(3) v[0] = self._dwdy[idx] - self._dvdz[idx] v[1] = self._dudz[idx] - self._dwdx[idx] v[2] = self._dvdx[idx] - self._dudy[idx] return v
[docs] def get_vorticity_magnitude(self, idx: int) -> float: """Calculates the vorticity magnitude for specified cell index Parameters ---------- idx: int : cell index Returns ------- float vorticity magnitude """ v = self.get_vorticity(idx) return np.sqrt(sum(v * v))
[docs] def get_SijSij(self, idx: int) -> float: """Gets strain rate tensor product for specified cell index Parameters ---------- idx: int : cell index Returns ------- float SijSij """ return (self._dudx[idx] ** 2 + self._dvdy[idx] ** 2 + self._dwdz[idx] ** 2 + 0.5 * ((self._dudy[idx] + self._dvdx[idx]) ** 2 + (self._dudz[idx] + self._dwdx[idx]) ** 2 + (self._dvdz[idx] + self._dwdy[idx]) ** 2))
def __get_face_velocities(self, u: ndarray, v: ndarray, w: ndarray, s: ndarray, kc: Union[ndarray, list], idx1: int, idx2: int, MODE: Any = GradientMode.AVERAGE): if type(MODE) is GradientMode: if MODE is GradientMode.AVERAGE: self.__u_face[idx1:idx2] = 0.5 * (u[kc[idx1:idx2, 1]] + u[kc[idx1:idx2, 2]]) self.__v_face[idx1:idx2] = 0.5 * (v[kc[idx1:idx2, 1]] + v[kc[idx1:idx2, 2]]) self.__w_face[idx1:idx2] = 0.5 * (w[kc[idx1:idx2, 1]] + w[kc[idx1:idx2, 2]]) return if MODE is GradientMode.BOUNDARY_MIRROR: self.__s_vel[idx1:idx2] = (s[idx1:idx2, 0] * u[kc[idx1:idx2, 1]] + s[idx1:idx2, 1] * v[kc[idx1:idx2, 1]] + s[idx1:idx2, 2] * w[kc[idx1:idx2, 1]]) self.__u_face[idx1:idx2] = u[kc[idx1:idx2, 1]] - self.__s_vel[idx1:idx2] * s[idx1:idx2, 0] self.__v_face[idx1:idx2] = v[kc[idx1:idx2, 1]] - self.__s_vel[idx1:idx2] * s[idx1:idx2, 1] self.__w_face[idx1:idx2] = w[kc[idx1:idx2, 1]] - self.__s_vel[idx1:idx2] * s[idx1:idx2, 2] return if MODE is GradientMode.BOUNDARY_EXTRAPOLATE: self.__u_face[idx1:idx2] = 1.5 * u[kc[idx1:idx2, 1]] - 0.5 * u[kc[idx1:idx2, 0]] self.__v_face[idx1:idx2] = 1.5 * v[kc[idx1:idx2, 1]] - 0.5 * v[kc[idx1:idx2, 0]] self.__w_face[idx1:idx2] = 1.5 * w[kc[idx1:idx2, 1]] - 0.5 * w[kc[idx1:idx2, 0]] return
[docs] def add_gradients(self, u: ndarray, v: ndarray, w: ndarray, fmp: FMP, StartIndex: int = 0, n_faces: int = 0, MODE: Any = GradientMode.AVERAGE) -> None: """Add face contribution to velocity gradient field Parameters ---------- u : ndarray : x-velocity vector v : ndarray : y-velocity vector w : ndarray : z-velocity vector fmp : FMP : flux molecule pointer placeholder StartIndex : int : first index (Default value = 0) n_faces : int : number of faces (Default value = 0) MODE : GradientMode : type of gradient calculation (Default value = GradientMode.AVERAGE) """ if type(MODE) is GradientMode: if np.int32(n_faces) == 0: n_faces = fmp.size - StartIndex n_faces, idx1, idx2 = np.int32([n_faces, StartIndex, StartIndex + n_faces]) if n_faces == 0: return kp, kc = fmp.get_pointers() s, sl = fmp.get_conv_metrics() self.__get_face_velocities(u, v, w, s, kc, idx1, idx2, MODE) self._dudx[kc[idx1:idx2, 1]] += self.__u_face[idx1:idx2] * s[idx1:idx2, 0] self._dudy[kc[idx1:idx2, 1]] += self.__u_face[idx1:idx2] * s[idx1:idx2, 1] self._dudz[kc[idx1:idx2, 1]] += self.__u_face[idx1:idx2] * s[idx1:idx2, 2] self._dvdx[kc[idx1:idx2, 1]] += self.__v_face[idx1:idx2] * s[idx1:idx2, 0] self._dvdy[kc[idx1:idx2, 1]] += self.__v_face[idx1:idx2] * s[idx1:idx2, 1] self._dvdz[kc[idx1:idx2, 1]] += self.__v_face[idx1:idx2] * s[idx1:idx2, 2] self._dwdx[kc[idx1:idx2, 1]] += self.__w_face[idx1:idx2] * s[idx1:idx2, 0] self._dwdy[kc[idx1:idx2, 1]] += self.__w_face[idx1:idx2] * s[idx1:idx2, 1] self._dwdz[kc[idx1:idx2, 1]] += self.__w_face[idx1:idx2] * s[idx1:idx2, 2] self._dudx[kc[idx1:idx2, 2]] -= self.__u_face[idx1:idx2] * s[idx1:idx2, 0] self._dudy[kc[idx1:idx2, 2]] -= self.__u_face[idx1:idx2] * s[idx1:idx2, 1] self._dudz[kc[idx1:idx2, 2]] -= self.__u_face[idx1:idx2] * s[idx1:idx2, 2] self._dvdx[kc[idx1:idx2, 2]] -= self.__v_face[idx1:idx2] * s[idx1:idx2, 0] self._dvdy[kc[idx1:idx2, 2]] -= self.__v_face[idx1:idx2] * s[idx1:idx2, 1] self._dvdz[kc[idx1:idx2, 2]] -= self.__v_face[idx1:idx2] * s[idx1:idx2, 2] self._dwdx[kc[idx1:idx2, 2]] -= self.__w_face[idx1:idx2] * s[idx1:idx2, 0] self._dwdy[kc[idx1:idx2, 2]] -= self.__w_face[idx1:idx2] * s[idx1:idx2, 1] self._dwdz[kc[idx1:idx2, 2]] -= self.__w_face[idx1:idx2] * s[idx1:idx2, 2]