"""Finite non-linear wave calculator (moving expansion regions)"""
import os
from typing import Any, Union
if os.environ.get('__USE_CUDA', '0') == '1':
import cupy as np
else:
import numpy as np
from g3d.defs import CFlowVariableType
from .calculator import G3DCalculator
[docs]
class G3DMovingExpansionCalculator(G3DCalculator):
"""Class collecting functions related to moving expansion regions"""
def __init__(self, *args: Any, **kwargs: Any) -> None:
"""Initialize calculator parameters"""
super().__init__(*args, **kwargs)
def _set_default(self) -> None:
super()._set_default()
self.__U = self._vars.add(name="U", long_name="Local flow velocity", type=CFlowVariableType.VELOCITY)
self.__P = self._vars.add(name="P", long_name="Pressure", type=CFlowVariableType.PRESSURE)
self.__T = self._vars.add(name="T", long_name="Temperature", type=CFlowVariableType.TEMPERATURE)
self.__RO = self._vars.add(name="RO", long_name="Density", type=CFlowVariableType.DENSITY)
self.__C = self._vars.add(name="C", long_name="Speed of sound", type=CFlowVariableType.VELOCITY)
self.__P4 = self._vars.add(name="P4", long_name="Pressure (region 4)", type=CFlowVariableType.PRESSURE)
self.__T4 = self._vars.add(name="T4", long_name="Temperature (region 4)", type=CFlowVariableType.TEMPERATURE)
self.__RO4 = self._vars.add(name="RO4", long_name="Density (region 4)", type=CFlowVariableType.DENSITY)
self.__C4 = self._vars.add(name="C4", long_name="Speed of sound (region 4)", type=CFlowVariableType.VELOCITY)
def __expansion_factor(self, U: float = None, T4: float = None) -> float:
if U is None:
U = self.__U.value
if T4 is None:
T4 = self.__T4.value
return 1. - (self._gas.gm1 / 2.) * (U / self._gas.get_speed_of_sound(T4))
[docs]
def get_pressure(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]:
"""
calculates pressure for a location inside a moving expansion region (P [Pa])
from local velocity (U [m/s]), temperature ahead of expansion region (T4 [K]),
pressure ahead of expansion wave (P4 [Pa])
input: local flow velocity (U [m/s]), temperature ahead of expansion region (T4 [K]),
pressure ahead of expansion wave (P4 [Pa])
example P = get_pressure(U=U, T4=T4, P4=P4)
"""
return self._eval(["U", "T4", "P4"], self.__get_pressure, *args, **kwargs)
def __get_pressure(self, U: float = None, T4: float = None, P4: float = None) -> float:
if U is None:
U = self.__U.value
if T4 is None:
T4 = self.__T4.value
if P4 is None:
P4 = self.__P4.value
return P4 * np.power(self.__expansion_factor(U, T4), (2. * self._gas.gamma / self._gas.gm1))
[docs]
def get_density(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]:
"""
calculates density for a location inside a moving expansion region (RO [kg/m^3])
from local velocity (U [m/s]), temperature ahead of expansion region (T4 [K]),
density ahead of expansion wave (RO4 [kg/m^3])
input: local flow velocity (U [m/s]), temperature ahead of expansion region (T4 [K]),
density ahead of expansion wave (RO4 [kg/m^3])
example RO = get_density(U=U, T4=T4, RO4=RO4)
"""
return self._eval(["U", "T4", "RO4"], self.__get_density, *args, **kwargs)
def __get_density(self, U: float = None, T4: float = None, RO4: float = None) -> float:
if U is None:
U = self.__U.value
if T4 is None:
T4 = self.__T4.value
if RO4 is None:
RO4 = self.__RO4.value
return RO4 * np.power(self.__expansion_factor(U, T4), (2. / self._gas.gm1))
[docs]
def get_temperature(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]:
"""
calculates temperature for a location inside a moving expansion region (P [Pa])
from local velocity (U [m/s]) and temperature ahead of expansion region (T4 [K])
input: local flow velocity (U [m/s]), temperature ahead of expansion region (T4 [K])
example T = get_temperature(U=U, T4=T4)
"""
return self._eval(["U", "T4"], self.__get_temperature, *args, **kwargs)
def __get_temperature(self, U: float = None, T4: float = None) -> float:
if U is None:
U = self.__U.value
if T4 is None:
T4 = self.__T4.value
return T4 * np.power(self.__expansion_factor(U, T4), 2)
[docs]
def get_speed_of_sound(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]:
"""
calculates speed of sound for a location inside a moving expansion region (C [m/s])
from local velocity (U [m/s]) and temperature ahead of expansion region (T4 [K])
input: local flow velocity (U [m/s]), temperature ahead of expansion region (T4 [K])
example C = get_speed_of_sound(U=U, T4=T4)
"""
return self._eval(["U", "T4"], self.__get_speed_of_sound, *args, **kwargs)
def __get_speed_of_sound(self, U: float = None, T4: float = None) -> float:
if U is None:
U = self.__U.value
if T4 is None:
T4 = self.__T4.value
return self._gas.get_speed_of_sound(T4) * self.__expansion_factor(U, T4)
[docs]
def get_U_from_pressure_ratio(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]:
"""
calculates local flow velocity for a location inside a moving expansion region (U [m/s]) from
local pressure (P [Pa]), pressure head of expansion region (P4 [Pa]),
and temperature ahead of expansion region (T4 [K])
input: local pressure (P [Pa]), pressure head of expansion region (P4 [Pa]),
temperature ahead of expansion region (T4 [K])
example U = get_U_from_pressure_ratio(P=P, P4=P4, T4=T4)
"""
return self._eval(["P", "P4", "T4"], self.__get_U_from_pressure_ratio, *args, **kwargs)
def __get_U_from_pressure_ratio(self, P: float = None, P4: float = None, T4: float = None) -> float:
if P is None:
P = self.__P.value
if P4 is None:
P4 = self.__P4.value
if T4 is None:
T4 = self.__T4.value
return ((2. * self._gas.get_speed_of_sound(T4) / self._gas.gm1)
* (1. - np.power((P / P4), (self._gas.gm1 / (2. * self._gas.gamma)))))
[docs]
def get_U_from_temperature_ratio(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]:
"""
calculates local flow velocity for a location inside a moving expansion region (U [m/s])
from local temperature (T [K]), and temperature ahead of expansion region (T4 [K])
input: local temperature (T [K]), temperature ahead of expansion region (T4 [K])
example U = get_U_from_temperature_ratio(T=T, T4=T4)
"""
return self._eval(["T", "T4"], self.__get_U_from_temperature_ratio, *args, **kwargs)
def __get_U_from_temperature_ratio(self, T: float = None, T4: float = None) -> float:
if T is None:
T = self.__T.value
if T4 is None:
T4 = self.__T4.value
return (2. * self._gas.get_speed_of_sound(T4) / self._gas.gm1) * (1. - np.sqrt(T / T4))
[docs]
def get_U_from_density_ratio(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]:
"""
calculates local flow velocity for a location inside a moving expansion region (U [m/s])
from local density (RO [kg/m^3]), density ahead of expansion region (RO4 [kg/m^3]),
and temperature ahead of expansion region (T4 [K])
input: local density (RO [kg/m^3]), density ahead of expansion region (RO4 [kg/m^3]),
temperature ahead of expansion region (T4 [K])
example U = get_U_from_density_ratio(RO=RO, RO4=RO4, T4=T4)
"""
return self._eval(["RO", "RO4", "T4"], self.__get_U_from_density_ratio, *args, **kwargs)
def __get_U_from_density_ratio(self, RO: float = None, RO4: float = None, T4: float = None) -> float:
if RO is None:
RO = self.__RO.value
if RO4 is None:
RO4 = self.__RO4.value
if T4 is None:
T4 = self.__T4.value
return ((2. * self._gas.get_speed_of_sound(T4) / self._gas.gm1) *
(1. - np.power((RO / RO4), (self._gas.gm1 / 2.))))
[docs]
def get_U_from_C_ratio(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]:
"""
calculates local flow velocity for a location inside a moving expansion region (U [m/s]) from local
speed of sound (C [m/s]) and speed of sound ahead of expansion region (RO4 [kg/m^3])
input: local speed of sound (C [m/s]), speed of sound ahead of expansion region (C4 [m/s]),
temperature ahead of expansion region (T4 [K])
example U = get_U_from_C_ratio(C=C, C4=C4)
"""
return self._eval(["C", "C4"], self.__get_U_from_C_ratio, *args, **kwargs)
def __get_U_from_C_ratio(self, C: float = None, C4: float = None) -> float:
if C is None:
C = self.__C.value
if C4 is None:
C4 = self.__C4.value
return (2. * C4 / self._gas.gm1) * (1. - (C / C4))