Source code for g3d.flow.placeholders.cons

"""Conservative variables - flow field data placeholder (ConsField 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 G3DWorld
from g3d.defs import DIMMode

from g3d.flow.vars import Cons

from g3d.flow.placeholders import FlowDataPlaceHolder
from g3d.mesh.geo import Coordinates


[docs] class ConsField(FlowDataPlaceHolder): """Definition of class ConsField, extends class FlowDataPlaceHolder: conservative flow variables container""" def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) @property def ro(self) -> ndarray: """Density [kg/m^3] Returns ------- ndarray density array """ return self._ro @property def ru(self) -> ndarray: """X-momentum [kg/(m^2 s)] Returns ------- ndarray x-momentum array """ return self._ru @property def rv(self) -> ndarray: """Y-momentum [kg/(m^2 s)] Returns ------- ndarray y-momentum array """ return self._rv @property def rw(self) -> ndarray: """Z-momentum [kg/(m^2 s)] Returns ------- ndarray z-momentum array """ return self._rw @property def et(self) -> ndarray: """Total energy [J/m^3] Returns ------- ndarray total energy array """ return self._et def _set_default(self) -> None: super()._set_default() self._tag = 'conservative variables' def _define_variables(self) -> None: super()._define_variables() self._variables['ro'] = {} self._variables['ro']['longname'] = 'density' self._variables['ro']['dimension'] = 'kg/m^3' self._variables['ru'] = {} self._variables['ru']['longname'] = 'x-momentum' self._variables['ru']['dimension'] = 'kg/(m^2 s)' self._variables['rv'] = {} self._variables['rv']['longname'] = 'y-momentum' self._variables['rv']['dimension'] = 'kg/(m^2 s)' self._variables['rw'] = {} self._variables['rw']['longname'] = 'z-momentum' self._variables['rw']['dimension'] = 'kg/(m^2 s)' self._variables['et'] = {} self._variables['et']['longname'] = 'energy' self._variables['et']['dimension'] = 'J kg/m^3' self.__define_sigma_placeholder() g3d_world = G3DWorld() g3d_world.sizes.n_var = len(self._variables.keys()) def __define_sigma_placeholder(self) -> None: g3d_world = G3DWorld() if g3d_world.options.dim_mode is DIMMode.Q3D: if 'sigma' not in self._variables: self._variables['sigma'] = {} self._variables['sigma']['longname'] = 'stream tube source term' self._variables['sigma']['dimension'] = 'N/m^3' def _allocate_placeholders(self) -> None: self.__define_sigma_placeholder() super()._allocate_placeholders() self._ro = np.zeros(self._size) self._ru = np.zeros(self._size) self._rv = np.zeros(self._size) self._rw = np.zeros(self._size) self._et = np.zeros(self._size) self._variables['ro']['ref'] = self._ro self._variables['ru']['ref'] = self._ru self._variables['rv']['ref'] = self._rv self._variables['rw']['ref'] = self._rw self._variables['et']['ref'] = self._et if G3DWorld().options.dim_mode is DIMMode.Q3D: self._sigma = np.zeros(self._size) self._variables['sigma']['ref'] = self._sigma
[docs] def set_values(self, ro: Union[float, ndarray], ru: Union[float, ndarray], rv: Union[float, ndarray], rw: Union[float, ndarray], et: Union[float, 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 arrays Parameters ---------- ro : float or ndarray : density value or array of values ru : float or ndarray : x-momentum value or array of values rv : float or ndarray : y-momentum value or array of values rw : float or ndarray : z-momentum value or array of values et : float or ndarray : total energy value or array of values idx : int : cell index (Default value = None) """ if idx is None: idx1, idx2 = self.get_range() self._ro[idx1:idx2] = ro self._ru[idx1:idx2] = ru self._rv[idx1:idx2] = rv self._rw[idx1:idx2] = rw self._et[idx1:idx2] = et else: self._ro[idx] = ro self._ru[idx] = ru self._rv[idx] = rv self._rw[idx] = rw self._et[idx] = et
[docs] def get_Cons(self, idx: int) -> Cons: """Extracts an instance of conservative variable object for specified cell index Parameters ---------- idx : int : cell index Returns ------- Cons conservative variable object """ q = Cons() q.ro = self._ro[idx] q.ru = self._ru[idx] q.rv = self._rv[idx] q.rw = self._rw[idx] q.et = self._et[idx] return q
[docs] def get_by_index(self, idx: int) -> Tuple[float, ...]: """Gets tuple of conservative variable values for cell with specified index Parameters ---------- idx : int : cell index Returns ------- tuple conservative variable values (ro, ru, rv, rw, et) """ return self._ro[idx], self._ru[idx], self._rv[idx], self._rw[idx], self._et[idx]
[docs] def set_momentum_vector(self, idx: int, r_vel: Union[ndarray, list[float], Tuple[float, ...]]) -> None: """Set momentum vector for cell with specified index Parameters ---------- idx : int : cell index r_vel : ndarray, list, or tuple : momentum vector (ru, rv, rw) """ self._ru[idx] = r_vel[0] self._rv[idx] = r_vel[1] self._rw[idx] = r_vel[2]
[docs] def get_momentum_vector(self, idx: int) -> ndarray: """Get momentum vector for cell with specified index Parameters ---------- idx : int : cell index Returns ------- ndarray momentum vector (ru, rv, rw) """ return np.array([self._ru[idx], self._rv[idx], self._rw[idx]])
[docs] def set_from_arrays(self, ro: ndarray, ru: ndarray, rv: ndarray, rw: ndarray, et: ndarray) -> None: """Set data from provided arrays Parameters ---------- ro : ndarray : density data ru : ndarray : x-momentum data rv : ndarray : y-momentum data rw : ndarray : z-momentum data et : ndarray : total energy data """ idx1, idx2 = self.get_range() self._ro[idx1:idx2] = ro[idx1:idx2] self._ru[idx1:idx2] = ru[idx1:idx2] self._rv[idx1:idx2] = rv[idx1:idx2] self._rw[idx1:idx2] = rw[idx1:idx2] self._et[idx1:idx2] = et[idx1:idx2]
[docs] def get_arrays(self) -> Tuple[ndarray, ...]: """Gets conservative flow data arrays Returns ------- tuple data arrays (ro, ru, rv, rw, et) """ idx1, idx2 = self.get_range() return ( self._ro[idx1:idx2], self._ru[idx1:idx2], self._rv[idx1:idx2], self._rw[idx1:idx2], self._et[idx1:idx2])
[docs] def get_arrays_with_ghosts(self) -> Tuple[ndarray, ...]: """Gets conservative flow data arrays including ghost cell values Returns ------- tuple data arrays (ro, ru, rv, rw, et) """ return ( self._ro, self._ru, self._rv, self._rw, self._et)
[docs] def set_from_Cons(self, c: Cons) -> None: """Set array values from provided conservative variable object Parameters ---------- c : Cons : conservative variable object """ idx1, idx2 = self.get_range() self._ro[idx1:idx2] = c.ro self._ru[idx1:idx2] = c.ru self._rv[idx1:idx2] = c.rv self._rw[idx1:idx2] = c.rw self._et[idx1:idx2] = c.et
[docs] def set_by_index_from_Cons(self, idx: int, c: Cons) -> None: """Set array values for cell with specified cell index from provided conservative variable object Parameters ---------- idx : int : cell index c : Cons : conservative variable object """ self._ro[idx] = c.ro self._ru[idx] = c.ru self._rv[idx] = c.rv self._rw[idx] = c.rw self._et[idx] = c.et
[docs] def set_from_cons_field(self, c: 'ConsField') -> None: """Copy data from provided conservative variables placeholder object Parameters ---------- c : ConsField : conservative variables container """ ro, ru, rv, rw, et = c.get_arrays() self.set_from_arrays(ro, ru, rv, rw, et) g3d_world = G3DWorld() if g3d_world.options.dim_mode is DIMMode.Q3D: self.set_from_array(c.get_array('sigma'), 'sigma')
# -- OLD STUFF --#
[docs] def CellToNode(self, c: 'ConsField') -> None: """Convert cell values to node values Parameters ---------- c : ConsField : conservative variables container """ c_first, c_last = c.get_range() c_n_cells = c_last - c_first c_n_nodes = c_n_cells + 1 self.setup(n_cells=c_n_nodes) self.nullify() for i in range(c_n_cells): j = i + c_first self._ro[i] += 0.5 * c.ro[j] self._ro[i + 1] += 0.5 * c.ro[j] self._ru[i] += 0.5 * c.ru[j] self._ru[i + 1] += 0.5 * c.ru[j] self._rv[i] += 0.5 * c.rv[j] self._rv[i + 1] += 0.5 * c.rv[j] self._rw[i] += 0.5 * c.rw[j] self._rw[i + 1] += 0.5 * c.rw[j] self._et[i] += 0.5 * c.et[j] self._et[i + 1] += 0.5 * c.et[j] self._ro[0] = 4.0 * self._ro[0] - self._ro[1] self._ru[0] = 4.0 * self._ru[0] - self._ru[1] self._rv[0] = 4.0 * self._rv[0] - self._rv[1] self._rw[0] = 4.0 * self._rw[0] - self._rw[1] self._et[0] = 4.0 * self._et[0] - self._et[1] self._ro[self._size - 1] = 4.0 * self._ro[self._size - 1] - self._ro[self._size - 2] self._ru[self._size - 1] = 4.0 * self._ru[self._size - 1] - self._ru[self._size - 2] self._rv[self._size - 1] = 4.0 * self._rv[self._size - 1] - self._rv[self._size - 2] self._rw[self._size - 1] = 4.0 * self._rw[self._size - 1] - self._rw[self._size - 2] self._et[self._size - 1] = 4.0 * self._et[self._size - 1] - self._et[self._size - 2]
[docs] def Interpolate(self, nodes: Coordinates, cells: Coordinates, node_cons: 'ConsField') -> None: """Interpolate cell-centered flow field data to node-centered data Parameters ---------- nodes : Coordinates : node coordinates cells : Coordinates : cell coordinates node_cons : ConsField : node stored conservative variables """ idx = 0 for i in range(cells.size): xc = cells.X[i] cell_found = False while idx < (nodes.size - 1): if nodes.X[idx] <= xc <= nodes.X[idx + 1]: cell_found = True break else: idx = idx + 1 if cell_found: interpolate_factor = (xc - nodes.X[idx]) / (nodes.X[idx + 1] - nodes.X[idx]) self._ro[i] = node_cons.ro[idx] + (node_cons.ro[idx + 1] - node_cons.ro[idx]) * interpolate_factor self._ru[i] = node_cons.ru[idx] + (node_cons.ru[idx + 1] - node_cons.ru[idx]) * interpolate_factor self._rv[i] = node_cons.rv[idx] + (node_cons.rv[idx + 1] - node_cons.rv[idx]) * interpolate_factor self._rw[i] = node_cons.rw[idx] + (node_cons.rw[idx + 1] - node_cons.rw[idx]) * interpolate_factor self._et[i] = node_cons.et[idx] + (node_cons.et[idx + 1] - node_cons.et[idx]) * interpolate_factor
# else: # console.log('interpolation error: cell '+i+' (x = '+xc+') not found');