"""Auxiliary variables - flow field data placeholder (AuxvField 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 G3DDisplay
from g3d.flow.vars import Auxv
from g3d.flow.placeholders import FlowDataPlaceHolder
from g3d.gas import Gas
from g3d.flow.placeholders import ConsField
[docs]
class AuxvField(FlowDataPlaceHolder):
"""Definition of class AuxvField, extends class FlowDataPlaceHolder: primitive flow variables container"""
def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
@property
def p(self) -> ndarray:
"""Pressure [Pa]
Returns
-------
ndarray
pressure array
"""
return self._p
@property
def u(self) -> ndarray:
"""X-direction velocity [m/s]
Returns
-------
ndarray
u velocity array
"""
return self._u
@property
def v(self) -> ndarray:
"""Y-direction velocity [m/s]
Returns
-------
ndarray
v velocity array
"""
return self._v
@property
def w(self) -> ndarray:
"""Z-direction velocity [m/s]
Returns
-------
ndarray
w velocity array
"""
return self._w
@property
def t(self) -> ndarray:
"""Temperature [K]
Returns
-------
ndarray
temperature array
"""
return self._t
@property
def c(self) -> ndarray:
"""Speed of sound [m/s]
Returns
-------
ndarray
speed of sound array
"""
return self._c
def _set_default(self) -> None:
super()._set_default()
self._tag = 'auxiliary variables'
def _define_variables(self) -> None:
super()._define_variables()
self._variables['p'] = {}
self._variables['p']['longname'] = 'pressure'
self._variables['p']['dimension'] = 'Pa'
self._variables['u'] = {}
self._variables['u']['longname'] = 'x-velocity'
self._variables['u']['dimension'] = 'm/s'
self._variables['v'] = {}
self._variables['v']['longname'] = 'y-velocity'
self._variables['v']['dimension'] = 'm/s'
self._variables['w'] = {}
self._variables['w']['longname'] = 'z-velocity'
self._variables['w']['dimension'] = 'm/s'
self._variables['t'] = {}
self._variables['t']['longname'] = 'temperature'
self._variables['t']['dimension'] = 'K'
self._variables['c'] = {}
self._variables['c']['longname'] = 'speed of sound'
self._variables['c']['dimension'] = 'm/s'
def _allocate_placeholders(self) -> None:
super()._allocate_placeholders()
self._p = np.zeros(self._size)
self._u = np.zeros(self._size)
self._v = np.zeros(self._size)
self._w = np.zeros(self._size)
self._t = np.zeros(self._size)
self._c = np.zeros(self._size)
self._variables['p']['ref'] = self._p
self._variables['u']['ref'] = self._u
self._variables['v']['ref'] = self._v
self._variables['w']['ref'] = self._w
self._variables['t']['ref'] = self._t
self._variables['c']['ref'] = self._c
[docs]
def set_variables(self,
p: Union[float, ndarray],
u: Union[float, ndarray],
v: Union[float, ndarray],
w: Union[float, ndarray],
t: Union[float, ndarray],
c: 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
----------
p : float or ndarray :
pressure value or array of values
u : float or ndarray :
x-velocity value or array of values
v : float or ndarray :
y-velocity value or array of values
w : float or ndarray :
z-velocity value or array of values
t : float or ndarray :
temperature value or array of values
c : float or ndarray :
speed-of-sound value or array of values
idx : int :
cell index (Default value = None)
"""
if idx is None:
# works both for float and ndarray
idx1, idx2 = self.get_range()
self._p[idx1:idx2] = p
self._u[idx1:idx2] = u
self._v[idx1:idx2] = v
self._w[idx1:idx2] = w
self._t[idx1:idx2] = t
self._c[idx1:idx2] = c
else:
self._p[idx] = p
self._u[idx] = u
self._v[idx] = v
self._w[idx] = w
self._t[idx] = t
self._c[idx] = c
[docs]
def get_Auxv(self, idx: int) -> Auxv:
"""Extracts an instance of primitive variable object for specified cell index
Parameters
----------
idx : int :
cell index
Returns
-------
Auxv
primitive variable object
"""
a = Auxv()
a.p = self._p[idx]
a.u = self._u[idx]
a.v = self._v[idx]
a.w = self._w[idx]
a.t = self._t[idx]
a.c = self._c[idx]
return a
[docs]
def set_velocity_vector(self, idx: int, vel: Union[ndarray, list[float], Tuple[float, ...]]):
"""Set velocity vector for cell with specified index
Parameters
----------
idx : int :
cell index
vel : ndarray, list, or tuple :
velocity vector (u, v, w)
"""
self._u[idx] = vel[0]
self._v[idx] = vel[1]
self._w[idx] = vel[2]
[docs]
def get_velocity_vector(self, idx: int) -> ndarray:
"""Get velocity vector for cell with specified index
Parameters
----------
idx : int :
cell index
Returns
-------
ndarray
velocity vector (u, v, w)
"""
return np.array([self._u[idx], self._v[idx], self._w[idx]])
[docs]
def set_from_Auxv(self, a: Auxv) -> None:
"""Set array values from provided primitive variable object
Parameters
----------
a : Auxv :
primitive variable object
Returns
-------
"""
idx1, idx2 = self.get_range()
self._p[idx1:idx2] = a.p
self._u[idx1:idx2] = a.u
self._v[idx1:idx2] = a.v
self._w[idx1:idx2] = a.w
self._t[idx1:idx2] = a.t
self._c[idx1:idx2] = a.c
[docs]
def set_from_arrays(self, p: ndarray, u: ndarray, v: ndarray, w: ndarray, t: ndarray, c: ndarray) -> None:
"""Set data from provided arrays
Parameters
----------
p : ndarray :
pressure data
u : ndarray :
x-velocity data
v : ndarray :
y-velocity data
w : ndarray :
z-velocity data
t : ndarray :
temperature data
c : ndarray :
speed-of-sound data
"""
idx1, idx2 = self.get_range()
self._p[idx1:idx2] = p[idx1:idx2]
self._u[idx1:idx2] = u[idx1:idx2]
self._v[idx1:idx2] = v[idx1:idx2]
self._w[idx1:idx2] = w[idx1:idx2]
self._t[idx1:idx2] = t[idx1:idx2]
self._c[idx1:idx2] = c[idx1:idx2]
[docs]
def get_arrays(self) -> Tuple[ndarray, ...]:
"""Gets primitive flow data arrays
Returns
-------
tuple
data arrays (p, u, v, w, t, c)
"""
idx1, idx2 = self.get_range()
return (
self._p[idx1:idx2],
self._u[idx1:idx2],
self._v[idx1:idx2],
self._w[idx1:idx2],
self._t[idx1:idx2],
self._c[idx1:idx2])
[docs]
def get_arrays_with_ghosts(self) -> Tuple[ndarray, ...]:
"""Gets primitive flow data arrays including ghost cell values
Returns
-------
tuple
data arrays (p, u, v, w, t, c)
"""
return (
self._p,
self._u,
self._v,
self._w,
self._t,
self._c)
[docs]
def set_from_auxv_field(self, a: 'AuxvField') -> None:
"""Copy data from another AuxvField object
Parameters
----------
a : AuxvField :
flow data source
"""
p, u, v, w, t, c = a.get_arrays()
self.set_from_arrays(p, u, v, w, t, c)
[docs]
def get_velocity_arrays_with_ghosts(self) -> Tuple[ndarray, ...]:
"""Gets velocity data arrays including ghost cell values
Returns
-------
tuple
data arrays (u, v, w)
"""
return self._u, self._v, self._w
[docs]
def get_velocity_arrays(self) -> Tuple[ndarray, ...]:
"""Gets velocity data arrays
Returns
-------
tuple
data arrays (u, v, w)
"""
idx1, idx2 = self.get_range()
return self._u[idx1:idx2], self._v[idx1:idx2], self._w[idx1:idx2]
[docs]
def update(self, cons: ConsField, gas: Gas, verbose: bool = False) -> None:
"""Calculates new flow data values based on provided input and updates placeholder arrays
Parameters
----------
cons : ConsField :
conservative flow variables
gas : Gas :
gas model
verbose : bool :
in verbose mode, extreme values will be printed to stdout (Default value = False)
"""
g3d_disp = G3DDisplay()
ro, ru, rv, rw, et = cons.get_arrays()
idx1, idx2 = self.get_range()
self._u[idx1:idx2] = ru[idx1:idx2] / ro[idx1:idx2]
self._v[idx1:idx2] = rv[idx1:idx2] / ro[idx1:idx2]
self._w[idx1:idx2] = rw[idx1:idx2] / ro[idx1:idx2]
self._p[idx1:idx2] = (gas.gamma - 1.0) * \
(et[idx1:idx2] - 0.5 * (ru[idx1:idx2] * self._u[idx1:idx2] +
rv[idx1:idx2] * self._v[idx1:idx2] +
rw[idx1:idx2] * self._w[idx1:idx2]))
self._t[idx1:idx2] = self._p[idx1:idx2] / (ro[idx1:idx2] * gas.R)
self._c[idx1:idx2] = np.sqrt(gas.gamma * gas.R * self._t[idx1:idx2])
if g3d_disp.verbose or verbose:
self.print_extreme_values()