Source code for g3d.calc.calculators.moving_shock

"""Moving shock wave calculator"""
import os
from typing import Union, Any

if os.environ.get('__USE_CUDA', '0') == '1':
    import cupy as np
else:
    import numpy as np

from .calculator import G3DCalculator

from g3d.defs import CFlowVariableType

from .normal_shock import G3DNormalShockCalculator


[docs] class G3DMovingShockCalculator(G3DCalculator): """Class collecting functions related to moving shock waves""" def __init__(self, *args: Any, **kwargs: Any) -> None: """Initialize calculator parameters""" super().__init__(*args, **kwargs) self.__normal_shock = G3DNormalShockCalculator(update_code_type=False) def _set_default(self) -> None: super()._set_default() self.__Ms = self._vars.add(name="Ms", long_name="Mach number of incident shock wave") self.__Mr = self._vars.add(name="Mr", long_name="Mach number of reflected shock wave") self.__Up = self._vars.add(name="Up", long_name="Induced flow velocity", type=CFlowVariableType.VELOCITY) self.__PR21 = self._vars.add(name="PR21", long_name="Pressure ratio P2/P1") self.__PR51 = self._vars.add(name="PR51", long_name="Pressure ratio P5/P1") self.__TR51 = self._vars.add(name="TR51", long_name="Temperature ratio T5/T1") self.__T1 = self._vars.add(name="T1", long_name="Temperature (region 1)", type=CFlowVariableType.TEMPERATURE) def _associate(self) -> None: super()._associate() self.__normal_shock.gas = self._gas
[docs] def get_Ms(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """ calculates incident shock Mach number (Ms []) corresponding to specified shock pressure ratio (PR21 []) input: shock pressure ratio (PR21 []) example: Ms = get_Ms(PR21=PR21) """ return self._eval(["PR21"], self.__get_Ms, *args, **kwargs)
def __get_Ms(self, PR21: float = None) -> float: if PR21 is None: PR21 = self.__PR21.value return np.sqrt((self._gas.gp1 / (2. * self._gas.gamma)) * (PR21 - 1.) + 1.)
[docs] def get_up(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """ calculates induced flow velocity (Up [m/s], velocity behind incident shock) corresponding to specified shock pressure ratio (PR21 []) and temperature in front of incident shock (T1 [K]) input: shock pressure ratio (PR21 []), temperature in front of incident shock (T1 [K]) example: Up = get_up(PR21=PR21, T1=T1) """ return self._eval(["PR21", "T1"], self.__get_up, *args, **kwargs)
def __get_up(self, PR21: float = None, T1: float = None) -> float: if PR21 is None: PR21 = self.__PR21.value if T1 is None: T1 = self.__T1.value return ((self._gas.get_speed_of_sound(T1) / self._gas.gamma) * (PR21 - 1.) * np.sqrt((2. * self._gas.gamma / self._gas.gp1) / (PR21 + self._gas.gm1 / self._gas.gp1)))
[docs] def get_temperature_ratio(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """ calculates shock temperature ratio (TR21 []) corresponding to specified shock pressure ratio (PR21 []) input: shock pressure ratio (PR21 []) example TR21 = get_temperature_ratio(PR21=PR21) """ return self._eval(["PR21"], self.__get_temperature_ratio, *args, **kwargs)
def __get_temperature_ratio(self, PR21: float = None) -> float: if PR21 is None: PR21 = self.__PR21.value return PR21 * (((self._gas.gp1 / self._gas.gm1) + PR21) / (1. + (self._gas.gp1 / self._gas.gm1) * PR21))
[docs] def get_density_ratio(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """ calculates shock density ratio (RR21 []) corresponding to specified shock pressure ratio (PR21 []) input: shock pressure ratio (PR21 []) example RR21 = get_density_ratio(PR21=PR21) """ return self._eval(["PR21"], self.__get_density_ratio, *args, **kwargs)
def __get_density_ratio(self, PR21: float = None) -> float: if PR21 is None: PR21 = self.__PR21.value return (1. + (self._gas.gp1 / self._gas.gm1) * PR21) / ((self._gas.gp1 / self._gas.gm1) + PR21)
[docs] def get_Mr(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """ calculates reflected shock Mach number (Mr []) corresponding to specified incident shock Mach number (Ms []) input: incident shock Mach number (Ms []) example: Mr = get_Mr(Ms=Ms) """ return self._eval(["Ms"], self.__get_Mr, *args, **kwargs)
def __get_Mr(self, Ms: float = None) -> float: if Ms is None: Ms = self.__Ms.value a = (Ms / (Ms * Ms - 1.)) * np.sqrt(1. + (2. * self._gas.gm1 * (Ms * Ms - 1.) * (self._gas.gamma + (1. / (Ms * Ms))) / (self._gas.gp1 * self._gas.gp1))) b = (1. / (2. * a)) return b + np.sqrt(b * b + 1.)
[docs] def get_Mr_from_PR21(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """ calculates reflected shock Mach number (Mr []) corresponding to specified incident shock pressure ratio (PR21 []) input: incident shock Mach number (Ms []) example: Mr = get_Mr_from_PR21(PR21=PR21) """ return self._eval(["PR21"], self.__get_Mr_from_PR21, *args, **kwargs)
def __get_Mr_from_PR21(self, PR21: float = None) -> float: if PR21 is None: PR21 = self.__PR21.value return self.__get_Mr(self.__get_Ms(PR21))
[docs] def get_PR51_from_PR21(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """ calculates ratio of pressure behind reflected shock (P5) and pressure in the undisturbed flow ahead of the incident shock (P1) (PR51 []) from specified incident shock pressure ratio (PR21 []) input: incident shock pressure ratio (PR21 []) example: PR51 = get_PR51_from_PR21(PR21=PR21) """ return self._eval(["PR21"], self.__get_PR51_from_PR21, *args, **kwargs)
def __get_PR51_from_PR21(self, PR21: float = None) -> float: if PR21 is None: PR21 = self.__PR21.value return PR21 * self.__normal_shock.get_downstream_pressure(self.get_Mr_from_PR21(PR21))
[docs] def get_TR51_from_PR21(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """ calculates ratio of temperature behind reflected shock (T5) and temperature in the undisturbed flow ahead of the incident shock (T1) (TR51 []) from specified incident shock pressure ratio (PR21 []) input: incident shock pressure ratio (PR21 []) example: TR51 = get_TR51_from_PR21(PR21=PR21) """ return self._eval(["PR21"], self.__get_TR51_from_PR21, *args, **kwargs)
def __get_TR51_from_PR21(self, PR21: float = None) -> float: if PR21 is None: PR21 = self.__PR21.value return self.__get_temperature_ratio(PR21) * \ self.__normal_shock.get_downstream_temperature(self.__get_Mr_from_PR21(PR21))
[docs] def find_PR21_from_Ms(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """ .. deprecated:: 2.6 redirects to :func:`get_PR21_from_Ms` """ return self.get_PR21_from_Ms(*args, **kwargs)
[docs] def get_PR21_from_Ms(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """ calculates pressure ratio of incident shock (PR21 []) from shock Mach number (Ms []) input: incident shock Mach number (Ms []) example PR21 = get_PR21_from_Ms(Ms=Ms) """ return self._eval(["Ms"], self.__get_PR21_from_Ms, *args, **kwargs)
def __get_PR21_from_Ms(self, Ms: float = None) -> float: if Ms is None: Ms = self.__Ms.value return ((Ms ** 2 - 1.0) * 2.0 * self._gas.gamma / self._gas.gp1) + 1.0
[docs] def find_PR21_from_Mr(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """ .. deprecated:: 2.6 redirects to :func:`get_PR21_from_Mr` """ return self.get_PR21_from_Mr(*args, **kwargs)
[docs] def get_PR21_from_Mr(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """ calculates pressure ratio of incident shock (PR21 []) from reflected shock Mach number (Mr []) the pressure ratio is calculated using the built-in Newton-Raphson solver input: reflected shock Mach number (Mr []) example PR21 = get_PR21_from_Mr(Mr=Mr) """ self._newton.reset() return self._eval(["Mr"], self.__get_PR21_from_Mr, *args, **kwargs)
def __get_PR21_from_Mr(self, Mr: float = None) -> float: if Mr is None: Mr = self.__Mr.value newton = self._get_newton_kernel() newton.target_value = Mr newton.start_value = 1.5 # run Newton solver to find deflection angle return newton.solve(self.__get_Mr_from_PR21)
[docs] def find_PR21_from_up(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """ .. deprecated:: 2.6 redirects to :func:`get_PR21_from_up` """ return self.get_PR21_from_up(*args, **kwargs)
[docs] def get_PR21_from_up(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """ calculates pressure ratio of incident shock (PR21 []) from induced flow velocity (Up [m/s]) the pressure ratio is calculated using the built-in Newton-Raphson solver input: induced flow velocity (Up [m/s]), temperature of the undisturbed flow ahead of the incident shock (T1 [K]) example PR21 = get_PR21_from_up(Up=Up, T1=T1) """ self._newton.reset() return self._eval(["Up", "T1"], self.__get_PR21_from_up, *args, **kwargs)
def __get_PR21_from_up(self, Up: float = None, T1: float = None) -> float: if Up is None: Up = self.__Up.value if T1 is not None: self.__T1.value = T1 newton = self._get_newton_kernel() newton.target_value = Up newton.start_value = 1.5 # run Newton solver to find deflection angle return newton.solve(self.__get_up)
[docs] def find_PR21_from_PR51(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """ .. deprecated:: 2.6 redirects to :func:`get_PR21_from_PR51` """ return self.get_PR21_from_PR51(*args, **kwargs)
[docs] def get_PR21_from_PR51(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """ calculates pressure ratio of incident shock (PR21 []) from the ratio of pressure behind the reflected shock (P5) and the pressure in the undisturbed flow ahead of the incident shock (P1) (PR51 []) the pressure ratio is calculated using the built-in Newton-Raphson solver input: reflected shock to undisturbed flow pressure ratio (PR51 []) example PR21 = get_PR21_from_PR51(PR51=PR51) """ self._newton.reset() return self._eval(["PR51"], self.__get_PR21_from_PR51, *args, **kwargs)
def __get_PR21_from_PR51(self, PR51: float = None) -> float: if PR51 is None: PR51 = self.__PR51.value newton = self._get_newton_kernel() newton.target_value = PR51 newton.start_value = 1.5 # run Newton solver to find deflection angle return newton.solve(self.__get_PR51_from_PR21)
[docs] def find_PR21_from_TR51(self, *args: Any, **kwargs: Any) -> Union[np.float64, list[np.float64], float]: """ .. deprecated:: 2.6 redirects to :func:`get_PR21_from_TR51` """ return self.get_PR21_from_TR51(*args, **kwargs)
[docs] def get_PR21_from_TR51(self, *args: Any, **kwargs: Any) -> Union[np.float64, list[np.float64], float]: """ calculates pressure ratio of incident shock (PR21 []) from the ratio of temperature behind the reflected shock (T5) and the temperature in the undisturbed flow ahead of the incident shock (T1) (TR51 []) the pressure ratio is calculated using the built-in Newton-Raphson solver input: reflected shock to undisturbed flow temperature ratio (TR51 []) example PR21 = get_PR21_from_TR51(TR51=TR51) """ self._newton.reset() return self._eval(["TR51"], self.__get_PR21_from_TR51, *args, **kwargs)
def __get_PR21_from_TR51(self, TR51: float = None) -> float: if TR51 is None: TR51 = self.__TR51.value newton = self._get_newton_kernel() newton.target_value = TR51 newton.start_value = 1.5 # run Newton solver to find deflection angle return newton.solve(self.__get_TR51_from_PR21)