turbo-design 1.3.1__tar.gz → 1.3.2__tar.gz
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.3.1 → turbo_design-1.3.2}/PKG-INFO +3 -2
- {turbo_design-1.3.1 → turbo_design-1.3.2}/pyproject.toml +1 -1
- turbo_design-1.3.2/turbodesign/.DS_Store +0 -0
- turbo_design-1.3.2/turbodesign/loss/.DS_Store +0 -0
- turbo_design-1.3.2/turbodesign/loss/__pycache__/__init__.cpython-310.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/__pycache__/__init__.cpython-312.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/__pycache__/losstype.cpython-310.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/__pycache__/losstype.cpython-312.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/turbine/__pycache__/TD2.cpython-310.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/turbine/__pycache__/TD2.cpython-312.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/turbine/__pycache__/__init__.cpython-310.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/turbine/__pycache__/__init__.cpython-312.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/turbine/__pycache__/ainleymathieson.cpython-310.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/turbine/__pycache__/ainleymathieson.cpython-312.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/turbine/__pycache__/craigcox.cpython-310.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/turbine/__pycache__/craigcox.cpython-312.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/turbine/__pycache__/fixedefficiency.cpython-310.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/turbine/__pycache__/fixedefficiency.cpython-312.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/turbine/__pycache__/fixedpressureloss.cpython-310.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/turbine/__pycache__/fixedpressureloss.cpython-312.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/turbine/__pycache__/kackerokapuu.cpython-310.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/turbine/__pycache__/kackerokapuu.cpython-312.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/turbine/__pycache__/traupel.cpython-310.pyc +0 -0
- turbo_design-1.3.2/turbodesign/loss/turbine/__pycache__/traupel.cpython-312.pyc +0 -0
- turbo_design-1.3.2/turbodesign/radeq.py +160 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/solve_radeq.py +1 -1
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/td_math.py +3 -3
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/turbinespool.py +65 -69
- turbo_design-1.3.1/turbodesign/radeq.py +0 -286
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/__init__.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/arrayfuncs.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/bladerow.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/cantera_gas/co2.yaml +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/compressorspool.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/coolant.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/enums.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/inlet.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/isentropic.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/loss/__init__.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/loss/compressor/__init__.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/loss/losstype.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/loss/turbine/TD2.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/loss/turbine/__init__.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/loss/turbine/ainleymathieson.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/loss/turbine/craigcox.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/loss/turbine/fixedefficiency.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/loss/turbine/fixedpressureloss.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/loss/turbine/kackerokapuu.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/loss/turbine/traupel.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/lossinterp.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/outlet.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/passage.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/rotor.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/spool.py +0 -0
- {turbo_design-1.3.1 → turbo_design-1.3.2}/turbodesign/stage.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: turbo-design
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.2
|
|
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
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
from scipy.interpolate import interp1d,PchipInterpolator
|
|
2
|
+
from scipy.integrate import solve_ivp
|
|
3
|
+
import numpy as np
|
|
4
|
+
import numdifftools as nd
|
|
5
|
+
from .bladerow import BladeRow
|
|
6
|
+
from .enums import RowType
|
|
7
|
+
import math
|
|
8
|
+
|
|
9
|
+
def radeq(row:BladeRow,upstream:BladeRow,downstream:BladeRow=None) -> BladeRow:
|
|
10
|
+
"""Solves the radial equilibrium equation for axial machines and returns the convergence.
|
|
11
|
+
|
|
12
|
+
Note:
|
|
13
|
+
This function will give you T0, P0, Vm as a function of the radius.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
row (BladeRow): Current row
|
|
17
|
+
upstream (BladeRow): Previous row
|
|
18
|
+
downstream (BladeRow): Next row
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
BladeRow: current row with T0, P0, and Vm calculated
|
|
22
|
+
"""
|
|
23
|
+
row_radius = row.r # Use these for gradient
|
|
24
|
+
up_radius = upstream.r
|
|
25
|
+
|
|
26
|
+
def ode_radeq_streamtube(r:np.ndarray,y:np.ndarray):
|
|
27
|
+
"""Solves the radial equilibrium equation for a streamtube
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
r (np.ndarray): radius not as a percent
|
|
31
|
+
y (np.ndarray): Array containing [P0,Vt,VtU,T0]
|
|
32
|
+
|
|
33
|
+
"""
|
|
34
|
+
P0 = y[0]
|
|
35
|
+
T0 = y[1]
|
|
36
|
+
Vm = y[2]
|
|
37
|
+
r = row.r.mean()+r
|
|
38
|
+
if r>row_radius[-1]:
|
|
39
|
+
return [0,0,0]
|
|
40
|
+
elif r<row_radius[0]:
|
|
41
|
+
return [0,0,0]
|
|
42
|
+
|
|
43
|
+
Cp = row.Cp
|
|
44
|
+
phi = interp1d(row_radius, row.phi)(r)
|
|
45
|
+
alpha = interp1d(row_radius, row.alpha2)(r)
|
|
46
|
+
T = interp1d(row_radius, row.T)(r)
|
|
47
|
+
P = interp1d(row_radius, row.P)(r)
|
|
48
|
+
rm = interp1d(row_radius, row.rm)(r)
|
|
49
|
+
rho = row.rho.mean()
|
|
50
|
+
|
|
51
|
+
if (row.row_type == RowType.Rotor):
|
|
52
|
+
omega = row.rpm*np.pi/30
|
|
53
|
+
U = omega*r
|
|
54
|
+
else:
|
|
55
|
+
omega = 0
|
|
56
|
+
U = 0
|
|
57
|
+
gamma = row.gamma
|
|
58
|
+
|
|
59
|
+
# Solve the Radial Equlibrium
|
|
60
|
+
Vt = Vm*np.tan(alpha)
|
|
61
|
+
Vr = Vm*np.sin(phi)
|
|
62
|
+
# Estimations
|
|
63
|
+
dVm_dr = float(interp1d(row_radius, np.gradient(row.Vm, row_radius))(r))
|
|
64
|
+
up_Vm = interp1d(row_radius, upstream.Vm)(r)
|
|
65
|
+
|
|
66
|
+
if downstream:
|
|
67
|
+
if downstream.row_type == RowType.Outlet:
|
|
68
|
+
down_Vm = Vm
|
|
69
|
+
else:
|
|
70
|
+
down_Vm = interp1d(row_radius, downstream.Vm)(r)
|
|
71
|
+
else:
|
|
72
|
+
down_Vm = Vm
|
|
73
|
+
up_m = interp1d(row_radius, upstream.m)(r)
|
|
74
|
+
|
|
75
|
+
# Get a rough guess of dVm/dm
|
|
76
|
+
if downstream!=None:
|
|
77
|
+
down_m = interp1d(row_radius, downstream.m)(r)
|
|
78
|
+
row_m = interp1d(row_radius, row.m)(r)
|
|
79
|
+
if down_m != row_m:
|
|
80
|
+
func_Vm_m = PchipInterpolator([up_m, row_m, down_m],[up_Vm, Vm, down_Vm])
|
|
81
|
+
else:
|
|
82
|
+
func_Vm_m = PchipInterpolator([up_m, row_m],[up_Vm, Vm])
|
|
83
|
+
else:
|
|
84
|
+
func_Vm_m = PchipInterpolator([up_m, row_m],[up_Vm, Vm])
|
|
85
|
+
dVm_dm = func_Vm_m.derivative()(row_m)
|
|
86
|
+
|
|
87
|
+
# Upstream
|
|
88
|
+
dT_dr = float(interp1d(row_radius, np.gradient(row.T,row_radius))(r))
|
|
89
|
+
dP_dr = float(interp1d(row_radius, np.gradient(row.P,row_radius))(r))
|
|
90
|
+
P = float(interp1d(row_radius, np.gradient(row.P,row_radius))(r))
|
|
91
|
+
dT0_dr = dT_dr + Vm/Cp * (1 + np.tan(alpha)**2)*dVm_dr
|
|
92
|
+
dP0_dr = dP_dr * (T0/T)**(gamma/(gamma-1)) + P*gamma/(gamma-1) * (T0/T)**(1/(gamma-1)) * (T*dT0_dr-T0*dT_dr)/T**2
|
|
93
|
+
# dT0_dr = float(interp1d(row.percent_hub_shroud, np.gradient(row.T0,row_radius))((r-row_radius[0])/(row_radius[-1]-row_radius[0])))
|
|
94
|
+
# dP0_dr = float(interp1d(row.percent_hub_shroud, np.gradient(row.P0,row_radius))((r-row_radius[0])/(row_radius[-1]-row_radius[0])))
|
|
95
|
+
|
|
96
|
+
C = (1 + np.tan(alpha)**2) * Vm**2/(2*Cp*T0)
|
|
97
|
+
if (C>1) & ((gamma/(gamma-1))<2):
|
|
98
|
+
raise Exception("Invalid value of C {C}, change reduce alpha or Vm")
|
|
99
|
+
B = (1-C)**(gamma/(gamma-1))
|
|
100
|
+
A = -P0 * gamma/(gamma-1) * (1-C)**(1/(gamma-1)) * (1 + np.tan(alpha)**2)/(2*Cp)
|
|
101
|
+
|
|
102
|
+
eqn15_rhs = Vt**2/r - Vm**2/rm*np.sin(phi) - Vr*dVm_dm # right hand side of equation 15
|
|
103
|
+
eqn15_rhs_simple = Vt**2/r # right hand side of equation 15 simplified for axial machines
|
|
104
|
+
|
|
105
|
+
epsilon = 1e-10 # or another small threshold
|
|
106
|
+
if abs(rm) > epsilon:
|
|
107
|
+
dVm_dr = T0/(2*Vm*A) * (rho*eqn15_rhs - B*dP0_dr) + Vm/(2*T0) * dT0_dr # Eqn 21
|
|
108
|
+
else:
|
|
109
|
+
dVm_dr = T0/(2*Vm*A) * (rho*eqn15_rhs_simple - B*dP0_dr) + Vm/(2*T0) * dT0_dr # Eqn 21, simple
|
|
110
|
+
|
|
111
|
+
ydot = np.array([dP0_dr,dT0_dr,dVm_dr])
|
|
112
|
+
|
|
113
|
+
return ydot
|
|
114
|
+
|
|
115
|
+
T0 = row.T0
|
|
116
|
+
|
|
117
|
+
P0 = row.P0
|
|
118
|
+
Vm = row.Vm
|
|
119
|
+
|
|
120
|
+
# Estimate the Vt based on a given turning angle
|
|
121
|
+
mean_radius = row_radius.mean()
|
|
122
|
+
tip_radius = row_radius.max()
|
|
123
|
+
hub_radius = row_radius.min()
|
|
124
|
+
|
|
125
|
+
T0m = interp1d(row.percent_hub_shroud,T0)(0.5);
|
|
126
|
+
P0m = interp1d(row.percent_hub_shroud,P0)(0.5); Vmm = interp1d(row.percent_hub_shroud,Vm)(0.5)
|
|
127
|
+
# We are solving for the values of these quantities at row exit
|
|
128
|
+
ics = np.array([P0m,T0m,Vmm])
|
|
129
|
+
|
|
130
|
+
# hub_to_tip = np.linspace(hub_radius,tip_radius)
|
|
131
|
+
# res = odeint(ode_radeq_streamtube, ics, hub_to_tip, tfirst=True)
|
|
132
|
+
|
|
133
|
+
# P0_new = interp1d(hub_to_tip,res[:,0])(row_radius)
|
|
134
|
+
# T0_new = interp1d(hub_to_tip,res[:,1])(row_radius)
|
|
135
|
+
# Vm_new = interp1d(hub_to_tip,res[:,2])(row_radius)
|
|
136
|
+
|
|
137
|
+
# mean_radius_to_tip = np.linspace(0,tip_radius-mean_radius,len(row_radius)*5)
|
|
138
|
+
res1 = solve_ivp(ode_radeq_streamtube, t_span =[0, tip_radius-mean_radius], y0 = ics)
|
|
139
|
+
|
|
140
|
+
# mean_radius_to_hub = np.linspace(0,hub_radius-mean_radius,len(row_radius)*5)
|
|
141
|
+
res2 = solve_ivp(ode_radeq_streamtube, t_span = [hub_radius-mean_radius,0], y0 = ics)
|
|
142
|
+
|
|
143
|
+
mid_to_tip_vals = res1.y.transpose()
|
|
144
|
+
mid_to_tip_r = res1.t + mean_radius
|
|
145
|
+
mid_to_hub_vals = res2.y.transpose()
|
|
146
|
+
mid_to_hub_r = res2.t + mean_radius
|
|
147
|
+
mid_to_hub_vals = np.flipud(mid_to_hub_vals)
|
|
148
|
+
hub_to_tip_vals = np.concatenate([mid_to_hub_vals[:-1,:],mid_to_tip_vals])
|
|
149
|
+
|
|
150
|
+
r = np.concatenate([mid_to_hub_r[:-1], mid_to_tip_r])
|
|
151
|
+
|
|
152
|
+
P0_new = interp1d(r,hub_to_tip_vals[:,0])(row_radius)
|
|
153
|
+
T0_new = interp1d(r,hub_to_tip_vals[:,1])(row_radius)
|
|
154
|
+
Vm_new = interp1d(r,hub_to_tip_vals[:,2])(row_radius)
|
|
155
|
+
|
|
156
|
+
row.P0 = P0_new
|
|
157
|
+
row.T0 = T0_new
|
|
158
|
+
row.Vm = Vm_new
|
|
159
|
+
return row
|
|
160
|
+
|
|
@@ -296,7 +296,7 @@ def rotor_calc(row:BladeRow,upstream:BladeRow,calculate_vm:bool=True):
|
|
|
296
296
|
row.P0R = upstream.P0R - row.Yp*(upstream.P0R-row.P)
|
|
297
297
|
|
|
298
298
|
# Total Relative Temperature stays constant through the rotor. Adjust for change in radius from rotor inlet to exit
|
|
299
|
-
row.T0R = (upstream_rothalpy + 0.5*row.U**2)/row.Cp - T0_coolant_weighted_average(row)
|
|
299
|
+
row.T0R = upstream.T0R # (upstream_rothalpy + 0.5*row.U**2)/row.Cp # - T0_coolant_weighted_average(row)
|
|
300
300
|
P0R_P = row.P0R / row.P
|
|
301
301
|
T0R_T = P0R_P**((row.gamma-1)/row.gamma)
|
|
302
302
|
row.T = (row.T0R/T0R_T) # Exit static temperature
|
|
@@ -326,7 +326,7 @@ def rotor_calc(row:BladeRow,upstream:BladeRow,calculate_vm:bool=True):
|
|
|
326
326
|
row.Vt = row.Wt+row.U
|
|
327
327
|
|
|
328
328
|
row.alpha2 = np.arctan2(row.Vt,row.Vm)
|
|
329
|
-
row.V = np.sqrt(row.
|
|
329
|
+
row.V = np.sqrt(row.Vm**2*(1+np.tan(row.alpha2)**2))
|
|
330
330
|
|
|
331
331
|
row.M = row.V/np.sqrt(row.gamma*row.R*row.T)
|
|
332
332
|
T0_T = (1+(row.gamma-1)/2 * row.M**2)
|
|
@@ -369,7 +369,7 @@ def inlet_calc(row:BladeRow):
|
|
|
369
369
|
raise ValueError(f"Unusually slow flow:{iter} Mach:{avg_mach}")
|
|
370
370
|
row.Vm[0] = 1/(len(row.Vm)-1)*row.Vm[1:].sum() # Initialize the value at the hub to not upset the mean
|
|
371
371
|
row.Vr = row.Vm*np.sin(row.phi)
|
|
372
|
-
row.Vt = row.Vm*np.
|
|
372
|
+
row.Vt = row.Vm*np.tan(row.alpha2)
|
|
373
373
|
row.V = np.sqrt(row.Vt**2+row.Vm**2)
|
|
374
374
|
# Fine tune the Temperature and Pressure and density
|
|
375
375
|
row.M = row.V/np.sqrt(row.gamma*row.R*row.T)
|
|
@@ -13,6 +13,7 @@ from .solve_radeq import adjust_streamlines, radeq
|
|
|
13
13
|
from scipy.optimize import minimize_scalar, differential_evolution, fmin_slsqp
|
|
14
14
|
from .inlet import Inlet
|
|
15
15
|
from .outlet import Outlet
|
|
16
|
+
from pyturbo.helper import convert_to_ndarray
|
|
16
17
|
|
|
17
18
|
class TurbineSpool(Spool):
|
|
18
19
|
|
|
@@ -193,7 +194,7 @@ class TurbineSpool(Spool):
|
|
|
193
194
|
"""
|
|
194
195
|
total_massflow = list(); s = 0; massflow_stage = list()
|
|
195
196
|
stage_ids = list(set([row.stage_id for row in blade_rows if row.stage_id>=0]))
|
|
196
|
-
for row in blade_rows
|
|
197
|
+
for row in blade_rows: # Ignore inlet and outlet
|
|
197
198
|
total_massflow.append(row.total_massflow_no_coolant)
|
|
198
199
|
sign = 1
|
|
199
200
|
for s in stage_ids:
|
|
@@ -237,7 +238,7 @@ class TurbineSpool(Spool):
|
|
|
237
238
|
2. Keep the mean
|
|
238
239
|
|
|
239
240
|
Args:
|
|
240
|
-
x0 (List[float]):
|
|
241
|
+
x0 (List[float]): Percentage of P0 exiting each row
|
|
241
242
|
blade_rows (List[List[BladeRow]]): _description_
|
|
242
243
|
P0 (npt.NDArray): _description_
|
|
243
244
|
P (npt.NDArray): (1) Outlet Static Pressure. (2)
|
|
@@ -250,9 +251,9 @@ class TurbineSpool(Spool):
|
|
|
250
251
|
# try:
|
|
251
252
|
if balance_mean_pressure:
|
|
252
253
|
for j in range(self.num_streamlines):
|
|
253
|
-
|
|
254
|
+
Ps = outlet_pressure(x0,P0[j],P[j])
|
|
254
255
|
for i in range(1,len(blade_rows)-2):
|
|
255
|
-
blade_rows[i].P[j] =
|
|
256
|
+
blade_rows[i].P[j] = float(Ps[i-1])
|
|
256
257
|
blade_rows[-2].P = P
|
|
257
258
|
else:
|
|
258
259
|
for i in range(1,len(blade_rows)-1):
|
|
@@ -261,7 +262,7 @@ class TurbineSpool(Spool):
|
|
|
261
262
|
# try:
|
|
262
263
|
calculate_massflows(blade_rows,True,self.fluid)
|
|
263
264
|
print(x0)
|
|
264
|
-
return self.__massflow_std__(blade_rows)
|
|
265
|
+
return self.__massflow_std__(blade_rows[1:-1]) # do not consider inlet and outlet
|
|
265
266
|
# except Exception as e:
|
|
266
267
|
# print(e)
|
|
267
268
|
# finally:
|
|
@@ -280,7 +281,7 @@ class TurbineSpool(Spool):
|
|
|
280
281
|
past_err = -100; loop_iter = 0; err = 0.001
|
|
281
282
|
while (np.abs((err-past_err)/err)>0.05) and loop_iter<10:
|
|
282
283
|
if len(outlet_P) == 1:
|
|
283
|
-
# x = balance_massflows(0.
|
|
284
|
+
# x = balance_massflows(0.22896832148169688,self.blade_rows,self.blade_rows[0].P0,self.blade_rows[-1].P)
|
|
284
285
|
res = minimize_scalar(fun=balance_massflows,args=(self.blade_rows,self.blade_rows[0].P0,self.blade_rows[-1].P),bounds=outlet_P[0],tol=0.001,options={'disp': True},method='bounded')
|
|
285
286
|
x = res.x
|
|
286
287
|
print(x)
|
|
@@ -395,64 +396,63 @@ def calculate_massflows(blade_rows:List[BladeRow],calculate_vm:bool=False,fluid:
|
|
|
395
396
|
passage (Passage): _description_
|
|
396
397
|
calculate_vm (bool, optional): _description_. Defaults to False.
|
|
397
398
|
"""
|
|
398
|
-
for
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
for _ in range(2):
|
|
416
|
-
if row.row_type == RowType.Rotor:
|
|
417
|
-
rotor_calc(row,upstream,calculate_vm=True)
|
|
418
|
-
# Finds Equilibrium between Vm, P0, T0
|
|
419
|
-
row = radeq(row,upstream,downstream)
|
|
420
|
-
compute_gas_constants(row,fluid)
|
|
421
|
-
rotor_calc(row,upstream,calculate_vm=False)
|
|
422
|
-
elif row.row_type == RowType.Stator:
|
|
423
|
-
stator_calc(row,upstream,downstream,calculate_vm=True)
|
|
424
|
-
# Finds Equilibrium between Vm, P0, T0
|
|
425
|
-
row = radeq(row,upstream,downstream)
|
|
426
|
-
compute_gas_constants(row,fluid)
|
|
427
|
-
stator_calc(row,upstream,downstream,calculate_vm=False)
|
|
428
|
-
compute_gas_constants(row,fluid)
|
|
429
|
-
compute_massflow(row)
|
|
430
|
-
compute_power(row,upstream)
|
|
431
|
-
|
|
432
|
-
elif row.loss_function.loss_type == LossType.Enthalpy:
|
|
399
|
+
for i in range(1,len(blade_rows)-1):
|
|
400
|
+
row = blade_rows[i]
|
|
401
|
+
# Upstream Row
|
|
402
|
+
if i == 0:
|
|
403
|
+
upstream = blade_rows[i]
|
|
404
|
+
else:
|
|
405
|
+
upstream = blade_rows[i-1]
|
|
406
|
+
if i<len(blade_rows)-1:
|
|
407
|
+
downstream = blade_rows[i+1]
|
|
408
|
+
|
|
409
|
+
# Pressure loss = shift in entropy which affects the total pressure of the row
|
|
410
|
+
if row.row_type == RowType.Inlet:
|
|
411
|
+
row.Yp = 0
|
|
412
|
+
else:
|
|
413
|
+
if row.loss_function.loss_type == LossType.Pressure:
|
|
414
|
+
row.Yp = row.loss_function(row,upstream)
|
|
415
|
+
for _ in range(2):
|
|
433
416
|
if row.row_type == RowType.Rotor:
|
|
434
|
-
row
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
rotor_calc(row,upstream,calculate_vm=True)
|
|
440
|
-
row = radeq(row,upstream)
|
|
441
|
-
compute_gas_constants(row,fluid)
|
|
442
|
-
rotor_calc(row,upstream,calculate_vm=False)
|
|
443
|
-
return abs(row.eta_total - eta_total)
|
|
444
|
-
|
|
445
|
-
res = minimize_scalar(find_yp,bounds=[0,0.6],args=(row,upstream))
|
|
446
|
-
row.Yp = res.x
|
|
417
|
+
rotor_calc(row,upstream,calculate_vm=True)
|
|
418
|
+
# Finds Equilibrium between Vm, P0, T0
|
|
419
|
+
row = radeq(row,upstream,downstream)
|
|
420
|
+
compute_gas_constants(row,fluid)
|
|
421
|
+
rotor_calc(row,upstream,calculate_vm=False)
|
|
447
422
|
elif row.row_type == RowType.Stator:
|
|
448
|
-
row.Yp = 0
|
|
449
423
|
stator_calc(row,upstream,downstream,calculate_vm=True)
|
|
450
|
-
|
|
451
|
-
row =
|
|
424
|
+
# Finds Equilibrium between Vm, P0, T0
|
|
425
|
+
row = radeq(row,upstream,downstream)
|
|
426
|
+
compute_gas_constants(row,fluid)
|
|
452
427
|
stator_calc(row,upstream,downstream,calculate_vm=False)
|
|
453
|
-
|
|
428
|
+
compute_gas_constants(row,fluid)
|
|
454
429
|
compute_massflow(row)
|
|
455
430
|
compute_power(row,upstream)
|
|
431
|
+
|
|
432
|
+
elif row.loss_function.loss_type == LossType.Enthalpy:
|
|
433
|
+
if row.row_type == RowType.Rotor:
|
|
434
|
+
row.Yp = 0
|
|
435
|
+
rotor_calc(row,upstream,calculate_vm=calculate_vm)
|
|
436
|
+
eta_total = float(row.loss_function(row,upstream))
|
|
437
|
+
def find_yp(Yp,row,upstream):
|
|
438
|
+
row.Yp = Yp
|
|
439
|
+
rotor_calc(row,upstream,calculate_vm=True)
|
|
440
|
+
row = radeq(row,upstream)
|
|
441
|
+
compute_gas_constants(row,fluid)
|
|
442
|
+
rotor_calc(row,upstream,calculate_vm=False)
|
|
443
|
+
return abs(row.eta_total - eta_total)
|
|
444
|
+
|
|
445
|
+
res = minimize_scalar(find_yp,bounds=[0,0.6],args=(row,upstream))
|
|
446
|
+
row.Yp = res.x
|
|
447
|
+
elif row.row_type == RowType.Stator:
|
|
448
|
+
row.Yp = 0
|
|
449
|
+
stator_calc(row,upstream,downstream,calculate_vm=True)
|
|
450
|
+
row = radeq(row,upstream)
|
|
451
|
+
row = compute_gas_constants(row,fluid)
|
|
452
|
+
stator_calc(row,upstream,downstream,calculate_vm=False)
|
|
453
|
+
row = compute_gas_constants(row,fluid)
|
|
454
|
+
compute_massflow(row)
|
|
455
|
+
compute_power(row,upstream)
|
|
456
456
|
|
|
457
457
|
def massflow_loss_function(exit_angle:float,index:int,row:BladeRow,upstream:BladeRow,downstream:BladeRow=None,fluid:Solution=None):
|
|
458
458
|
"""Finds the blade exit angles that balance the massflow throughout the stage
|
|
@@ -533,14 +533,10 @@ def outlet_pressure(percents:List[float],inletP0:float,outletP:float) -> npt.NDA
|
|
|
533
533
|
Returns:
|
|
534
534
|
npt.NDArray: Array of static pressures
|
|
535
535
|
"""
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
Ps =
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
Ps[i] = p*(maxP - minP) + minP
|
|
544
|
-
maxP = Ps[i]
|
|
545
|
-
i+=1
|
|
546
|
-
return Ps
|
|
536
|
+
percents = convert_to_ndarray(percents)
|
|
537
|
+
Ps = np.zeros((len(percents),))
|
|
538
|
+
for i in range(len(percents)):
|
|
539
|
+
Ps[i] = float(interp1d((0,1),(inletP0,outletP))(percents[i]))
|
|
540
|
+
inletP0 = Ps[i]
|
|
541
|
+
return Ps
|
|
542
|
+
|
|
@@ -1,286 +0,0 @@
|
|
|
1
|
-
from scipy.interpolate import interp1d,PchipInterpolator
|
|
2
|
-
from scipy.integrate import odeint
|
|
3
|
-
import numpy as np
|
|
4
|
-
import numdifftools as nd
|
|
5
|
-
from .bladerow import BladeRow
|
|
6
|
-
from .enums import RowType
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def radeq(row:BladeRow,upstream:BladeRow,downstream:BladeRow=None) -> BladeRow:
|
|
10
|
-
"""Solves the radial equilibrium equation for axial machines and returns the convergence.
|
|
11
|
-
|
|
12
|
-
Note:
|
|
13
|
-
This function will give you T0, P0, Vm as a function of the radius.
|
|
14
|
-
|
|
15
|
-
Args:
|
|
16
|
-
row (BladeRow): Current row
|
|
17
|
-
upstream (BladeRow): Previous row
|
|
18
|
-
downstream (BladeRow): Next row
|
|
19
|
-
|
|
20
|
-
Returns:
|
|
21
|
-
BladeRow: current row with T0, P0, and Vm calculated
|
|
22
|
-
"""
|
|
23
|
-
row_radius = row.r # Use these for gradient
|
|
24
|
-
up_radius = upstream.r
|
|
25
|
-
|
|
26
|
-
def ode_radeq_streamtube(r:np.ndarray,y:np.ndarray):
|
|
27
|
-
"""Solves the radial equilibrium equation for a streamtube
|
|
28
|
-
|
|
29
|
-
Args:
|
|
30
|
-
r (np.ndarray): radius not as a percent
|
|
31
|
-
y (np.ndarray): Array containing [P0,Vt,VtU,T0]
|
|
32
|
-
|
|
33
|
-
"""
|
|
34
|
-
P0 = y[0]
|
|
35
|
-
T0 = y[1]
|
|
36
|
-
Vm = y[2]
|
|
37
|
-
if r>row_radius[-1]:
|
|
38
|
-
return [0,0,0]
|
|
39
|
-
elif r<row_radius[0]:
|
|
40
|
-
return [0,0,0]
|
|
41
|
-
|
|
42
|
-
Cp = row.Cp
|
|
43
|
-
phi = interp1d(row_radius, row.phi)(r)
|
|
44
|
-
alpha = interp1d(row_radius, row.alpha2)(r)
|
|
45
|
-
rm = interp1d(row_radius, row.rm)(r)
|
|
46
|
-
rho = row.rho.mean()
|
|
47
|
-
|
|
48
|
-
if (row.row_type == RowType.Rotor):
|
|
49
|
-
omega = row.rpm*np.pi/30
|
|
50
|
-
U = omega*r
|
|
51
|
-
else:
|
|
52
|
-
omega = 0
|
|
53
|
-
U = 0
|
|
54
|
-
gamma = row.gamma
|
|
55
|
-
|
|
56
|
-
# Solve the Radial Equlibrium
|
|
57
|
-
Vt = Vm*np.tan(alpha)
|
|
58
|
-
Vr = Vm*np.sin(phi)
|
|
59
|
-
# Estimations
|
|
60
|
-
dVm_dr = float(interp1d(row_radius, np.gradient(row.Vm, row_radius))(r))
|
|
61
|
-
dVt_dr = dVm_dr*np.tan(alpha)
|
|
62
|
-
# dVr_dr = dVm_dr*np.sin(phi)
|
|
63
|
-
|
|
64
|
-
up_Vm = interp1d(row_radius, upstream.Vm)(r)
|
|
65
|
-
if downstream:
|
|
66
|
-
if downstream.row_type == RowType.Outlet:
|
|
67
|
-
down_Vm = Vm
|
|
68
|
-
else:
|
|
69
|
-
down_Vm = interp1d(row_radius, downstream.Vm)(r)
|
|
70
|
-
else:
|
|
71
|
-
down_Vm = Vm
|
|
72
|
-
up_m = interp1d(row_radius, upstream.m)(r)
|
|
73
|
-
|
|
74
|
-
# Get a rough guess of dVm/dm
|
|
75
|
-
if downstream!=None:
|
|
76
|
-
down_m = interp1d(row_radius, downstream.m)(r)
|
|
77
|
-
row_m = interp1d(row_radius, row.m)(r)
|
|
78
|
-
if down_m != row_m:
|
|
79
|
-
func_Vm_m = PchipInterpolator([up_m, row_m, down_m],[up_Vm, Vm, down_Vm])
|
|
80
|
-
else:
|
|
81
|
-
func_Vm_m = PchipInterpolator([up_m, row_m],[up_Vm, Vm])
|
|
82
|
-
else:
|
|
83
|
-
func_Vm_m = PchipInterpolator([up_m, row_m],[up_Vm, Vm])
|
|
84
|
-
dVm_dm = func_Vm_m.derivative()(row_m)
|
|
85
|
-
|
|
86
|
-
# Upstream
|
|
87
|
-
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
|
|
88
|
-
dP0up_dr = float(interp1d(upstream.percent_hub_shroud, np.gradient(upstream.P0,up_radius))((r-row_radius[0])/(row_radius[-1]-row_radius[0]))) # use percentage to get the T0 upstream value
|
|
89
|
-
|
|
90
|
-
dP0_dr = float(interp1d(row.percent_hub_shroud, np.gradient(row.P0,row_radius))((r-row_radius[0])/(row_radius[-1]-row_radius[0]))) # use percentage to get
|
|
91
|
-
|
|
92
|
-
U_up = float(interp1d(upstream.percent_hub_shroud,up_radius*omega)((r-row_radius[0])/(row_radius[-1]-row_radius[0]))) # use percentage to get the T0 upstream value
|
|
93
|
-
dVtup_dr = float(interp1d(upstream.percent_hub_shroud,np.gradient(upstream.Vt,up_radius))((r-row_radius[0])/(row_radius[-1]-row_radius[0])))
|
|
94
|
-
Vtup = float(interp1d(upstream.percent_hub_shroud,upstream.Vt)((r-row_radius[0])/(row_radius[-1]-row_radius[0])))
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
dT0_dr = dT0up_dr - 1/row.Cp*(U_up*dVtup_dr + Vtup*omega - (U*dVt_dr+Vt*omega)) # Eqn 8
|
|
98
|
-
# if row.loss_function.LossType == LossType.Pressure: # type: ignore
|
|
99
|
-
# dP0_dr = dP0up_dr-row.Yp*(dP0up_dr - dP_dr) # Eqn 9
|
|
100
|
-
|
|
101
|
-
C = Vm**2*(1+np.tan(alpha)**2)/(2*Cp*T0)
|
|
102
|
-
if (C>1) & ((gamma/(gamma-1))<2):
|
|
103
|
-
raise Exception("Invalid value of C {C}, change reduce alpha or Vm")
|
|
104
|
-
B = (1-C)**(gamma/(gamma-1))
|
|
105
|
-
A = P0 * gamma/(gamma-1) * (1-C)**(1/(gamma-1)) * (1+np.tan(alpha)**2)/(2*Cp)
|
|
106
|
-
|
|
107
|
-
epsilon = 1e-10 # or another small threshold
|
|
108
|
-
if abs(rm) > epsilon:
|
|
109
|
-
dVm_dr = Vm/(2*T0**2) * dT0_dr - rho/(2*A*Vm) * (Vt**2/r + Vm/rm*np.cos(phi)-Vr*dVm_dm) + B/(2*A*Vm) * dP0_dr # Eqn 21
|
|
110
|
-
else:
|
|
111
|
-
dVm_dr = Vm/(2*T0**2) * dT0_dr - rho/(2*A*Vm) * (Vt**2/r) + B/(2*A*Vm) * dP0_dr # Eqn 21, modified
|
|
112
|
-
|
|
113
|
-
ydot = np.array([dP0_dr,dT0_dr,dVm_dr])
|
|
114
|
-
|
|
115
|
-
return ydot
|
|
116
|
-
|
|
117
|
-
T0 = row.T0
|
|
118
|
-
|
|
119
|
-
P0 = row.P0
|
|
120
|
-
Vm = row.Vm
|
|
121
|
-
|
|
122
|
-
# Estimate the Vt based on a given turning angle
|
|
123
|
-
mean_radius = row_radius.mean()
|
|
124
|
-
tip_radius = row_radius[-1]
|
|
125
|
-
hub_radius = row_radius[0]
|
|
126
|
-
|
|
127
|
-
T0m = interp1d(row.percent_hub_shroud,T0)(0.5);
|
|
128
|
-
P0m = interp1d(row.percent_hub_shroud,P0)(0.5); Vmm = interp1d(row.percent_hub_shroud,Vm)(0.5)
|
|
129
|
-
# We are solving for the values of these quantities at row exit
|
|
130
|
-
ics = np.array([P0m,T0m,Vmm])
|
|
131
|
-
|
|
132
|
-
rm_to_tip = np.linspace(mean_radius,tip_radius)
|
|
133
|
-
res1 = odeint(ode_radeq_streamtube, ics, rm_to_tip, tfirst=True)
|
|
134
|
-
|
|
135
|
-
rm_to_hub = np.flip(np.linspace(hub_radius,mean_radius))
|
|
136
|
-
res2 = odeint(ode_radeq_streamtube, ics, rm_to_hub, tfirst=True)
|
|
137
|
-
|
|
138
|
-
res2 = np.flipud(res2)
|
|
139
|
-
res = np.concatenate([res2[:-1,:],res1])
|
|
140
|
-
r = np.concatenate([np.flip(rm_to_hub)[:-1], rm_to_tip])
|
|
141
|
-
|
|
142
|
-
P0_new = interp1d(r,res[:,0])(row_radius)
|
|
143
|
-
T0_new = interp1d(r,res[:,1])(row_radius)
|
|
144
|
-
Vm_new = interp1d(r,res[:,2])(row_radius)
|
|
145
|
-
|
|
146
|
-
row.P0 = P0_new
|
|
147
|
-
row.T0 = T0_new
|
|
148
|
-
row.Vm = Vm_new
|
|
149
|
-
if row.row_type == RowType.Rotor:
|
|
150
|
-
# U(VT1-VT2) = Power/massflow; VT2 = VT1 - Power/massflow
|
|
151
|
-
row.Vt = upstream.Vt-row.power/(row.total_massflow*row.U)
|
|
152
|
-
row.alpha2 = np.arctan2(row.Vt,row.Vx)
|
|
153
|
-
elif row.row_type == RowType.Stator:
|
|
154
|
-
row.Vt = row.Vm*np.cos(row.phi)*np.tan(row.alpha2)
|
|
155
|
-
row.Vr = row.Vm*np.sin(row.phi)
|
|
156
|
-
row.Vx = row.Vm*np.cos(row.phi)
|
|
157
|
-
|
|
158
|
-
return row
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
def radeq_normalized(row:BladeRow,upstream:BladeRow) -> BladeRow:
|
|
162
|
-
"""Solves the radial equilibrium equation for axial or radial machines and returns the convergence.
|
|
163
|
-
|
|
164
|
-
Args:
|
|
165
|
-
row (BladeRow): Current row
|
|
166
|
-
upstream (BladeRow): Previous row
|
|
167
|
-
|
|
168
|
-
Returns:
|
|
169
|
-
BladeRow: current row with Vt, T0, P0, and Vm calculated
|
|
170
|
-
"""
|
|
171
|
-
_,row_radius = row.streamline.get_point(row.percent_hub_shroud) # Use these for gradient
|
|
172
|
-
_,up_radius = upstream.streamline.get_point(upstream.percent_hub_shroud)
|
|
173
|
-
|
|
174
|
-
def ode_radeq_streamtube(t:np.ndarray,y:np.ndarray):
|
|
175
|
-
"""Solves the radial equilibrium equation for a streamtube
|
|
176
|
-
|
|
177
|
-
Args:
|
|
178
|
-
t (np.ndarray): percent from hub to shroud
|
|
179
|
-
y (np.ndarray): Array containing [P0,Vt,VtU,T0]
|
|
180
|
-
|
|
181
|
-
"""
|
|
182
|
-
P0 = y[0]
|
|
183
|
-
T0 = y[1]
|
|
184
|
-
Vm = y[2]
|
|
185
|
-
if t>1:
|
|
186
|
-
return [0,0,0]
|
|
187
|
-
elif t<0:
|
|
188
|
-
return [0,0,0]
|
|
189
|
-
|
|
190
|
-
_,r = row.streamline.get_point()
|
|
191
|
-
Cp = row.Cp
|
|
192
|
-
# Interpolate angle of inclination (phi), exit flow angle (alpha), radius of curvature (rm) at a particular percentage from hub to shroud
|
|
193
|
-
phi = interp1d(row.percent_hub_shroud, row.phi)(t)
|
|
194
|
-
alpha = interp1d(row.percent_hub_shroud, row.alpha2)(t)
|
|
195
|
-
rm = interp1d(row.percent_hub_shroud,row.rm)(t)
|
|
196
|
-
rho = interp1d(row.percent_hub_shroud,row.rho)(t)
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
if (row.row_type == RowType.Rotor):
|
|
200
|
-
omega = row.rpm*np.pi/30
|
|
201
|
-
U = omega*r
|
|
202
|
-
else:
|
|
203
|
-
omega = 0
|
|
204
|
-
U = 0
|
|
205
|
-
gamma = row.gamma
|
|
206
|
-
|
|
207
|
-
# Solve the Radial Equlibrium
|
|
208
|
-
Vt = Vm*np.cos(phi)*np.tan(alpha)
|
|
209
|
-
Vr = float(interp1d(row.percent_hub_shroud, row.Vr)(t))
|
|
210
|
-
# Estimations: need the radius of the streamline to compute gradients
|
|
211
|
-
dVm_dr = interp1d(row_radius,np.gradient(row.Vm, row_radius))(r)
|
|
212
|
-
dVt_dr = dVm_dr*np.cos(phi)*np.tan(alpha)
|
|
213
|
-
|
|
214
|
-
dVm_dm = interp1d(row_radius, np.gradient(Vm, r)) + interp1d(x, np.gradient(Vm, r))
|
|
215
|
-
|
|
216
|
-
# Upstream: We interpolate the gradient based on the percentage from hub to shroud
|
|
217
|
-
dT0up_dr = interp1d(upstream.percent_hub_shroud,
|
|
218
|
-
np.gradient(upstream.T0,up_radius))(t)
|
|
219
|
-
dP0up_dr = interp1d(upstream.percent_hub_shroud,
|
|
220
|
-
np.gradient(upstream.P0,up_radius))(t)
|
|
221
|
-
dP0_dr = interp1d(upstream.percent_hub_shroud,
|
|
222
|
-
np.gradient(upstream.P0,up_radius))(t)
|
|
223
|
-
|
|
224
|
-
U_up = interp1d(upstream.percent_hub_shroud,up_radius*omega)(t) # use percentage to get the T0 upstream value
|
|
225
|
-
dVtup_dr = interp1d(upstream.percent_hub_shroud,np.gradient(upstream.Vt,up_radius))(t)
|
|
226
|
-
Vtup = interp1d(upstream.percent_hub_shroud,upstream.Vt)(t)
|
|
227
|
-
|
|
228
|
-
dP_dr = interp1d(row.percent_hub_shroud,np.gradient(row.P,row_radius))(t)
|
|
229
|
-
dT0_dr = dT0up_dr - 1/row.Cp*(U_up*dVtup_dr + Vtup*omega - (U*dVt_dr+Vt*omega)) # Eqn 8
|
|
230
|
-
# if row.loss_function.LossType == LossType.Pressure: # type: ignore
|
|
231
|
-
# dP0_dr = dP0up_dr-row.Yp*(dP0up_dr - dP_dr) # Eqn 9
|
|
232
|
-
|
|
233
|
-
C = Vm**2*(1+np.cos(phi)**2 * np.tan(alpha)**2)/(2*Cp*T0)
|
|
234
|
-
B = (1-C)**(gamma/(gamma-1))
|
|
235
|
-
A = P0 * gamma/(gamma-1) * (1-C)**(1/(gamma-1))
|
|
236
|
-
dVm_dr = 1/(2*Vm*A) * (rho*(Vt/r - Vm**2/rm * np.cos(phi)-Vr*dVm_dm) - dP0_dr*B) + 1/(2*T0) *dT0_dr # Eqn 6
|
|
237
|
-
|
|
238
|
-
ydot = np.array([dP0_dr,dT0_dr,dVm_dr])
|
|
239
|
-
|
|
240
|
-
return ydot
|
|
241
|
-
|
|
242
|
-
T0 = row.T0
|
|
243
|
-
P0 = row.P0
|
|
244
|
-
Vm = row.Vm
|
|
245
|
-
|
|
246
|
-
# Estimate the Vt based on a given turning angle
|
|
247
|
-
_, mean_radius = row.streamline.get_point(0.5)
|
|
248
|
-
_, tip_radius = row.streamline.get_point(1)
|
|
249
|
-
_, hub_radius = row.streamline.get_point(0)
|
|
250
|
-
|
|
251
|
-
T0m = interp1d(row.percent_hub_shroud,T0)(0.5);
|
|
252
|
-
P0m = interp1d(row.percent_hub_shroud,P0)(0.5);
|
|
253
|
-
Vmm = interp1d(row.percent_hub_shroud,Vm)(0.5)
|
|
254
|
-
# We are solving for the values of these quantities at row exit
|
|
255
|
-
ics = np.array([P0m,T0m,Vmm])
|
|
256
|
-
|
|
257
|
-
mid_to_tip = np.linspace(0,1)
|
|
258
|
-
res1 = odeint(ode_radeq_streamtube, ics, mid_to_tip, tfirst=True) # Results
|
|
259
|
-
|
|
260
|
-
mid_to_hub = np.flip(np.linspace(hub_radius,mean_radius))
|
|
261
|
-
res2 = odeint(ode_radeq_streamtube, ics, mid_to_hub, tfirst=True) # Results
|
|
262
|
-
|
|
263
|
-
res2 = np.flipud(res2)
|
|
264
|
-
res = np.concatenate([res2[:-1,:],res1]) # Combine the results
|
|
265
|
-
t = np.concatenate([np.flip(mid_to_hub)[:-1], mid_to_tip])
|
|
266
|
-
|
|
267
|
-
P0_new = interp1d(t,res[:,0])(row.percent_hub_shroud)
|
|
268
|
-
T0_new = interp1d(t,res[:,1])(row.percent_hub_shroud)
|
|
269
|
-
Vm_new = interp1d(t,res[:,2])(row.percent_hub_shroud)
|
|
270
|
-
|
|
271
|
-
row.P0 = P0_new
|
|
272
|
-
row.T0 = T0_new
|
|
273
|
-
row.Vm = Vm_new
|
|
274
|
-
if row.row_type == RowType.Rotor:
|
|
275
|
-
# U(VT1-VT2) = Power/massflow; VT2 = VT1 - Power/massflow
|
|
276
|
-
row.Vt = upstream.Vt-row.power/(row.total_massflow*row.U)
|
|
277
|
-
row.alpha2 = np.arctan2(row.Vt,row.Vx)
|
|
278
|
-
elif row.row_type == RowType.Stator:
|
|
279
|
-
row.Vt = row.Vm*np.cos(row.phi)*np.tan(row.alpha2)
|
|
280
|
-
row.Vr = row.Vm*np.sin(row.phi)
|
|
281
|
-
row.Vx = row.Vm*np.cos(row.phi)
|
|
282
|
-
|
|
283
|
-
return row
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|