Source code for g3d.calc.calculators.expansion_wave

"""Expansion wave calculator"""
import os

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

from typing import Tuple, Union, Any

from .calculator import G3DCalculator

from g3d.defs import CFlowVariableType
from g3d.defs import AngleType


[docs] class G3DExpansionWaveCalculator(G3DCalculator): """Class collecting functions related to Prandtl-Meyer expansions""" def __init__(self, *args: Any, **kwargs: Any) -> None: """Initialize calculator parameters""" super().__init__(*args, **kwargs) def _set_default(self) -> None: super()._set_default() self.__M = self._vars.add(name="M", long_name="Mach number") self.__M1 = self._vars.add(name="M1", long_name="Mach number") self.__theta = self._vars.add(name="theta", long_name="Flow deflection angle", type=CFlowVariableType.RADIANS)
[docs] def get_Prandtl_Meyer_function(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """Evaluates Prandtl-Meyer function for specified Mach number the value calculated is given in radians unless angle_type=AngleType.DEGREES is specified input: Mach number (M []) supported data types: float, list[float], ndarray Parameters ---------- *args : Any arguments (optional input): Mach number value(s) **kwargs : Any keyword-value pairs (optional input): valid keywords: 'M', 'angle_type' Returns ------- float, ndarray Prandtl-Meyer function value (nu) [rad or deg] Examples -------- Basic usage: $_>>> from g3d import cflow $_>>> nu = cflow.expansion.get_Prandtl_Meyer_function(M=2.5, angle_type=AngleType.DEGREES) """ return self._eval(["M"], self.__get_Prandtl_Meyer_function, *args, **kwargs)
def __get_Prandtl_Meyer_function(self, M: float = None) -> float: if M is None: M = self.__M.value return (np.sqrt(self._gas.gp1 / self._gas.gm1) * np.arctan(np.sqrt((self._gas.gm1 / self._gas.gp1) * (M * M - 1.))) - np.arctan(np.sqrt(M * M - 1.)))
[docs] def find_Mach(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """ .. deprecated:: 2.6 redirects to :func:`get_Mach` """ return self.get_Mach(*args, **kwargs)
[docs] def get_Mach(self, *args: Any, **kwargs: Any) -> Union[Union[tuple[Any, ...], list[Any]], Any]: """Finds Mach number corresponding to specified Prandtl-Meyer function value using the built-in Newton-Raphson solver the Prandtl-Meyer function value should be specified in radians unless angle_type=AngleType.DEGREES is specified input: Prandtl-Meyer value (theta [rad or deg]) supported data types: float, list[float], ndarray Parameters ---------- *args : Any arguments (optional input): Prandtl-Meyer [rad or deg] value(s) **kwargs : Any keyword-value pairs (optional input): valid keywords: 'theta', 'angle_type' Returns ------- float, ndarray Mach number Examples -------- Basic usage: $_>>> from g3d import cflow $_>>> M = cflow.expansion.get_Mach(theta=10., angle_type=AngleType.DEGREES) """ self._newton.reset() return self._eval(["theta"], self.__get_Mach, *args, **kwargs)
def __get_Mach(self, theta: float = None, angle_type: Any = AngleType.UNDEFINED) -> float: if theta is None: theta = self.__theta.value theta = self._angle_import(theta, angle_type=angle_type) newton = self._get_newton_kernel() newton.start_value = 1.5 newton.target_value = theta # run Newton solver to find deflection angle return newton.solve(self.__get_Prandtl_Meyer_function)
[docs] def analyze_expansion_region(self, *args: Any, **kwargs: Any) \ -> Union[Tuple[np.float64, ...], list[Tuple[np.float64, ...]]]: """Calculate pressure ratio (PR21 []), temperature ratio (TR21 []), and downstream Mach number (M2 []) for specified upstream Mach number (M1 []) and flow deflection (theta) flow deflection should be given in radians unless angle_type=AngleType.DEGREES is specified input: upstream Mach number (M1 []) and flow deflection (theta [rad or deg]) supported data types: float, list[float], ndarray Parameters ---------- *args : Any arguments (optional input): 1. upstream Mach number 2. flow deflection [rad or deg] variable value(s) in above-listed order **kwargs : Any keyword-value pairs (optional input): valid keywords: 'M1', 'theta', 'angle_type' Returns ------- tuple[float], tuple[ndarray] flow expansion properties: downstream Mach number, pressure ratio, temperature ratio Examples -------- Basic usage: $_>>> from g3d import cflow $_>>> M2, PR21, TR21 = cflow.expansion.analyze_expansion_region(M1=2.5, theta=10., angle_type=AngleType.DEGREES) """ self._reset_eval(outdim=3) return self._eval(["M1", "theta"], self.__analyze_expansion_region, *args, **kwargs)
def __analyze_expansion_region(self, M1: float = None, theta: float = None, angle_type: Any = AngleType.UNDEFINED) -> tuple[float, float, float]: if M1 is None: M1 = self.__M1.value if theta is None: theta = self.__theta.value self.__M.value = M1 theta = self._angle_import(theta, angle_type=angle_type) nu1 = self.__get_Prandtl_Meyer_function(M1) nu2 = nu1 + theta M2 = self.__get_Mach(nu2, AngleType.RADIANS) PR21 = self._stagnation.get_total_pressure(M1, 1.) / self._stagnation.get_total_pressure(M2, 1.) TR21 = self._stagnation.get_total_temperature(M1, 1.) / self._stagnation.get_total_temperature(M2, 1.) return M2, PR21, TR21