Module CompAero.prandtl_meyer
This class defines the relations for the Prandtl Meyer flows
Expand source code
"""
This class defines the relations for the Prandtl Meyer flows
"""
from enum import Enum
from math import atan, degrees, nan, radians, sqrt
from scipy.optimize import brenth # type: ignore
from CompAero.greek_letters import LowerCaseGreek as lcg
from CompAero.internal import (
GammaNotDefinedError,
InvalidOptionCombinationError,
check_value,
footer,
named_header,
named_subheader,
seperator,
to_string,
)
from CompAero.oblique_shock_relations import ObliqueShockRelations
class PrandtlMeyerChoice(Enum):
"""List valid initialization options for prandtl meyer flows"""
GAMMA_MACH = "gamma, mach"
GAMMA_NU = "gamma, nu"
GAMMA_MU = "gamma, mu"
GAMMA_DEFLECTION_DWN_STRM_MACH = "gamma, deflection angle, dwn_strm_mach"
GAMMA_DEFLECTION_DWN_STRM_MU = "gamma, deflection angle, dwn_strm_mu"
GAMMA_DEFLECTION_DWN_STRM_NU = "gamma, deflection angle, dwn_strm_nu"
PRANDTL_MEYER_OPTIONS = [x.value for x in PrandtlMeyerChoice]
class PrandtlMeyer:
# pylint: disable=too-many-instance-attributes
"""
This class is a collective name space for basic calculations regarding Prandtl Meyer flows.
The constructor of this class determines the entire state of the flow from a partial state
Args:
gamma (float): Ratio of specific heats
mach (float, optional): Mach number of the flow. Defaults to nan.
nu (float, optional): Prandtl Meyer function. Defaults to nan.
mu (float, optional): Mach Wave angle. Defaults to nan.
down_stream_nu (float, optional): down stream prandtl meyer function. Defaults to nan.
down_stream_mu (float, optional): down stream mach wave angle. Defaults to nan.
down_stream_mach (float, optional): down stream mach number. Defaults to nan.
deflection_angle (float, optional): deflection angle seen by the flow. Defaults to nan.
in_degrees (bool, optional): Flags that angles passed in are in degrees. Doesnt convert
output to degrees. Defaults to True.
Raises:
GammaNotDefinedError: Raised if Gamma is undefined
InvalidOptionCombinationError: Raised if an invalid combination of parameters is given and
flow state cannot be determined
Useage:
To use this class pass gamma and one other known parameter of the flow
Valid_Combinations_of_Parameters:
1: gamma, mach\n
2: gamma, nu\n
3: gamma, mu\n
4: gamma, deflection angle, dwn_strm_mach\n
5: gamma, deflection angle, dwn_strm_mu\n
6: gamma, deflection angle, dwn_strm_nu\n
"""
def __init__(
self,
gamma: float,
mach: float = nan,
nu: float = nan,
mu: float = nan,
down_stream_nu: float = nan,
down_stream_mu: float = nan,
down_stream_mach: float = nan,
deflection_angle: float = nan,
in_degrees: bool = True,
) -> None:
# pylint: disable=too-many-arguments
# pylint: disable=too-many-statements
self.gamma = gamma
""" Ratio of specific heats """
self.mach = mach
""" Mach number of the flow """
self.nu = nu
""" The Prandtl Meyer function value """
self.mu = mu
""" The angle of the mach wave"""
self.deflection_angle = deflection_angle
""" Angle of the flow deflection angle"""
self._degrees = in_degrees
""" Angles passed to the constructor are in degrees"""
self.precision = 4
""" Precision to use when printing output to the console defaults to four """
self.down_stream_nu = down_stream_nu
""" The Prandtl Meyer function value after the expansion wave """
self.down_stream_mu = down_stream_mu
""" The angle of the mach wave after the expansion wave"""
self.down_stream_mach = down_stream_mach
""" Mach number of the flow after the expansion wave """
if not self._degrees:
self.deflection_angle = degrees(self.deflection_angle)
if not check_value(self.gamma):
raise GammaNotDefinedError()
if check_value(self.mach):
pass
elif check_value(self.nu):
self.mach = PrandtlMeyer.calc_mach_from_nu(self.nu, self.gamma)
elif check_value(self.mu):
self.mach = ObliqueShockRelations.calc_mach_from_mach_wave_angle(radians(self.mu))
elif check_value(self.deflection_angle) and check_value(self.down_stream_mach):
self.down_stream_nu = PrandtlMeyer.calc_nu(self.down_stream_mach, self.gamma)
self.nu = self.down_stream_nu - self.deflection_angle
self.mach = PrandtlMeyer.calc_mach_from_nu(self.nu, self.gamma)
elif check_value(self.deflection_angle) and check_value(self.down_stream_nu):
self.nu = self.down_stream_nu - self.deflection_angle
self.mach = PrandtlMeyer.calc_mach_from_nu(self.nu, self.gamma)
elif check_value(self.deflection_angle) and check_value(self.down_stream_mu):
self.down_stream_mach = ObliqueShockRelations.calc_mach_from_mach_wave_angle(
radians(self.down_stream_mu)
)
self.down_stream_nu = PrandtlMeyer.calc_nu(self.down_stream_mach, self.gamma)
self.nu = self.down_stream_nu - self.deflection_angle
self.mach = PrandtlMeyer.calc_mach_from_nu(self.nu, self.gamma)
else:
raise InvalidOptionCombinationError()
if check_value(self.mach) and self.mach >= 1.0:
self._calc_state()
def __str__(self) -> str:
return "".join(
[
named_header("Prandtl Relations at Mach", self.mach, self.precision),
seperator(),
to_string(lcg.gamma, self.gamma, self.precision),
to_string(lcg.nu, self.nu, self.precision, dot_line=True),
to_string(lcg.mu, self.mu, self.precision),
seperator(),
named_subheader("Downstream Conditions"),
to_string("Mach", self.down_stream_mach, self.precision),
to_string(lcg.nu, self.down_stream_nu, self.precision, dot_line=True),
to_string(lcg.mu, self.down_stream_mu, self.precision),
to_string(
f"Flow Deflection Angle [{lcg.theta}]",
self.deflection_angle,
self.precision,
dot_line=True,
),
footer(),
]
)
def _calc_state(self) -> None:
self.nu = PrandtlMeyer.calc_nu(self.mach, self.gamma)
self.mu = degrees(ObliqueShockRelations.calc_mach_wave_angle(self.mach))
if not check_value(self.deflection_angle):
return
self.down_stream_nu = self.deflection_angle + self.nu
self.down_stream_mach = PrandtlMeyer.calc_mach_from_nu(self.down_stream_nu, self.gamma)
self.down_stream_mu = degrees(
ObliqueShockRelations.calc_mach_wave_angle(self.down_stream_mach)
)
@staticmethod
def calc_nu(mach: float, gamma: float, offset: float = 0.0) -> float:
"""Calculates the prandtl meyer function value (nu)
Args:
mach (float): mach number of the the flow
gamma (float): ratio of specific heats
offset (float, optional): offset that can be used for root finding. Defaults to 0.0.
Returns:
float: nu
"""
if mach <= 1.0:
return 0.0
gp1 = gamma + 1
gm1 = gamma - 1
m_sqr_minus_1 = pow(mach, 2) - 1
return (
degrees(
sqrt(gp1 / gm1) * atan(sqrt(gm1 / gp1 * m_sqr_minus_1)) - atan(sqrt(m_sqr_minus_1))
)
- offset
)
@staticmethod
def calc_mach_from_nu(nu: float, gamma: float) -> float:
"""Calculates the mach number based on a prandtl meyer function value
Args:
nu (float): prandtl meyer function value
gamma (float): ratio of specific heats
Returns:
float: mach number
"""
if nu <= 0.0:
return 1.0
return brenth(PrandtlMeyer.calc_nu, 1 + 1e-9, 30, args=(gamma, nu)) # type: ignore
Classes
class PrandtlMeyer (gamma: float, mach: float = nan, nu: float = nan, mu: float = nan, down_stream_nu: float = nan, down_stream_mu: float = nan, down_stream_mach: float = nan, deflection_angle: float = nan, in_degrees: bool = True)
-
This class is a collective name space for basic calculations regarding Prandtl Meyer flows. The constructor of this class determines the entire state of the flow from a partial state
Args
gamma
:float
- Ratio of specific heats
mach
:float
, optional- Mach number of the flow. Defaults to nan.
nu
:float
, optional- Prandtl Meyer function. Defaults to nan.
mu
:float
, optional- Mach Wave angle. Defaults to nan.
down_stream_nu
:float
, optional- down stream prandtl meyer function. Defaults to nan.
down_stream_mu
:float
, optional- down stream mach wave angle. Defaults to nan.
down_stream_mach
:float
, optional- down stream mach number. Defaults to nan.
deflection_angle
:float
, optional- deflection angle seen by the flow. Defaults to nan.
in_degrees
:bool
, optional- Flags that angles passed in are in degrees. Doesnt convert output to degrees. Defaults to True.
Raises
GammaNotDefinedError
- Raised if Gamma is undefined
InvalidOptionCombinationError
- Raised if an invalid combination of parameters is given and flow state cannot be determined
Useage: To use this class pass gamma and one other known parameter of the flow
Valid_Combinations_Of_Parameters
1: gamma, mach
2: gamma, nu
3: gamma, mu
4: gamma, deflection angle, dwn_strm_mach
5: gamma, deflection angle, dwn_strm_mu
6: gamma, deflection angle, dwn_strm_nu
Expand source code
class PrandtlMeyer: # pylint: disable=too-many-instance-attributes """ This class is a collective name space for basic calculations regarding Prandtl Meyer flows. The constructor of this class determines the entire state of the flow from a partial state Args: gamma (float): Ratio of specific heats mach (float, optional): Mach number of the flow. Defaults to nan. nu (float, optional): Prandtl Meyer function. Defaults to nan. mu (float, optional): Mach Wave angle. Defaults to nan. down_stream_nu (float, optional): down stream prandtl meyer function. Defaults to nan. down_stream_mu (float, optional): down stream mach wave angle. Defaults to nan. down_stream_mach (float, optional): down stream mach number. Defaults to nan. deflection_angle (float, optional): deflection angle seen by the flow. Defaults to nan. in_degrees (bool, optional): Flags that angles passed in are in degrees. Doesnt convert output to degrees. Defaults to True. Raises: GammaNotDefinedError: Raised if Gamma is undefined InvalidOptionCombinationError: Raised if an invalid combination of parameters is given and flow state cannot be determined Useage: To use this class pass gamma and one other known parameter of the flow Valid_Combinations_of_Parameters: 1: gamma, mach\n 2: gamma, nu\n 3: gamma, mu\n 4: gamma, deflection angle, dwn_strm_mach\n 5: gamma, deflection angle, dwn_strm_mu\n 6: gamma, deflection angle, dwn_strm_nu\n """ def __init__( self, gamma: float, mach: float = nan, nu: float = nan, mu: float = nan, down_stream_nu: float = nan, down_stream_mu: float = nan, down_stream_mach: float = nan, deflection_angle: float = nan, in_degrees: bool = True, ) -> None: # pylint: disable=too-many-arguments # pylint: disable=too-many-statements self.gamma = gamma """ Ratio of specific heats """ self.mach = mach """ Mach number of the flow """ self.nu = nu """ The Prandtl Meyer function value """ self.mu = mu """ The angle of the mach wave""" self.deflection_angle = deflection_angle """ Angle of the flow deflection angle""" self._degrees = in_degrees """ Angles passed to the constructor are in degrees""" self.precision = 4 """ Precision to use when printing output to the console defaults to four """ self.down_stream_nu = down_stream_nu """ The Prandtl Meyer function value after the expansion wave """ self.down_stream_mu = down_stream_mu """ The angle of the mach wave after the expansion wave""" self.down_stream_mach = down_stream_mach """ Mach number of the flow after the expansion wave """ if not self._degrees: self.deflection_angle = degrees(self.deflection_angle) if not check_value(self.gamma): raise GammaNotDefinedError() if check_value(self.mach): pass elif check_value(self.nu): self.mach = PrandtlMeyer.calc_mach_from_nu(self.nu, self.gamma) elif check_value(self.mu): self.mach = ObliqueShockRelations.calc_mach_from_mach_wave_angle(radians(self.mu)) elif check_value(self.deflection_angle) and check_value(self.down_stream_mach): self.down_stream_nu = PrandtlMeyer.calc_nu(self.down_stream_mach, self.gamma) self.nu = self.down_stream_nu - self.deflection_angle self.mach = PrandtlMeyer.calc_mach_from_nu(self.nu, self.gamma) elif check_value(self.deflection_angle) and check_value(self.down_stream_nu): self.nu = self.down_stream_nu - self.deflection_angle self.mach = PrandtlMeyer.calc_mach_from_nu(self.nu, self.gamma) elif check_value(self.deflection_angle) and check_value(self.down_stream_mu): self.down_stream_mach = ObliqueShockRelations.calc_mach_from_mach_wave_angle( radians(self.down_stream_mu) ) self.down_stream_nu = PrandtlMeyer.calc_nu(self.down_stream_mach, self.gamma) self.nu = self.down_stream_nu - self.deflection_angle self.mach = PrandtlMeyer.calc_mach_from_nu(self.nu, self.gamma) else: raise InvalidOptionCombinationError() if check_value(self.mach) and self.mach >= 1.0: self._calc_state() def __str__(self) -> str: return "".join( [ named_header("Prandtl Relations at Mach", self.mach, self.precision), seperator(), to_string(lcg.gamma, self.gamma, self.precision), to_string(lcg.nu, self.nu, self.precision, dot_line=True), to_string(lcg.mu, self.mu, self.precision), seperator(), named_subheader("Downstream Conditions"), to_string("Mach", self.down_stream_mach, self.precision), to_string(lcg.nu, self.down_stream_nu, self.precision, dot_line=True), to_string(lcg.mu, self.down_stream_mu, self.precision), to_string( f"Flow Deflection Angle [{lcg.theta}]", self.deflection_angle, self.precision, dot_line=True, ), footer(), ] ) def _calc_state(self) -> None: self.nu = PrandtlMeyer.calc_nu(self.mach, self.gamma) self.mu = degrees(ObliqueShockRelations.calc_mach_wave_angle(self.mach)) if not check_value(self.deflection_angle): return self.down_stream_nu = self.deflection_angle + self.nu self.down_stream_mach = PrandtlMeyer.calc_mach_from_nu(self.down_stream_nu, self.gamma) self.down_stream_mu = degrees( ObliqueShockRelations.calc_mach_wave_angle(self.down_stream_mach) ) @staticmethod def calc_nu(mach: float, gamma: float, offset: float = 0.0) -> float: """Calculates the prandtl meyer function value (nu) Args: mach (float): mach number of the the flow gamma (float): ratio of specific heats offset (float, optional): offset that can be used for root finding. Defaults to 0.0. Returns: float: nu """ if mach <= 1.0: return 0.0 gp1 = gamma + 1 gm1 = gamma - 1 m_sqr_minus_1 = pow(mach, 2) - 1 return ( degrees( sqrt(gp1 / gm1) * atan(sqrt(gm1 / gp1 * m_sqr_minus_1)) - atan(sqrt(m_sqr_minus_1)) ) - offset ) @staticmethod def calc_mach_from_nu(nu: float, gamma: float) -> float: """Calculates the mach number based on a prandtl meyer function value Args: nu (float): prandtl meyer function value gamma (float): ratio of specific heats Returns: float: mach number """ if nu <= 0.0: return 1.0 return brenth(PrandtlMeyer.calc_nu, 1 + 1e-9, 30, args=(gamma, nu)) # type: ignore
Static methods
def calc_mach_from_nu(nu: float, gamma: float) ‑> float
-
Calculates the mach number based on a prandtl meyer function value
Args
nu
:float
- prandtl meyer function value
gamma
:float
- ratio of specific heats
Returns
float
- mach number
Expand source code
@staticmethod def calc_mach_from_nu(nu: float, gamma: float) -> float: """Calculates the mach number based on a prandtl meyer function value Args: nu (float): prandtl meyer function value gamma (float): ratio of specific heats Returns: float: mach number """ if nu <= 0.0: return 1.0 return brenth(PrandtlMeyer.calc_nu, 1 + 1e-9, 30, args=(gamma, nu)) # type: ignore
def calc_nu(mach: float, gamma: float, offset: float = 0.0) ‑> float
-
Calculates the prandtl meyer function value (nu)
Args
mach
:float
- mach number of the the flow
gamma
:float
- ratio of specific heats
offset
:float
, optional- offset that can be used for root finding. Defaults to 0.0.
Returns
float
- nu
Expand source code
@staticmethod def calc_nu(mach: float, gamma: float, offset: float = 0.0) -> float: """Calculates the prandtl meyer function value (nu) Args: mach (float): mach number of the the flow gamma (float): ratio of specific heats offset (float, optional): offset that can be used for root finding. Defaults to 0.0. Returns: float: nu """ if mach <= 1.0: return 0.0 gp1 = gamma + 1 gm1 = gamma - 1 m_sqr_minus_1 = pow(mach, 2) - 1 return ( degrees( sqrt(gp1 / gm1) * atan(sqrt(gm1 / gp1 * m_sqr_minus_1)) - atan(sqrt(m_sqr_minus_1)) ) - offset )
Instance variables
var deflection_angle
-
Angle of the flow deflection angle
var down_stream_mach
-
Mach number of the flow after the expansion wave
var down_stream_mu
-
The angle of the mach wave after the expansion wave
var down_stream_nu
-
The Prandtl Meyer function value after the expansion wave
var gamma
-
Ratio of specific heats
var mach
-
Mach number of the flow
var mu
-
The angle of the mach wave
var nu
-
The Prandtl Meyer function value
var precision
-
Precision to use when printing output to the console defaults to four
class PrandtlMeyerChoice (*args, **kwds)
-
List valid initialization options for prandtl meyer flows
Expand source code
class PrandtlMeyerChoice(Enum): """List valid initialization options for prandtl meyer flows""" GAMMA_MACH = "gamma, mach" GAMMA_NU = "gamma, nu" GAMMA_MU = "gamma, mu" GAMMA_DEFLECTION_DWN_STRM_MACH = "gamma, deflection angle, dwn_strm_mach" GAMMA_DEFLECTION_DWN_STRM_MU = "gamma, deflection angle, dwn_strm_mu" GAMMA_DEFLECTION_DWN_STRM_NU = "gamma, deflection angle, dwn_strm_nu"
Ancestors
- enum.Enum
Class variables
var GAMMA_DEFLECTION_DWN_STRM_MACH
var GAMMA_DEFLECTION_DWN_STRM_MU
var GAMMA_DEFLECTION_DWN_STRM_NU
var GAMMA_MACH
var GAMMA_MU
var GAMMA_NU