"""Channel flow calculator"""
from typing import Any
import os
if os.environ.get('__USE_CUDA', '0') == '1':
import cupy as np
else:
import numpy as np
from g3d.defs import G3DWorld
from g3d.defs import DIMMode
from .calculator import G3DCalculator
[docs]
class G3DChannelFlowCalculator(G3DCalculator):
"""Class collecting functions related to compressible channel flow"""
def __init__(self, *args: Any, **kwargs: Any) -> None:
"""Initialize calculator parameters"""
# default values
self.__default_u_tau = 1.
self.__default_rho = 1.
self.__default_tau_w = 1.
self.__default_Re = 1.
self.__default_Re_tau = 1.
self.__default_M = 1.
self.__default_delta = 1.
self.__default_mu = 1.
self.__default_u = 1.
self.__default_p = 1.
self.__default_T = 1.
self.__default_dpdx = -1.
# initialize channel flow parameters
self._u_tau = self.__default_u_tau
self._rho = self.__default_rho
self._tau_w = self.__default_tau_w
self._Re = self.__default_Re
self._Re_tau = self.__default_Re_tau
self._M = self.__default_M
self._delta = self.__default_delta
self._mu = self.__default_mu
self._L = 2. * self._delta * np.pi
self._W = self._delta * np.pi
self._H = 2. * self._delta
self._u = self.__default_u
self._p = self.__default_p
self._T = self.__default_T
self._dpdx = self.__default_dpdx
super().__init__(*args, **kwargs)
def _set_default(self) -> None:
super()._set_default()
self._u_tau = self.__default_u_tau
self._rho = self.__default_rho
self._tau_w = self.__default_tau_w
self._Re = self.__default_Re
self._Re_tau = self.__default_Re_tau
self._M = self.__default_M
self._delta = self.__default_delta
self._mu = self.__default_mu
self._L = 2. * self._delta * np.pi
self._W = self._delta * np.pi
self._H = 2. * self._delta
self._u = self.__default_u
self._p = self.__default_p
self._T = self.__default_T
self._dpdx = self.__default_dpdx
g3d_world = G3DWorld()
if g3d_world.options.dim_mode == DIMMode.G2D or g3d_world.options.dim_mode == DIMMode.G2D_AXISYMM:
self._W = 1.
@property
def u_tau(self) -> float:
"""Friction velocity [m/s]
Returns
-------
float
friction velocity
"""
return self._u_tau
@u_tau.setter
def u_tau(self, val: float) -> None:
self._u_tau = val
self._update_flow_data()
@property
def rho(self) -> float:
"""Density [kg/s]
Returns
-------
float
density
"""
return self._rho
@rho.setter
def rho(self, val: float) -> None:
self._rho = val
self._update_flow_data()
@property
def tau_w(self) -> float:
"""Wall-shear stress [N/m^2]
Returns
-------
float
wall-shear stress
"""
return self._tau_w
@tau_w.setter
def tau_w(self, val: float) -> None:
self._tau_w = val
self._u_tau = np.sqrt(self._tau_w / self._rho)
@property
def Re(self) -> float:
"""Reynolds number based on freestream velocity []
Returns
-------
float
Reynolds number
"""
return self._Re
@Re.setter
def Re(self, val: float) -> None:
self._Re = val
self._update_flow_data()
@property
def Re_tau(self) -> float:
"""Reynolds number based on friction velocity []
Returns
-------
float
Reynolds number
"""
return self._Re_tau
@Re_tau.setter
def Re_tau(self, val: float) -> None:
self._Re_tau = val
self._update_flow_data()
@property
def M(self) -> float:
"""Mach number based on freestream velocity []
Returns
-------
float
Mach number
"""
return self._M
@M.setter
def M(self, val: float) -> None:
self._M = val
self._update_flow_data()
@property
def delta(self) -> float:
"""Channel half height [m]
Returns
-------
float
channel half height
"""
return self._delta
@delta.setter
def delta(self, val: float) -> None:
self._delta = val
self._L = 2. * self._delta * np.pi
self._W = self._delta * np.pi
self._H = 2. * self._delta
g3d_world = G3DWorld()
if g3d_world.options.dim_mode == DIMMode.G2D or g3d_world.options.dim_mode == DIMMode.G2D_AXISYMM:
self._W = 1.
self._update_flow_data()
@property
def L(self) -> float:
"""Channel length [m]
Returns
-------
float
channel length
"""
return self._L
@L.setter
def L(self, val: float) -> None:
self._L = val
@property
def H(self) -> float:
"""Channel height [m]
Returns
-------
float
channel height
"""
return self._H
@H.setter
def H(self, val: float) -> None:
self._H = val
self._delta = 0.5 * self._H
self._update_flow_data()
@property
def W(self) -> float:
"""Channel width [m]
Returns
-------
float
channel width
"""
return self._W
@W.setter
def W(self, val: float) -> None:
self._W = val
@property
def mu(self) -> float:
"""Dynamic viscosity [kg/(m s)]
Returns
-------
float
dynamic viscosity
"""
return self._mu
@property
def u(self) -> float:
"""Velocity [m/s]
Returns
-------
float
velocity
"""
return self._u
@property
def p(self) -> float:
"""Pressure [Pa]
Returns
-------
float
pressure
"""
return self._p
@property
def T(self) -> float:
"""Temperature [K]
Returns
-------
float
temperature
"""
return self._T
def _update_flow_data(self) -> None:
self._mu = self._rho * self._u_tau * self._delta / self._Re_tau
self._u = self._u_tau * (self._Re / self._Re_tau)
self._p = self._rho * ((self._Re * self._u_tau) / (self._Re_tau * self._M)) ** 2 * (1. / self._gas.gamma)
self._T = self._gas.get_temperature(self._p, self._rho)
self._mu = (self._rho * self._u_tau * self._delta) / self._Re_tau
self._tau_w = self._u_tau ** 2 * self._rho
self._dpdx = -self._tau_w
[docs]
def print(self) -> None:
"""
print channel flow stats based on previously provided input
"""
self.header('channel flow data\n Re = %.0f, Re_t = %.0f, M = %.2f' % (self._Re, self._Re_tau, self._M))
print(' rho = %.1f kg/m^3' % self._rho)
print(' u = %.1f m/s' % self._u)
print(' p = %.3f kPa' % (self._p / 1000.))
print(' T = %.1f K (%.1f C)' % (self._T, self._T - 273))
print(' c = %.1f m/s' % (self._gas.get_speed_of_sound(self._T)))
print(' mu = %.3e kg/(ms)' % self._mu)
print(' u_tau = %.2f m/s' % self._u_tau)
print(' tau_w = %.2f Pa' % self.tau_w)
print(' delta = %.2f m' % self._delta)
print(' dpdx = %.2f Pa/m' % self._dpdx)
print()