turbo-design 1.0.10__py3-none-any.whl → 1.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of turbo-design might be problematic. Click here for more details.
- {turbo_design-1.0.10.dist-info → turbo_design-1.1.0.dist-info}/METADATA +3 -2
- {turbo_design-1.0.10.dist-info → turbo_design-1.1.0.dist-info}/RECORD +9 -9
- {turbo_design-1.0.10.dist-info → turbo_design-1.1.0.dist-info}/WHEEL +1 -1
- turbodesign/bladerow.py +5 -2
- turbodesign/passage.py +49 -12
- turbodesign/radeq.py +6 -4
- turbodesign/spool.py +11 -3
- turbodesign/td_math.py +24 -20
- turbodesign/turbinespool.py +23 -21
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: turbo-design
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: TurboDesign is a library used to design turbines and compressors using radial equilibrium.
|
|
5
5
|
Author: Paht Juangphanich
|
|
6
6
|
Author-email: paht.juangphanich@nasa.gov
|
|
@@ -10,6 +10,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.10
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
14
|
Requires-Dist: cantera
|
|
14
15
|
Requires-Dist: findiff
|
|
15
16
|
Requires-Dist: matplotlib
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
turbodesign/__init__.py,sha256=N8Nu0I1vrlEHYJZZ7yhhg-FtbNbLyrgjy7hoicygUqg,325
|
|
2
2
|
turbodesign/arrayfuncs.py,sha256=GHIlTyLfeNsNCQQoh5m1aXK3iyvU6RjdYQipkqpU_ps,519
|
|
3
|
-
turbodesign/bladerow.py,sha256
|
|
3
|
+
turbodesign/bladerow.py,sha256=-Oym4HhX9Wx6i6Nv7Krb6xdZWSxLiEVMb7xg2K5rR0w,24239
|
|
4
4
|
turbodesign/cantera_gas/co2.yaml,sha256=M2o_RzxV9B9rDkgkXJC-l3voKraFZguTZuKKt4F7S_c,887
|
|
5
5
|
turbodesign/compressorspool.py,sha256=z8ZVczJ-EdZvIqqZArC6UdwC5MbU2SZh_MT2CGq5avY,2600
|
|
6
6
|
turbodesign/coolant.py,sha256=nuj7ryUXuBhuOPt2jHjHwtEM_LVno7A8Wm14P0lJn-8,436
|
|
@@ -20,14 +20,14 @@ turbodesign/loss/turbine/kackerokapuu.py,sha256=hUmZdyA1hAhN3_xbwBhka2dyk0Aq9rqq
|
|
|
20
20
|
turbodesign/loss/turbine/traupel.py,sha256=aZxFE9JDcCfi1gy-fqS1SxjjlhuDG-H-g3LPurty1M0,4164
|
|
21
21
|
turbodesign/lossinterp.py,sha256=B2KEobp-nD9jwD6UINgBmTlH9kKyWg3UNvXxqfUsr-k,6198
|
|
22
22
|
turbodesign/outlet.py,sha256=SwTwoL6XnWlsrE5A6wLxu3qXkydDDUsdKKeBbJm4mrQ,2069
|
|
23
|
-
turbodesign/passage.py,sha256=
|
|
24
|
-
turbodesign/radeq.py,sha256=
|
|
23
|
+
turbodesign/passage.py,sha256=eZGaB5Gq9Frm80TTDJaLm1TxJV2-_fHHIeqjPuvtb8E,9550
|
|
24
|
+
turbodesign/radeq.py,sha256=RCsiQzcHvR5dozK6XG0eysAhXYewF0BY_qX0f1knURo,10091
|
|
25
25
|
turbodesign/rotor.py,sha256=tHl9o5H4aQ6Etd4gqa8Ime1UK7k0de4GLt5Yb1sJdGs,1376
|
|
26
26
|
turbodesign/solve_radeq.py,sha256=2VGzFSVkyN0rTPFHaCQiD3v166cdEs39x7x7RuzLgmw,1886
|
|
27
|
-
turbodesign/spool.py,sha256=
|
|
27
|
+
turbodesign/spool.py,sha256=h4m--HR5g8o01Kkhl4Mbvx7WORQez3YpncDE7XxbNaw,14172
|
|
28
28
|
turbodesign/stage.py,sha256=UP45sDKDLsAkO_WfDWJ6kqXU7cYKh_4QO01QZnSN1oQ,166
|
|
29
|
-
turbodesign/td_math.py,sha256=
|
|
30
|
-
turbodesign/turbinespool.py,sha256=
|
|
31
|
-
turbo_design-1.0.
|
|
32
|
-
turbo_design-1.0.
|
|
33
|
-
turbo_design-1.0.
|
|
29
|
+
turbodesign/td_math.py,sha256=K_LyxcgDWNjR9vOA4wfofzlmJlsDn_y64Rj1wi0FTZo,17489
|
|
30
|
+
turbodesign/turbinespool.py,sha256=OJZsucQpGiAHSQOmi7FcagN3jP8dai8umtwC0jBVZGM,25959
|
|
31
|
+
turbo_design-1.1.0.dist-info/METADATA,sha256=feg_7pDPWUK07MJJR8jhx8g6ixlSiEZerhcdKJQ9GBk,734
|
|
32
|
+
turbo_design-1.1.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
|
33
|
+
turbo_design-1.1.0.dist-info/RECORD,,
|
turbodesign/bladerow.py
CHANGED
|
@@ -117,7 +117,7 @@ class BladeRow:
|
|
|
117
117
|
_te_s:float = 0.08
|
|
118
118
|
_tip_clearance:float = 0 # Clearance as a percentage of span or blade height
|
|
119
119
|
|
|
120
|
-
_inlet_to_outlet_pratio = [0.06,0.
|
|
120
|
+
_inlet_to_outlet_pratio = [0.06,0.95]
|
|
121
121
|
|
|
122
122
|
@property
|
|
123
123
|
def inlet_to_outlet_pratio(self) -> Tuple[float,float]:
|
|
@@ -432,7 +432,10 @@ class BladeRow:
|
|
|
432
432
|
val (float): new trailing edge to pitch ratio
|
|
433
433
|
"""
|
|
434
434
|
self._te_s = val
|
|
435
|
-
|
|
435
|
+
|
|
436
|
+
def __repr__(self):
|
|
437
|
+
return f"{self.row_type.name:0.2f}' P0:{np.mean(self.P0):0.2f} T0:{np.mean(self.T0):0.2f} P:{np.mean(self.P):0.2f} massflow:{self.total_massflow_no_coolant}:0.3f"
|
|
438
|
+
|
|
436
439
|
def to_dict(self):
|
|
437
440
|
|
|
438
441
|
data = {
|
turbodesign/passage.py
CHANGED
|
@@ -104,26 +104,42 @@ class Passage:
|
|
|
104
104
|
|
|
105
105
|
"""
|
|
106
106
|
phi = np.zeros(shape=x_streamline.shape)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
107
|
+
r = np.zeros(shape=x_streamline.shape)
|
|
108
|
+
radius_curvature = np.zeros(shape=x_streamline.shape)
|
|
109
|
+
# Have to make sure there isn't a divide by zero which could happen if there is a vertical line somewhere
|
|
110
|
+
indices = np.where(np.abs(np.diff(x_streamline))>np.finfo(float).eps)[0]
|
|
111
|
+
|
|
112
|
+
d_dx = FinDiff(0,x_streamline[indices[0]:indices[-1]],1)
|
|
113
|
+
d2_dx2 = FinDiff(0,x_streamline[indices[0]:indices[-1]],2)
|
|
114
|
+
dr_dx = d_dx(r_streamline[indices[0]:indices[-1]])
|
|
115
|
+
d2r_dx2 = d2_dx2(r_streamline[indices[0]:indices[-1]])
|
|
114
116
|
|
|
115
|
-
radius_curvature = np.power((1+np.power(dr_dx,2)),1.5)
|
|
116
|
-
radius_curvature = np.divide(radius_curvature, np.abs(d2r_dx2))
|
|
117
|
+
radius_curvature[indices[0]:indices[-1]] = np.power((1+np.power(dr_dx,2)),1.5)
|
|
118
|
+
radius_curvature[indices[0]:indices[-1]] = np.divide(radius_curvature[indices[0]:indices[-1]], np.abs(d2r_dx2))
|
|
117
119
|
radius_curvature = np.nan_to_num(radius_curvature,nan=0)
|
|
118
120
|
|
|
121
|
+
def vertical_line_phi(start:int,end:int):
|
|
122
|
+
# Lets get the phi and slope for the vertical parts
|
|
123
|
+
for i in range(start,end):
|
|
124
|
+
dx = x_streamline[i] - x_streamline[i-1]
|
|
125
|
+
dr = r_streamline[i] - r_streamline[i-1]
|
|
126
|
+
if (dr < 0) & (np.abs(dx) < np.finfo(float).eps):
|
|
127
|
+
phi[i-1] = -np.pi/2
|
|
128
|
+
elif (dr > 0) & (np.abs(dx) < np.finfo(float).eps):
|
|
129
|
+
phi[i-1] = np.pi/2
|
|
130
|
+
radius_curvature[i-1] = 1000000 # Initialize to high number, used in radeq.
|
|
131
|
+
|
|
132
|
+
vertical_line_phi(1,indices[0])
|
|
133
|
+
vertical_line_phi(indices[1],len(x_streamline))
|
|
134
|
+
|
|
119
135
|
rm = radius_curvature # https://www.cuemath.com/radius-of-curvature-formula/ should be 1/curvature
|
|
120
|
-
phi = np.arctan(dr_dx)
|
|
136
|
+
phi[indices[0]:indices[-1]] = np.arctan(dr_dx)
|
|
121
137
|
r = r_streamline
|
|
122
138
|
|
|
123
139
|
return phi, rm, r
|
|
124
140
|
|
|
125
141
|
def get_cutting_line(self, t_hub:float) -> line2D:
|
|
126
|
-
"""Gets the cutting line
|
|
142
|
+
"""Gets the cutting line perpendicular to hub and shroud
|
|
127
143
|
|
|
128
144
|
Args:
|
|
129
145
|
t_hub (float): percentage along the axial direction
|
|
@@ -168,6 +184,27 @@ class Passage:
|
|
|
168
184
|
rshroud = self.rshroud(t_shroud)
|
|
169
185
|
return line2D([xhub,rhub],[xshroud,rshroud]), t_hub, t_shroud
|
|
170
186
|
|
|
187
|
+
def get_xr_slice(self,t_span:float,axial_location:float):
|
|
188
|
+
"""Returns the xr coordinates of a streamline, a line that is parallel to both hub and shroud
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
t_span (float): _description_
|
|
192
|
+
axial_location (float): _description_
|
|
193
|
+
|
|
194
|
+
Returns:
|
|
195
|
+
np.NDArray: _description_
|
|
196
|
+
"""
|
|
197
|
+
t_hub = np.linspace(0,axial_location,100)
|
|
198
|
+
|
|
199
|
+
shroud_pts_cyl = np.vstack([self.xshroud(t_hub),self.rshroud(t_hub)]).transpose()
|
|
200
|
+
hub_pts_cyl = np.vstack([self.xhub(t_hub),self.rhub(t_hub)]).transpose()
|
|
201
|
+
n = len(t_hub)
|
|
202
|
+
|
|
203
|
+
xr = np.zeros((n,2))
|
|
204
|
+
for j in range(n):
|
|
205
|
+
l = line2D(hub_pts_cyl[j,:],shroud_pts_cyl[j,:])
|
|
206
|
+
xr[j,0],xr[j,1] = l.get_point(t_span)
|
|
207
|
+
return xr
|
|
171
208
|
|
|
172
209
|
@property
|
|
173
210
|
def hub_length(self):
|
|
@@ -186,7 +223,7 @@ class Passage:
|
|
|
186
223
|
|
|
187
224
|
plt.figure(num=1,clear=True,dpi=150,figsize=(15,10))
|
|
188
225
|
plt.plot(self.xhub_pts,self.rhub_pts,label='hub',linestyle='solid',linewidth=2,color='black')
|
|
189
|
-
plt.plot(self.xshroud_pts,self.rshroud_pts,label='
|
|
226
|
+
plt.plot(self.xshroud_pts,self.rshroud_pts,label='shroud',linestyle='solid',linewidth=2,color='black')
|
|
190
227
|
for p in percent_axial:
|
|
191
228
|
cut,_,_ = self.get_cutting_line(p)
|
|
192
229
|
x,r = cut.get_point(np.linspace(0,1,10))
|
turbodesign/radeq.py
CHANGED
|
@@ -52,12 +52,12 @@ def radeq(row:BladeRow,upstream:BladeRow) -> BladeRow:
|
|
|
52
52
|
gamma = row.gamma
|
|
53
53
|
|
|
54
54
|
# Solve the Radial Equlibrium
|
|
55
|
-
Vt = Vm*np.
|
|
55
|
+
Vt = Vm*np.tan(alpha)
|
|
56
56
|
Vr = Vm*np.sin(phi)
|
|
57
57
|
# Estimations
|
|
58
58
|
dVm_dr = float(interp1d(row_radius, np.gradient(row.Vm, row_radius))(r))
|
|
59
|
-
dVt_dr = dVm_dr*np.
|
|
60
|
-
dVr_dr =
|
|
59
|
+
dVt_dr = dVm_dr*np.tan(alpha)
|
|
60
|
+
dVr_dr = dVm_dr*np.sin(phi)
|
|
61
61
|
|
|
62
62
|
# Upstream
|
|
63
63
|
dT0up_dr = float(interp1d(upstream.percent_hub_shroud, np.gradient(upstream.T0,up_radius))((r-row_radius[0])/(row_radius[-1]-row_radius[0]))) # use percentage to get the T0 upstream value
|
|
@@ -74,7 +74,9 @@ def radeq(row:BladeRow,upstream:BladeRow) -> BladeRow:
|
|
|
74
74
|
# if row.loss_function.LossType == LossType.Pressure: # type: ignore
|
|
75
75
|
# dP0_dr = dP0up_dr-row.Yp*(dP0up_dr - dP_dr) # Eqn 9
|
|
76
76
|
|
|
77
|
-
C = Vm**2*(1+np.
|
|
77
|
+
C = Vm**2*(1+np.tan(alpha)**2)/(2*Cp*T0)
|
|
78
|
+
if (C>1) & ((gamma/(gamma-1))<2):
|
|
79
|
+
raise Exception("Invalid value of C {C}, change reduce alpha or Vm")
|
|
78
80
|
B = (1-C)**(gamma/(gamma-1))
|
|
79
81
|
A = P0 * gamma/(gamma-1) * (1-C)**(1/(gamma-1))
|
|
80
82
|
dVm_dr = 1/(2*Vm*A) * (rho*(Vt/r - Vm**2/rm * np.cos(phi) - Vr*dVr_dr) - dP0_dr*B) + 1/(2*T0) *dT0_dr # Eqn 6
|
turbodesign/spool.py
CHANGED
|
@@ -87,6 +87,8 @@ class Spool:
|
|
|
87
87
|
new_gas (ct.Solution.Solution): New gas mixture
|
|
88
88
|
"""
|
|
89
89
|
self._fluid = newFluid
|
|
90
|
+
for i in range(len(self.blade_rows)):
|
|
91
|
+
self.blade_rows[i].fluid = self.fluid
|
|
90
92
|
|
|
91
93
|
@property
|
|
92
94
|
def adjust_streamlines(self) -> bool:
|
|
@@ -249,7 +251,7 @@ class Spool:
|
|
|
249
251
|
plt.figure(num=1,clear=True)
|
|
250
252
|
for i in range(1,len(self.blade_rows)-1): # Don't plot inlet or outlet
|
|
251
253
|
row = self.blade_rows[i]
|
|
252
|
-
x_end = x_start + row.
|
|
254
|
+
x_end = x_start + row.Vm.mean()
|
|
253
255
|
dx = x_end - x_start
|
|
254
256
|
|
|
255
257
|
Vt = row.Vt[j]
|
|
@@ -285,9 +287,15 @@ class Spool:
|
|
|
285
287
|
plt.annotate("", xy=(x_end,Wt+U), xytext=(x_end,Wt), arrowprops=prop) # U
|
|
286
288
|
plt.text(x_end+dx*0.1,Wt+U/2,"U",fontdict={"fontsize":"xx-large"})
|
|
287
289
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
+
if -np.sign(Vt)>0:
|
|
291
|
+
y = y_min
|
|
292
|
+
else:
|
|
293
|
+
y = y_max
|
|
294
|
+
plt.text((x_start+x_end)/2,-np.sign(Vt)*y*0.95,row.row_type.name,fontdict={"fontsize":"xx-large"})
|
|
295
|
+
x_start += row.Vm[j]
|
|
290
296
|
plt.axis([0,x_end+dx, y_min, y_max])
|
|
297
|
+
plt.ylabel("Tangental Velocity [m/s]")
|
|
298
|
+
plt.xlabel("Vm [m/s]")
|
|
291
299
|
plt.title(f"Velocity Triangles for Streamline {j}")
|
|
292
300
|
plt.savefig(f"streamline_{j:04d}.png",transparent=False,dpi=150)
|
|
293
301
|
|
turbodesign/td_math.py
CHANGED
|
@@ -4,6 +4,7 @@ import math
|
|
|
4
4
|
import numpy.typing as npt
|
|
5
5
|
from .bladerow import BladeRow, compute_gas_constants
|
|
6
6
|
from .enums import RowType, LossType
|
|
7
|
+
from scipy.integrate import trapezoid
|
|
7
8
|
|
|
8
9
|
def T0_coolant_weighted_average(row:BladeRow) -> float:
|
|
9
10
|
"""Calculate the new weighted Total Temperature array considering coolant
|
|
@@ -99,7 +100,7 @@ def compute_power(row:BladeRow,upstream:BladeRow) -> None:
|
|
|
99
100
|
row.eta_static = row.power/ (row.massflow[-1]*row.Cp*(upstream.T0.mean()-row.T0_is.mean()))
|
|
100
101
|
row.eta_total = row.power / (row.massflow[-1]*row.Cp * (upstream.T0.mean()-row.T0_is.mean()))
|
|
101
102
|
row.stage_loading = row.Cp*(upstream.T0.mean() - row.T0.mean())/row.U.mean()**2
|
|
102
|
-
row.euler_power =
|
|
103
|
+
row.euler_power = row.massflow[-1]* (upstream.U*upstream.Vt - row.U*row.Vt).mean()
|
|
103
104
|
|
|
104
105
|
def compute_quantities(row:BladeRow,upstream:BladeRow):
|
|
105
106
|
"""Calculation of all quantites after radial equilibrium has been solved assuming we know the static pressure at the exit.
|
|
@@ -254,21 +255,18 @@ def stator_calc(row:BladeRow,upstream:BladeRow,downstream:BladeRow=None,calculat
|
|
|
254
255
|
row.T0 = upstream.T0 - T0_coolant_weighted_average(row)
|
|
255
256
|
row.T = row.T0/T0_T
|
|
256
257
|
row.V = row.M*np.sqrt(row.gamma*row.R*row.T)
|
|
257
|
-
|
|
258
|
-
row.Vx = VV*np.cos(row.alpha2)
|
|
259
|
-
row.Vt = VV*np.sin(row.alpha2)
|
|
258
|
+
row.Vx = row.Vm*np.cos(row.phi)
|
|
260
259
|
row.Vr = row.V*np.sin(row.phi)
|
|
261
260
|
row.Vm = np.sqrt(row.Vx**2+row.Vr**2)
|
|
262
|
-
|
|
261
|
+
row.Vt = row.Vm*np.tan(row.alpha2)
|
|
262
|
+
else: # We know Vm, P0, T0, P
|
|
263
263
|
row.Vx = row.Vm*np.cos(row.phi)
|
|
264
264
|
row.Vr = row.Vm*np.sin(row.phi)
|
|
265
|
-
row.Vt = row.Vm*np.
|
|
265
|
+
row.Vt = row.Vm*np.tan(row.alpha2)
|
|
266
266
|
row.V = np.sqrt(row.Vx**2 + row.Vr**2 + row.Vt**2)
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
row.P = row.P0 *(1/T0_T)**(row.gamma/(row.gamma-1))
|
|
271
|
-
row.T = row.T0 * (1/T0_T)
|
|
267
|
+
|
|
268
|
+
row.T = row.P/(row.R*row.rho) # We know P, this is a guess
|
|
269
|
+
row.M = row.V/np.sqrt(row.gamma*row.R*row.T)
|
|
272
270
|
|
|
273
271
|
if upstream.row_type == RowType.Rotor:
|
|
274
272
|
row.alpha1 = upstream.alpha2 # Upstream rotor absolute frame flow angle
|
|
@@ -296,13 +294,14 @@ def rotor_calc(row:BladeRow,upstream:BladeRow,calculate_vm:bool=True):
|
|
|
296
294
|
upstream.U = upstream.rpm*np.pi/30 * upstream_radius # rad/s
|
|
297
295
|
upstream.Wt = upstream.Vt - upstream.U
|
|
298
296
|
upstream.W = np.sqrt(upstream.Vx**2 + upstream.Wt**2 + upstream.Vr**2)
|
|
299
|
-
upstream.beta2 = np.arctan2(upstream.Wt,upstream.
|
|
297
|
+
upstream.beta2 = np.arctan2(upstream.Wt,upstream.Vm)
|
|
300
298
|
upstream.T0R = upstream.T+upstream.W**2/(2*upstream.Cp)
|
|
301
299
|
upstream.P0R = upstream.P * (upstream.T0R/upstream.T)**((upstream.gamma)/(upstream.gamma-1))
|
|
302
300
|
upstream.M_rel = upstream.W/np.sqrt(upstream.gamma*upstream.R*upstream.T)
|
|
303
301
|
|
|
304
302
|
upstream_rothalpy = upstream.T0R*upstream.Cp - 0.5*upstream.U**2 # H01R - 1/2 U1^2
|
|
305
|
-
|
|
303
|
+
if np.any(upstream_rothalpy < 0):
|
|
304
|
+
print('U is too high, reduce RPM or radius')
|
|
306
305
|
# Rotor Exit Calculations
|
|
307
306
|
row.beta1 = upstream.beta2
|
|
308
307
|
#row.Yp # Evaluated earlier
|
|
@@ -319,26 +318,26 @@ def rotor_calc(row:BladeRow,upstream:BladeRow,calculate_vm:bool=True):
|
|
|
319
318
|
# Need to adjust T
|
|
320
319
|
print(f'nan detected: check flow path. Turbine inlet cut should be horizontal')
|
|
321
320
|
row.Vr = row.W*np.sin(row.phi)
|
|
322
|
-
row.
|
|
321
|
+
row.Vm = row.W*np.cos(row.beta2)
|
|
322
|
+
row.Wt = row.W*np.sin(row.beta2)
|
|
323
|
+
row.Vx = row.Vm*np.cos(row.phi)
|
|
323
324
|
row.Vt = row.Wt + row.U
|
|
324
|
-
ww = row.W*np.cos(row.phi)
|
|
325
|
-
row.Vx = ww*np.cos(row.beta2)
|
|
326
325
|
row.V = np.sqrt(row.Vr**2+row.Vt**2+row.Vx**2)
|
|
327
326
|
row.M = row.V/np.sqrt(row.gamma*row.R*row.T)
|
|
328
327
|
row.Vm = np.sqrt(row.Vx**2+row.Vr**2)
|
|
329
328
|
row.T0 = row.T + row.V**2/(2*row.Cp)
|
|
330
329
|
row.P0 = row.P*(row.T0/row.T)**(row.gamma/(row.gamma-1))
|
|
331
|
-
row.alpha2 = np.arctan2(row.Vt,row.
|
|
330
|
+
row.alpha2 = np.arctan2(row.Vt,row.Vm)
|
|
332
331
|
else: # We know Vm, P0, T0
|
|
333
332
|
row.Vr = row.Vm*np.sin(row.phi)
|
|
334
333
|
row.Vx = row.Vm*np.cos(row.phi)
|
|
335
334
|
|
|
336
335
|
row.W = np.sqrt(2*row.Cp*(row.T0R-row.T))
|
|
337
|
-
row.Wt =
|
|
336
|
+
row.Wt = row.W*np.sin(row.beta2)
|
|
338
337
|
row.U = row.omega * row.r
|
|
339
338
|
row.Vt = row.Wt+row.U
|
|
340
339
|
|
|
341
|
-
row.alpha2 = np.arctan2(row.Vt,row.
|
|
340
|
+
row.alpha2 = np.arctan2(row.Vt,row.Vm)
|
|
342
341
|
row.V = np.sqrt(row.Vx**2 + row.Vr**2 + row.Vt**2)
|
|
343
342
|
|
|
344
343
|
row.M = row.V/np.sqrt(row.gamma*row.R*row.T)
|
|
@@ -365,7 +364,7 @@ def inlet_calc(row:BladeRow):
|
|
|
365
364
|
row.P = row.P0
|
|
366
365
|
row.rho = row.P/(row.T*row.R)
|
|
367
366
|
total_area = 0
|
|
368
|
-
for
|
|
367
|
+
for iter in range(5): # Lets converge the Mach and Total and Static pressures
|
|
369
368
|
for j in range(1,len(row.percent_hub_shroud)):
|
|
370
369
|
rho = row.rho[j]
|
|
371
370
|
tube_massflow = row.massflow[j]-row.massflow[j-1]
|
|
@@ -379,6 +378,11 @@ def inlet_calc(row:BladeRow):
|
|
|
379
378
|
area[j] = 2*np.pi*C*(S/2*dx**2+row.r[j-1]*dx)
|
|
380
379
|
total_area += area[j]
|
|
381
380
|
row.Vm[j] = tube_massflow/(rho*area[j])
|
|
381
|
+
avg_mach = np.mean(row.M)
|
|
382
|
+
if np.mean(row.M)>0.5:
|
|
383
|
+
print(f"High inlet mach can lead to errors iter:{iter} Mach:{avg_mach}")
|
|
384
|
+
if np.mean(row.M)<0.01:
|
|
385
|
+
print(f"Unusually slow flow:{iter} Mach:{avg_mach}")
|
|
382
386
|
row.Vm[0] = 1/(len(row.Vm)-1)*row.Vm[1:].sum() # Initialize the value at the hub to not upset the mean
|
|
383
387
|
row.Vr = row.Vm*np.sin(row.phi)
|
|
384
388
|
row.Vt = row.Vm*np.cos(row.phi)*np.tan(row.alpha2)
|
turbodesign/turbinespool.py
CHANGED
|
@@ -206,7 +206,9 @@ class TurbineSpool(Spool):
|
|
|
206
206
|
sign*=-1
|
|
207
207
|
if len(stage_ids) % 2 == 1:
|
|
208
208
|
massflow_stage.append(massflow_stage[-1]*sign)
|
|
209
|
-
|
|
209
|
+
deviation = np.std(total_massflow)*2
|
|
210
|
+
if deviation>1.0:
|
|
211
|
+
print("high massflow deviation detected")
|
|
210
212
|
return np.std(total_massflow)*2 # + abs(sum(massflow_stage)) # Equation 28
|
|
211
213
|
|
|
212
214
|
# Balance the massflow between Stages
|
|
@@ -229,27 +231,27 @@ class TurbineSpool(Spool):
|
|
|
229
231
|
Returns:
|
|
230
232
|
_type_: _description_
|
|
231
233
|
"""
|
|
232
|
-
try:
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
for i in range(1,len(blade_rows)-1):
|
|
237
|
-
blade_rows[i].P[j] = Ps_range[i-1]
|
|
238
|
-
blade_rows[-1].P = P
|
|
239
|
-
else:
|
|
234
|
+
# try:
|
|
235
|
+
if balance_mean_pressure:
|
|
236
|
+
for j in range(self.num_streamlines):
|
|
237
|
+
Ps_range = outlet_pressure(x0,P0[j],P[j])
|
|
240
238
|
for i in range(1,len(blade_rows)-1):
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
calculate_massflows(blade_rows,True)
|
|
245
|
-
print(x0)
|
|
246
|
-
return calculate_error(blade_rows)
|
|
247
|
-
except:
|
|
239
|
+
blade_rows[i].P[j] = Ps_range[i-1]
|
|
240
|
+
blade_rows[-1].P = P
|
|
241
|
+
else:
|
|
248
242
|
for i in range(1,len(blade_rows)-1):
|
|
249
243
|
for j in range(self.num_streamlines):
|
|
250
|
-
blade_rows[i].P[j] = P[j]
|
|
251
|
-
|
|
252
|
-
|
|
244
|
+
blade_rows[i].P[j] = P[j]*x0[(i-1)*self.num_streamlines+j] # x0 size = num_streamlines -1
|
|
245
|
+
|
|
246
|
+
calculate_massflows(blade_rows,True)
|
|
247
|
+
print(x0)
|
|
248
|
+
return calculate_error(blade_rows)
|
|
249
|
+
# except:
|
|
250
|
+
# for i in range(1,len(blade_rows)-1):
|
|
251
|
+
# for j in range(self.num_streamlines):
|
|
252
|
+
# blade_rows[i].P[j] = P[j]
|
|
253
|
+
# calculate_massflows(blade_rows,True)
|
|
254
|
+
# return 10
|
|
253
255
|
# Break apart the rows to stages
|
|
254
256
|
outlet_P=list(); outlet_P_guess = list() # Outlet P is the bounds, outlet_p_guess is the guessed values
|
|
255
257
|
|
|
@@ -534,11 +536,11 @@ def outlet_pressure(percents:List[float],inletP0:float,outletP:float) -> npt.NDA
|
|
|
534
536
|
maxP = inletP0
|
|
535
537
|
minP = outletP
|
|
536
538
|
if isinstance(percents, float):
|
|
537
|
-
Ps = [percents*(minP
|
|
539
|
+
Ps = [percents*(maxP-minP)+minP]
|
|
538
540
|
else:
|
|
539
541
|
Ps = np.zeros(shape=(len(percents),1)); i = 0
|
|
540
542
|
for p in percents:
|
|
541
|
-
Ps[i] = p*(minP
|
|
543
|
+
Ps[i] = p*(maxP - minP) + minP
|
|
542
544
|
maxP = Ps[i]
|
|
543
545
|
i+=1
|
|
544
546
|
return Ps
|