Coverage for /opt/hostedtoolcache/Python/3.11.10/x64/lib/python3.11/site-packages/pysagas/flow.py: 80%
74 statements
« prev ^ index » next coverage.py v7.6.4, created at 2024-10-30 04:27 +0000
« prev ^ index » next coverage.py v7.6.4, created at 2024-10-30 04:27 +0000
1import numpy as np
2from pysagas.geometry import Vector
5class GasState:
6 """An ideal gas state defined by Mach number, pressure and
7 temperature.
8 """
10 gamma = 1.4
11 R = 287 # J/kg·K.3
13 def __init__(
14 self, mach: float, pressure: float, temperature: float, gamma: float = 1.4
15 ) -> None:
16 """Define a new gas state.
18 Parameters
19 -----------
20 mach : float
21 The flow Mach number.
23 pressure : float
24 The flow pressure (Pa).
26 temperature : float
27 The flow temperature (K).
29 gamma : float, optional
30 The ratio of specific heats. The default is 1.4.
31 """
32 # Assign properties
33 self._T = temperature
34 self._P = pressure
35 self._M = mach
36 self._gamma = gamma
38 def __str__(self) -> str:
39 return f"Mach {self.M} flow condition with P = {self.P}, T = {self.T}."
41 def __repr__(self) -> str:
42 return f"Flow(M={self.M}, P={self.P}, T={self.T})"
44 def __eq__(self, other: object) -> bool:
45 if not isinstance(other, GasState):
46 raise Exception(f"Cannot compare {type(other)} to GasState.")
47 return (
48 (self._T == other._T)
49 & (self._P == other._P)
50 & (self._M == other._M)
51 & (self._gamma == other._gamma)
52 )
54 @property
55 def T(self):
56 return self._T
58 @property
59 def P(self):
60 return self._P
62 @property
63 def M(self):
64 return self._M
66 @property
67 def a(self):
68 return (self.gamma * self.R * self.T) ** 0.5
70 @property
71 def rho(self):
72 return self.P / (self.R * self.T)
74 @property
75 def v(self):
76 return self.M * self.a
78 @property
79 def q(self):
80 return 0.5 * self.rho * self.v**2
82 @property
83 def gamma(self):
84 return self._gamma
87class FlowState(GasState):
88 """An ideal gas state defined by Mach number, pressure and
89 temperature, with a flow direction.
90 """
92 def __init__(
93 self,
94 mach: float,
95 pressure: float,
96 temperature: float,
97 direction: Vector = None,
98 aoa: float = 0.0,
99 gamma: float = 1.4,
100 ) -> None:
101 """Define a new flow state.
103 Parameters
104 -----------
105 mach : float
106 The flow Mach number.
108 pressure : float
109 The flow pressure (Pa).
111 temperature : float
112 The flow temperature (K).
114 direction : Vector, optional
115 The direction vector of the flow. The default is Vector(1,0,0).
117 aoa : float, optional
118 The angle of attack of the flow. The default is 0.0 (specified in
119 degrees).
121 gamma : float, optional
122 The ratio of specific heats. The default is 1.4.
123 """
124 super().__init__(mach, pressure, temperature, gamma)
125 if direction:
126 # Use direction provided
127 self.direction = direction.unit
128 else:
129 # Use AoA to calculate direction
130 self.direction = Vector(1, 1 * np.tan(np.deg2rad(aoa)), 0).unit
132 def __eq__(self, other: object) -> bool:
133 if not isinstance(other, FlowState):
134 raise Exception(f"Cannot compare {type(other)} to FlowState.")
135 same_gs = super().__eq__(other)
136 return same_gs & (self.direction == other.direction)
138 @property
139 def vx(self):
140 return self.Vector.x
142 @property
143 def vy(self):
144 return self.Vector.y
146 @property
147 def vz(self):
148 return self.Vector.z
150 @property
151 def vec(self):
152 return self.Vector.vec
154 @property
155 def Vector(self) -> Vector:
156 return self.direction * self.v
158 @property
159 def aoa(self):
160 aoa = np.rad2deg(np.arctan(self.vec[1] / self.vec[0]))
161 return round(aoa, 6)
164if __name__ == "__main__":
165 flow = FlowState(6, 700, 70)