"""Postprocessing variables - flow field data placeholder (PostField 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.placeholders import FlowDataPlaceHolder, ConsField, AuxvField
from g3d.flow.vars import Post
from g3d.gas import Gas
[docs]
class PostField(FlowDataPlaceHolder):
"""Definition of class PostField, extends class FlowDataPlaceHolder: postprocessing variables container"""
def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
@property
def p0(self) -> ndarray:
"""Total pressure [Pa]
Returns
-------
ndarray
total pressure array
"""
return self._p0
@property
def t0(self) -> ndarray:
"""Total temperature [K]
Returns
-------
ndarray
total temperature array
"""
return self._t0
@property
def M(self) -> ndarray:
"""Mach number []
Returns
-------
ndarray
Mach number array
"""
return self._M
@property
def s(self) -> ndarray:
"""Entropy [J/K]
Returns
-------
ndarray
entropy array
"""
return self._s
def _set_default(self) -> None:
super()._set_default()
self._tag = 'postprocessing variables'
def _define_variables(self) -> None:
super()._define_variables()
self._variables['p0'] = {}
self._variables['p0']['longname'] = 'total pressure'
self._variables['p0']['dimension'] = 'Pa'
self._variables['t0'] = {}
self._variables['t0']['longname'] = 'total temperature'
self._variables['t0']['dimension'] = 'K'
self._variables['M'] = {}
self._variables['M']['longname'] = 'Mach number'
self._variables['M']['dimension'] = '[]'
self._variables['s'] = {}
self._variables['s']['longname'] = 'entropy'
self._variables['s']['dimension'] = 'J/K'
def _allocate_placeholders(self) -> None:
super()._allocate_placeholders()
self._p0 = np.zeros(self._size)
self._t0 = np.zeros(self._size)
self._M = np.zeros(self._size)
self._s = np.zeros(self._size)
self._variables['p0']['ref'] = self._p0
self._variables['t0']['ref'] = self._t0
self._variables['M']['ref'] = self._M
self._variables['s']['ref'] = self._s
[docs]
def set_values(self,
p0: Union[float, ndarray],
t0: Union[float, ndarray],
M: Union[float, ndarray],
s: 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
----------
p0 : float or ndarray :
total pressure value or array of values
t0 : float or ndarray :
total temperature value or array of values
M : float or ndarray :
Mach number value or array of values
s : float or ndarray :
entropy value or array of values
idx : int :
cell index (Default value = None)
"""
if idx is None:
idx1, idx2 = self.get_range()
self._p0[idx1:idx2] = p0
self._t0[idx1:idx2] = t0
self._M[idx1:idx2] = M
self._s[idx1:idx2] = s
else:
self._p0[idx] = p0
self._t0[idx] = t0
self._M[idx] = M
self._s[idx] = s
[docs]
def set_from_Post(self, p: Post) -> None:
"""Set array values from provided postprocessing variable object
Parameters
----------
p : Post :
postprocessing variable object
"""
idx1, idx2 = self.get_range()
self._p0[idx1:idx2] = p.p0
self._t0[idx1:idx2] = p.t0
self._M[idx1:idx2] = p.M
self._s[idx1:idx2] = p.s
[docs]
def set_from_arrays(self, p0: ndarray, t0: ndarray, M: ndarray, s: ndarray) -> None:
"""Set data from provided arrays
Parameters
----------
p0 : ndarray :
density data
t0 : ndarray :
x-momentum data
M : ndarray :
y-momentum data
s : ndarray :
z-momentum data
"""
idx1, idx2 = self.get_range()
self._p0[idx1:idx2] = p0[idx1:idx2]
self._t0[idx1:idx2] = t0[idx1:idx2]
self._M[idx1:idx2] = M[idx1:idx2]
self._s[idx1:idx2] = s[idx1:idx2]
[docs]
def get_arrays(self) -> Tuple[ndarray, ...]:
"""Gets postprocessing flow data arrays
Returns
-------
tuple
data arrays (p0, t0, M, s)
"""
idx1, idx2 = self.get_range()
return (
self._p0[idx1:idx2],
self._t0[idx1:idx2],
self._M[idx1:idx2],
self._s[idx1:idx2])
[docs]
def get_arrays_with_ghosts(self) -> Tuple[ndarray, ...]:
"""Gets postprocessing flow data arrays including ghost cell values
Returns
-------
tuple
data arrays (p0, t0, M, s)
"""
return (
self._p0,
self._t0,
self._M,
self._s)
[docs]
def set_from_post_field(self, p: 'PostField') -> None:
"""Copy data from provided postprocessing variables placeholder object
Parameters
----------
p : PostField :
postprocessing variables container
"""
p0, t0, M, s = p.get_arrays()
self.set_from_arrays(p0, t0, M, s)
[docs]
def update(self, cons: ConsField, auxv: AuxvField, 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
auxv : AuxvField :
primitive 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()
p, u, v, w, t, c = auxv.get_arrays()
idx1, idx2 = self.get_range()
self._M[idx1:idx2] = (u[idx1:idx2] ** 2 + v[idx1:idx2] ** 2 + w[idx1:idx2] ** 2) ** 0.5 / c[idx1:idx2]
self._t0[idx1:idx2] = t[idx1:idx2] * (np.ones(self._size) + 0.5 * gas.gm1 * self._M[idx1:idx2] ** 2)
self._p0[idx1:idx2] = p[idx1:idx2] * (
np.ones(self._size) + 0.5 * gas.gm1 * self._M[idx1:idx2] ** 2) ** gas.g_over_gm1
self._s[idx1:idx2] = p[idx1:idx2] / ro[idx1:idx2] ** gas.gamma
if g3d_disp.verbose or verbose:
self.print_extreme_values()