turbo-design 1.3.4__py3-none-any.whl → 1.3.5__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.3.4.dist-info → turbo_design-1.3.5.dist-info}/METADATA +1 -1
- {turbo_design-1.3.4.dist-info → turbo_design-1.3.5.dist-info}/RECORD +12 -12
- turbodesign/bladerow.py +12 -12
- turbodesign/enums.py +6 -6
- turbodesign/inlet.py +14 -8
- turbodesign/loss/turbine/fixedpressureloss.py +1 -1
- turbodesign/outlet.py +2 -1
- turbodesign/passage.py +4 -5
- turbodesign/spool.py +1 -1
- turbodesign/td_math.py +18 -16
- turbodesign/turbinespool.py +20 -19
- {turbo_design-1.3.4.dist-info → turbo_design-1.3.5.dist-info}/WHEEL +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
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=351FMt9UtbFMAKtU-mDkJ12hmIdaaa4qF6K6Q-ZYkBM,25063
|
|
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=evDtUFOYhfZKTVAsDWzxRzUX20gTvfjj0uybaWg4CsI,427
|
|
7
|
-
turbodesign/enums.py,sha256=
|
|
8
|
-
turbodesign/inlet.py,sha256=
|
|
7
|
+
turbodesign/enums.py,sha256=WC6VPmHw3UF1zR1SLjj8z00gIWSNso66MShFGoYRY4U,1164
|
|
8
|
+
turbodesign/inlet.py,sha256=5uja906IA-_gca4FJykZvFLJ1he6HRy5pZDNQE1D2_g,7945
|
|
9
9
|
turbodesign/isentropic.py,sha256=YLTmNx69e_M5fTuLOmk_KvaQ6ABv0aZsityfBihJOmI,2003
|
|
10
10
|
turbodesign/loss/__init__.py,sha256=ZJomzXa6ElduFruURukCrFwJQXMWS2aW8JSaVQ-M2r8,46
|
|
11
11
|
turbodesign/loss/compressor/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
@@ -15,19 +15,19 @@ turbodesign/loss/turbine/__init__.py,sha256=d1UrbiIicO60FhDlOemo_irYW2asUaYoqlXU
|
|
|
15
15
|
turbodesign/loss/turbine/ainleymathieson.py,sha256=8UbugNmxI12I68HGctJe2lQpqjKZN1b40UOTzqU6hQQ,5861
|
|
16
16
|
turbodesign/loss/turbine/craigcox.py,sha256=TrbNdpGdyD5kTRFKfNmbRDhCOjA0-GT5xoluLQpO1gA,9664
|
|
17
17
|
turbodesign/loss/turbine/fixedefficiency.py,sha256=JJv4GUS5q9pvuf3akjBtlcHOykRYmRVFfDDrdWqH6S4,774
|
|
18
|
-
turbodesign/loss/turbine/fixedpressureloss.py,sha256=
|
|
18
|
+
turbodesign/loss/turbine/fixedpressureloss.py,sha256=sgkm6uQwz6Qz2LDCEmir46aJRSPLAdCKpDyR1hNdgQ8,682
|
|
19
19
|
turbodesign/loss/turbine/kackerokapuu.py,sha256=hUmZdyA1hAhN3_xbwBhka2dyk0Aq9rqq62S2ghuKSOk,5071
|
|
20
20
|
turbodesign/loss/turbine/traupel.py,sha256=aZxFE9JDcCfi1gy-fqS1SxjjlhuDG-H-g3LPurty1M0,4164
|
|
21
21
|
turbodesign/lossinterp.py,sha256=B2KEobp-nD9jwD6UINgBmTlH9kKyWg3UNvXxqfUsr-k,6198
|
|
22
|
-
turbodesign/outlet.py,sha256
|
|
23
|
-
turbodesign/passage.py,sha256=
|
|
22
|
+
turbodesign/outlet.py,sha256=MaZJ-mDuLvh19AashnMQLx2XlR-Rk1r0HQS4kE0OxeI,2191
|
|
23
|
+
turbodesign/passage.py,sha256=bp1fyfQ3rJpEiaYju4_hZ6O07AAOaWu7prz6B-AwtSw,12071
|
|
24
24
|
turbodesign/radeq.py,sha256=KiZybA8EtOKMzszstdlaR-sF5KI9nUBgYOGZYLU1x4I,6516
|
|
25
25
|
turbodesign/rotor.py,sha256=tHl9o5H4aQ6Etd4gqa8Ime1UK7k0de4GLt5Yb1sJdGs,1376
|
|
26
26
|
turbodesign/solve_radeq.py,sha256=nLYlRtXElPgHaoUP9jwMulRmYKTJs_uQ1eCulk2V59I,1938
|
|
27
|
-
turbodesign/spool.py,sha256=
|
|
27
|
+
turbodesign/spool.py,sha256=81UFbBi5JKm0RJ_hjB40bKWeCXx0V2lt0b2VAwOtTDU,14376
|
|
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.3.
|
|
32
|
-
turbo_design-1.3.
|
|
33
|
-
turbo_design-1.3.
|
|
29
|
+
turbodesign/td_math.py,sha256=qlLlAMB3kHUMdkvr9sOKl-rPShDx-XQCqG9DHOr7Vis,16268
|
|
30
|
+
turbodesign/turbinespool.py,sha256=vpmrNmZ23k2wU7b9GAZrT3dOpX3otkpTtjAlfCY92sQ,25271
|
|
31
|
+
turbo_design-1.3.5.dist-info/METADATA,sha256=uv1dI15QIhWediM6cMY8tRS-u73pnhAwXcpDPIAQ5sI,683
|
|
32
|
+
turbo_design-1.3.5.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
33
|
+
turbo_design-1.3.5.dist-info/RECORD,,
|
turbodesign/bladerow.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from dataclasses import field, Field
|
|
2
|
-
from typing import Any, Callable, List, Tuple, Union
|
|
2
|
+
from typing import Any, Callable, List, Optional, Tuple, Union
|
|
3
3
|
from .enums import RowType, PowerType
|
|
4
4
|
import numpy as np
|
|
5
5
|
import numpy.typing as npt
|
|
@@ -99,10 +99,10 @@ class BladeRow:
|
|
|
99
99
|
rm: npt.NDArray = field(default_factory=lambda: np.array([0])) # Curvature
|
|
100
100
|
incli_curve_radii: npt.NDArray = field(default_factory=lambda: np.array([0])) # radius at which curvature was evaluated
|
|
101
101
|
mprime:npt.NDArray = field(default_factory=lambda: np.array([0])) # Mprime distance
|
|
102
|
-
axial_chord:float = 0
|
|
103
102
|
|
|
104
103
|
Yp: float = 0 # Pressure loss
|
|
105
104
|
power:float = 0 # Watts
|
|
105
|
+
power_mean:float = 0
|
|
106
106
|
power_distribution:npt.NDArray # How power is divided by radius. Example: Equal distribution [0.33 0.33 0.33]. More at Tip [0.2,0.3,0.5]. More at Hub [0.6 0.5 ]
|
|
107
107
|
P0_P:float = 0 # Total to Static Pressure Ratio
|
|
108
108
|
Power_Type:PowerType
|
|
@@ -132,7 +132,7 @@ class BladeRow:
|
|
|
132
132
|
Returns:
|
|
133
133
|
List[float]: _description_
|
|
134
134
|
"""
|
|
135
|
-
return self._inlet_to_outlet_pratio
|
|
135
|
+
return self._inlet_to_outlet_pratio # type: ignore
|
|
136
136
|
|
|
137
137
|
@inlet_to_outlet_pratio.setter
|
|
138
138
|
def inlet_to_outlet_pratio(self,val:Tuple[float,float]=(0.06,0.7)):
|
|
@@ -355,7 +355,7 @@ class BladeRow:
|
|
|
355
355
|
"""
|
|
356
356
|
self._beta1_metal = np.radians(convert_to_ndarray(beta1_metal))
|
|
357
357
|
if len(percent) != len(beta1_metal):
|
|
358
|
-
percent = np.linspace(0,1,len(self._beta1_metal)).tolist()
|
|
358
|
+
percent = np.linspace(0,1,len(self._beta1_metal)).tolist() # type: ignore
|
|
359
359
|
self.beta1_metal_radii = convert_to_ndarray(percent)
|
|
360
360
|
self.beta1_fixed = True
|
|
361
361
|
self.beta1 = self.beta1_metal.copy()
|
|
@@ -371,7 +371,7 @@ class BladeRow:
|
|
|
371
371
|
"""
|
|
372
372
|
self._beta2_metal = np.radians(convert_to_ndarray(beta2_metal))
|
|
373
373
|
if len(percent) != len(beta2_metal):
|
|
374
|
-
percent = np.linspace(0,1,len(self._beta2_metal)).tolist()
|
|
374
|
+
percent = np.linspace(0,1,len(self._beta2_metal)).tolist() # type: ignore
|
|
375
375
|
self.beta2_metal_radii = convert_to_ndarray(percent)
|
|
376
376
|
self.beta2_fixed = True
|
|
377
377
|
self.beta2 = self._beta2_metal.copy()
|
|
@@ -418,7 +418,7 @@ class BladeRow:
|
|
|
418
418
|
code to do something with machine learning
|
|
419
419
|
return pressure loss
|
|
420
420
|
"""
|
|
421
|
-
self.loss_function = model
|
|
421
|
+
self.loss_function = model # type: ignore
|
|
422
422
|
|
|
423
423
|
@property
|
|
424
424
|
def te_pitch(self):
|
|
@@ -568,11 +568,11 @@ def interpolate_streamline_radii(row:BladeRow,passage:Passage,num_streamlines:in
|
|
|
568
568
|
row.T_is = interpolate_quantities(row.T_is,row.percent_hub_shroud,streamline_percent_length)
|
|
569
569
|
row.rho = interpolate_quantities(row.rho,row.percent_hub_shroud,streamline_percent_length)
|
|
570
570
|
|
|
571
|
-
if row.row_type == RowType.Inlet:
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
elif row.row_type == RowType.Outlet:
|
|
575
|
-
|
|
571
|
+
# if row.row_type == RowType.Inlet:
|
|
572
|
+
# row.P0_fun = interp1d(row.percent_hub_shroud,row.P0)
|
|
573
|
+
# row.T0_fun = interp1d(row.percent_hub_shroud,row.T0)
|
|
574
|
+
# elif row.row_type == RowType.Outlet:
|
|
575
|
+
# row.P_fun = interp1d(row.percent_hub_shroud,row.P)
|
|
576
576
|
|
|
577
577
|
return row
|
|
578
578
|
|
|
@@ -611,7 +611,7 @@ def interpolate_quantities(q:npt.NDArray,r:npt.NDArray,r2:npt.NDArray):
|
|
|
611
611
|
else:
|
|
612
612
|
return interp1d(r,q,kind='linear')(r2)
|
|
613
613
|
|
|
614
|
-
def compute_gas_constants(row:BladeRow,fluid:Solution=None) -> None:
|
|
614
|
+
def compute_gas_constants(row:BladeRow,fluid:Optional[Solution]=None) -> None:
|
|
615
615
|
"""Updates the Cp, Gamma, and density for a blade row. If fluid is not specified then only density and viscosity is updated.
|
|
616
616
|
|
|
617
617
|
Args:
|
turbodesign/enums.py
CHANGED
|
@@ -13,8 +13,8 @@ class RowType(Enum):
|
|
|
13
13
|
Outlet = 4
|
|
14
14
|
|
|
15
15
|
class MassflowConstraint(Enum):
|
|
16
|
-
MatchMassFlow
|
|
17
|
-
BalanceMassFlow
|
|
16
|
+
MatchMassFlow = 1 # Changes the exit angles to match the massflow
|
|
17
|
+
BalanceMassFlow = 2 # Keeps the exit angle but balances the massflow between the stages as best it can. This will affect the static pressure at the stage exit
|
|
18
18
|
|
|
19
19
|
class PowerType(Enum):
|
|
20
20
|
"""The code for BladeRow will assume a PowerType automatically depending on what you specify. If you specify the blade row to have P0_P which is the stator inlet total pressure to rotor exit static pressure then that will be used to calculate all the quantities.
|
|
@@ -27,10 +27,10 @@ class PowerType(Enum):
|
|
|
27
27
|
|
|
28
28
|
"""
|
|
29
29
|
#
|
|
30
|
-
P0_P
|
|
31
|
-
T0
|
|
30
|
+
P0_P = 1
|
|
31
|
+
T0 = 2
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
class PassageType(Enum):
|
|
35
|
-
Centrifugal
|
|
36
|
-
Axial
|
|
35
|
+
Centrifugal=0
|
|
36
|
+
Axial=1
|
turbodesign/inlet.py
CHANGED
|
@@ -40,8 +40,16 @@ class Inlet(BladeRow):
|
|
|
40
40
|
self.T0 = convert_to_ndarray(T0)
|
|
41
41
|
self.P0 = convert_to_ndarray(P0)
|
|
42
42
|
self.percent_hub_shroud = convert_to_ndarray(percent_radii)
|
|
43
|
+
|
|
44
|
+
def initialize_inputs(self,num_streamlines:int=5):
|
|
45
|
+
self.M = interpolate_quantities(self.M, self.percent_hub_shroud, np.linspace(0,1,num_streamlines))
|
|
46
|
+
self.P0 = interpolate_quantities(self.P0,self.percent_hub_shroud, np.linspace(0,1,num_streamlines))
|
|
47
|
+
self.T0 = interpolate_quantities(self.T0,self.percent_hub_shroud, np.linspace(0,1,num_streamlines))
|
|
48
|
+
# if it's inlet alpha and beta are the same, relative flow angle = absolute.
|
|
49
|
+
self.beta1 = interpolate_quantities(self.beta1,self.percent_hub_shroud, np.linspace(0,1,num_streamlines))
|
|
50
|
+
self.beta2 = np.radians(convert_to_ndarray(self.beta1))
|
|
51
|
+
self.alpha1 = np.radians(convert_to_ndarray(self.beta1))
|
|
43
52
|
|
|
44
|
-
|
|
45
53
|
def initialize_fluid(self,fluid:Solution=None,R:float=287.15,gamma:float=1.4,Cp:float=1024):
|
|
46
54
|
"""Initialize the inlet using the fluid. This function should be called by a class that inherits from spool
|
|
47
55
|
|
|
@@ -54,10 +62,6 @@ class Inlet(BladeRow):
|
|
|
54
62
|
"""
|
|
55
63
|
self.loss_function = None
|
|
56
64
|
|
|
57
|
-
# if it's inlet alpha and beta are the same, relative flow angle = absolute.
|
|
58
|
-
self.beta2 = np.radians(convert_to_ndarray(self.beta1))
|
|
59
|
-
self.alpha1 = np.radians(convert_to_ndarray(self.beta1))
|
|
60
|
-
|
|
61
65
|
if fluid:
|
|
62
66
|
fluid.TP = self.T0.mean(),self.P0.mean()
|
|
63
67
|
self.gamma = fluid.cp/fluid.cv
|
|
@@ -76,6 +80,10 @@ class Inlet(BladeRow):
|
|
|
76
80
|
self.rpm = 0
|
|
77
81
|
self.beta1_metal = [0]
|
|
78
82
|
self.beta2_metal = [0]
|
|
83
|
+
if len(self.percent_hub_shroud) == 1:
|
|
84
|
+
self.percent_hub_shroud = np.linspace(0,1,2)
|
|
85
|
+
self.P0 = self.percent_hub_shroud*0+self.P0[0]
|
|
86
|
+
self.T0 = self.percent_hub_shroud*0+self.T0[0]
|
|
79
87
|
self.P0_fun = interp1d(self.percent_hub_shroud,self.P0)
|
|
80
88
|
self.T0_fun = interp1d(self.percent_hub_shroud,self.T0)
|
|
81
89
|
self.mprime = [0]
|
|
@@ -91,8 +99,6 @@ class Inlet(BladeRow):
|
|
|
91
99
|
"""
|
|
92
100
|
# Perform Calculations on Velocity
|
|
93
101
|
Vm_prev = 0; Vm_err = 0
|
|
94
|
-
t,x,radius = passage.get_streamline(self.percent_hub_shroud)
|
|
95
|
-
radius = radius[0]
|
|
96
102
|
|
|
97
103
|
cutline,_,_ = passage.get_cutting_line(self.location)
|
|
98
104
|
self.x,self.r = cutline.get_point(np.linspace(0,1,num_streamlines))
|
|
@@ -116,7 +122,7 @@ class Inlet(BladeRow):
|
|
|
116
122
|
rho_mean = self.rho.mean()
|
|
117
123
|
for i in range(len(self.massflow)-1):
|
|
118
124
|
tube_massflow = self.massflow[i+1]-self.massflow[i]
|
|
119
|
-
if np.abs((self.x[
|
|
125
|
+
if np.abs((self.x[-1]-self.x[0]))<1E-5: # Axial Machines
|
|
120
126
|
self.Vm[i+1] = tube_massflow/(rho_mean*np.pi*(self.r[i+1]**2-self.r[i]**2))
|
|
121
127
|
else: # Radial Machines
|
|
122
128
|
dx = self.x[i]-self.x[i-1]
|
turbodesign/outlet.py
CHANGED
|
@@ -12,7 +12,7 @@ from scipy.interpolate import interp1d
|
|
|
12
12
|
class Outlet(BladeRow):
|
|
13
13
|
P_fun:interp1d
|
|
14
14
|
|
|
15
|
-
def __init__(self,P:Union[float,List[float]],percent_radii:List[float],num_streamlines:int=3,location:float=1):
|
|
15
|
+
def __init__(self,P:Union[float,List[float]],percent_radii:Union[List[float],float],num_streamlines:int=3,location:float=1):
|
|
16
16
|
"""Initialize the outlet
|
|
17
17
|
|
|
18
18
|
Args:
|
|
@@ -23,6 +23,7 @@ class Outlet(BladeRow):
|
|
|
23
23
|
self.percent_hub_shroud = convert_to_ndarray(percent_radii)
|
|
24
24
|
if len(self.percent_hub_shroud)==1:
|
|
25
25
|
self.percent_hub_shroud = np.arange(0,1,num_streamlines)
|
|
26
|
+
self.P = self.P[0]+0*self.percent_hub_shroud*0
|
|
26
27
|
self.P_fun = interp1d(self.percent_hub_shroud,self.P)
|
|
27
28
|
self.row_type = RowType.Outlet
|
|
28
29
|
self.loss_function = None
|
turbodesign/passage.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import List, Tuple
|
|
1
|
+
from typing import List, Tuple, Union
|
|
2
2
|
import numpy as np
|
|
3
3
|
import numpy.typing as npt
|
|
4
4
|
from scipy.interpolate import PchipInterpolator, interp1d
|
|
@@ -27,8 +27,8 @@ class Passage:
|
|
|
27
27
|
r_streamlines:npt.NDArray
|
|
28
28
|
hub_arc_len:float
|
|
29
29
|
|
|
30
|
-
def __init__(self,xhub:List[float],rhub:List[float],
|
|
31
|
-
xshroud:List[float],rshroud:List[float],
|
|
30
|
+
def __init__(self,xhub:Union[npt.NDArray,List[float]],rhub:Union[npt.NDArray,List[float]],
|
|
31
|
+
xshroud:Union[npt.NDArray,List[float]],rshroud:Union[npt.NDArray,List[float]],
|
|
32
32
|
passageType:PassageType=PassageType.Axial):
|
|
33
33
|
"""_summary_
|
|
34
34
|
|
|
@@ -81,8 +81,7 @@ class Passage:
|
|
|
81
81
|
rhub = self.rhub(t)
|
|
82
82
|
xshroud = self.xshroud(t)
|
|
83
83
|
rshroud = self.rshroud(t)
|
|
84
|
-
x_streamline[i],r_streamline[i] = line2D([xhub,rhub],[xshroud,rshroud]).get_point(t_radial)
|
|
85
|
-
|
|
84
|
+
x_streamline[i] ,r_streamline[i] = line2D([xhub,rhub],[xshroud,rshroud]).get_point(t_radial)
|
|
86
85
|
return t_streamline,x_streamline,r_streamline
|
|
87
86
|
|
|
88
87
|
@staticmethod
|
turbodesign/spool.py
CHANGED
turbodesign/td_math.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import List, Tuple
|
|
1
|
+
from typing import List, Optional, Tuple
|
|
2
2
|
import numpy as np
|
|
3
3
|
import math
|
|
4
4
|
import numpy.typing as npt
|
|
@@ -93,7 +93,7 @@ def compute_reynolds(rows:List[BladeRow],passage:Passage):
|
|
|
93
93
|
|
|
94
94
|
for i in range(1,len(rows)):
|
|
95
95
|
row = rows[i]
|
|
96
|
-
xr = passage.get_xr_slice(0.5,
|
|
96
|
+
xr = passage.get_xr_slice(0.5,(rows[i-1].location,row.percent_hub))
|
|
97
97
|
dx = np.diff(xr[:,0])
|
|
98
98
|
dr = np.diff(xr[:,1])
|
|
99
99
|
c = np.sum(np.sqrt(dx**2+dr**2))
|
|
@@ -124,8 +124,8 @@ def compute_power(row:BladeRow,upstream:BladeRow) -> None:
|
|
|
124
124
|
row.eta_total = 0
|
|
125
125
|
row.stage_loading = 0
|
|
126
126
|
row.euler_power = 0
|
|
127
|
-
row.T_is = 0
|
|
128
|
-
row.T0_is = 0
|
|
127
|
+
row.T_is = 0 * row.T0
|
|
128
|
+
row.T0_is = 0 * row.T0 # Make it an array
|
|
129
129
|
else:
|
|
130
130
|
P0_P = (upstream.P0/row.P).mean()
|
|
131
131
|
row.T_is = upstream.T0 * (1/P0_P)**((row.gamma-1)/row.gamma)
|
|
@@ -165,7 +165,7 @@ def compute_quantities(row:BladeRow,upstream:BladeRow):
|
|
|
165
165
|
row.T = (row.P/row.P0R)**((row.gamma-1)/row.gamma) * row.T0R
|
|
166
166
|
row.T0 = (1+(row.gamma-1)/2 * row.M**2) * row.T
|
|
167
167
|
row.power_distribution = row.massflow * row.Cp * (upstream.T0 - row.T0)
|
|
168
|
-
row.power = np.
|
|
168
|
+
row.power = np.trapezoid(row.power_distribution,row.r-row.r[0])
|
|
169
169
|
row.power_mean = row.massflow[-1] * row.Cp * (upstream.T0.mean()-row.T0.mean())
|
|
170
170
|
|
|
171
171
|
elif row.loss_function.loss_type == LossType.Enthalpy:
|
|
@@ -175,7 +175,7 @@ def compute_quantities(row:BladeRow,upstream:BladeRow):
|
|
|
175
175
|
|
|
176
176
|
def calculate_power(T0:npt.NDArray):
|
|
177
177
|
row.power_distribution = row.massflow * row.Cp * (upstream.T0 - T0)
|
|
178
|
-
row.power = np.
|
|
178
|
+
row.power = np.trapezoid(row.power_distribution,row.r-row.r[0])
|
|
179
179
|
row.power_mean = row.massflow[-1] * row.Cp * (upstream.T0.mean() - T0.mean())
|
|
180
180
|
|
|
181
181
|
# Factor in T0R_drop. Convert T0R drop to absolute terms
|
|
@@ -206,7 +206,7 @@ def compute_quantities(row:BladeRow,upstream:BladeRow):
|
|
|
206
206
|
row.T0R = row.T + row.W**2 / (2*row.Cp)
|
|
207
207
|
row.P0R = row.P*(row.T0R/row.T)**((row.gamma)/(row.gamma-1))
|
|
208
208
|
|
|
209
|
-
def stator_calc(row:BladeRow,upstream:BladeRow,downstream:BladeRow=None,calculate_vm:bool=True):
|
|
209
|
+
def stator_calc(row:BladeRow,upstream:BladeRow,downstream:Optional[BladeRow]=None,calculate_vm:bool=True):
|
|
210
210
|
"""Given P0, T0, P, alpha2 of stator calculate all other quantities
|
|
211
211
|
|
|
212
212
|
Usage:
|
|
@@ -233,8 +233,8 @@ def stator_calc(row:BladeRow,upstream:BladeRow,downstream:BladeRow=None,calculat
|
|
|
233
233
|
row.P0 = upstream.P0 - row.Yp*(upstream.P0-row.P)
|
|
234
234
|
|
|
235
235
|
if downstream is not None:
|
|
236
|
-
row.P0_P = row.P0/downstream.P
|
|
237
|
-
row.rp = (row.P-downstream.P)/(upstream.P0-downstream.P)
|
|
236
|
+
row.P0_P = float((row.P0/downstream.P).mean())
|
|
237
|
+
row.rp = ((row.P-downstream.P)/(upstream.P0-downstream.P)).mean()
|
|
238
238
|
|
|
239
239
|
if calculate_vm:
|
|
240
240
|
row.M = ((row.P0/row.P)**((row.gamma-1)/row.gamma) - 1) * 2/(row.gamma-1)
|
|
@@ -276,7 +276,7 @@ def rotor_calc(row:BladeRow,upstream:BladeRow,calculate_vm:bool=True):
|
|
|
276
276
|
# row.P = row.P0_stator_inlet*1/row.P0_P
|
|
277
277
|
|
|
278
278
|
# Static Pressure is assumed
|
|
279
|
-
row.P0_P = row.P0_stator_inlet/row.P
|
|
279
|
+
row.P0_P = (row.P0_stator_inlet/row.P).mean()
|
|
280
280
|
upstream_radius = upstream.r
|
|
281
281
|
row.U = row.omega*row.r
|
|
282
282
|
# Upstream Relative Frame Calculations
|
|
@@ -353,7 +353,7 @@ def inlet_calc(row:BladeRow):
|
|
|
353
353
|
for j in range(1,len(row.percent_hub_shroud)):
|
|
354
354
|
rho = row.rho[j]
|
|
355
355
|
tube_massflow = row.massflow[j]-row.massflow[j-1]
|
|
356
|
-
if np.abs((row.x[j]-row.x[j-1]))<1E-
|
|
356
|
+
if np.abs((row.x[j]-row.x[j-1]))<1E-6: # Axial Machines
|
|
357
357
|
total_area += np.pi*(row.r[j]**2-row.r[j-1]**2)
|
|
358
358
|
row.Vm[j] = tube_massflow/(rho*np.pi*(row.r[j]**2-row.r[j-1]**2))
|
|
359
359
|
else: # Radial Machines
|
|
@@ -364,10 +364,6 @@ def inlet_calc(row:BladeRow):
|
|
|
364
364
|
total_area += area[j]
|
|
365
365
|
row.Vm[j] = tube_massflow/(rho*area[j])
|
|
366
366
|
avg_mach = np.mean(row.M)
|
|
367
|
-
if np.mean(row.M)>0.5:
|
|
368
|
-
raise ValueError(f"High inlet mach can lead to errors iter:{iter} Mach:{avg_mach}")
|
|
369
|
-
if np.mean(row.M)<0.01:
|
|
370
|
-
raise ValueError(f"Unusually slow flow:{iter} Mach:{avg_mach}")
|
|
371
367
|
row.Vm[0] = 1/(len(row.Vm)-1)*row.Vm[1:].sum() # Initialize the value at the hub to not upset the mean
|
|
372
368
|
row.Vr = row.Vm*np.sin(row.phi)
|
|
373
369
|
row.Vt = row.Vm*np.tan(row.alpha2)
|
|
@@ -376,4 +372,10 @@ def inlet_calc(row:BladeRow):
|
|
|
376
372
|
row.M = row.V/np.sqrt(row.gamma*row.R*row.T)
|
|
377
373
|
row.T = row.T0 * 1/(1+(row.gamma-1)/2*row.M**2)
|
|
378
374
|
row.P = row.P0 * (row.T/row.T0)**(row.gamma/(row.gamma-1))
|
|
379
|
-
compute_gas_constants(row)
|
|
375
|
+
compute_gas_constants(row)
|
|
376
|
+
|
|
377
|
+
if np.mean(row.M)>0.5:
|
|
378
|
+
raise ValueError(f"High inlet mach can lead to errors iter:{iter} Mach:{avg_mach}")
|
|
379
|
+
|
|
380
|
+
if np.mean(row.M)<0.01:
|
|
381
|
+
print(f"Unusually slow flow:{iter} Mach:{avg_mach}")
|
turbodesign/turbinespool.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import List
|
|
1
|
+
from typing import List, Optional
|
|
2
2
|
from cantera.composite import Solution
|
|
3
3
|
from .bladerow import BladeRow, interpolate_streamline_radii
|
|
4
4
|
from .enums import RowType, MassflowConstraint, LossType, PassageType
|
|
@@ -20,9 +20,9 @@ class TurbineSpool(Spool):
|
|
|
20
20
|
def __init__(self,passage:Passage,
|
|
21
21
|
massflow:float,rows:List[BladeRow],
|
|
22
22
|
num_streamlines:int=3,
|
|
23
|
-
fluid:Solution=Solution('air.yaml'),
|
|
23
|
+
fluid:Optional[Solution]=Solution('air.yaml'),
|
|
24
24
|
rpm:float=-1,
|
|
25
|
-
massflow_constraint:MassflowConstraint=MassflowConstraint.MatchMassFlow):
|
|
25
|
+
massflow_constraint:MassflowConstraint=MassflowConstraint.MatchMassFlow): # type: ignore
|
|
26
26
|
"""Initializes a Turbine Spool
|
|
27
27
|
|
|
28
28
|
Args:
|
|
@@ -48,9 +48,9 @@ class TurbineSpool(Spool):
|
|
|
48
48
|
W0 = self.massflow
|
|
49
49
|
inlet = self.blade_rows[0]
|
|
50
50
|
if self.fluid:
|
|
51
|
-
inlet.initialize_fluid(self.fluid)
|
|
51
|
+
inlet.initialize_fluid(self.fluid) # type: ignore
|
|
52
52
|
else:
|
|
53
|
-
inlet.initialize_fluid(R=self.blade_rows[1].R,
|
|
53
|
+
inlet.initialize_fluid(R=self.blade_rows[1].R, # type: ignore
|
|
54
54
|
gamma=self.blade_rows[1].gamma,
|
|
55
55
|
Cp=self.blade_rows[1].Cp)
|
|
56
56
|
|
|
@@ -58,7 +58,8 @@ class TurbineSpool(Spool):
|
|
|
58
58
|
inlet.total_massflow_no_coolant = W0
|
|
59
59
|
inlet.massflow = np.linspace(0,1,self.num_streamlines)*W0
|
|
60
60
|
|
|
61
|
-
inlet.
|
|
61
|
+
inlet.initialize_inputs(self.num_streamlines)
|
|
62
|
+
inlet.initialize_velocity(self.passage,self.num_streamlines) # type: ignore
|
|
62
63
|
interpolate_streamline_radii(inlet,self.passage,self.num_streamlines)
|
|
63
64
|
|
|
64
65
|
compute_gas_constants(inlet,self.fluid)
|
|
@@ -69,10 +70,10 @@ class TurbineSpool(Spool):
|
|
|
69
70
|
|
|
70
71
|
outlet = self.blade_rows[-1]
|
|
71
72
|
for j in range(self.num_streamlines):
|
|
72
|
-
P0 = inlet.get_total_pressure(inlet.percent_hub_shroud[j])
|
|
73
|
+
P0 = inlet.get_total_pressure(inlet.percent_hub_shroud[j]) # type: ignore
|
|
73
74
|
percents = np.zeros(shape=(len(self.blade_rows)-2)) + 0.3
|
|
74
75
|
percents[-1] = 1
|
|
75
|
-
Ps_range = outlet_pressure(percents=percents,inletP0=inlet.P0[j],outletP=outlet.P[j])
|
|
76
|
+
Ps_range = outlet_pressure(percents=percents,inletP0=inlet.P0[j],outletP=outlet.P[j]) # type: ignore
|
|
76
77
|
for i in range(1,len(self.blade_rows)-1):
|
|
77
78
|
self.blade_rows[i].P[j] = Ps_range[i-1]
|
|
78
79
|
|
|
@@ -122,7 +123,7 @@ class TurbineSpool(Spool):
|
|
|
122
123
|
row.R = upstream.R
|
|
123
124
|
|
|
124
125
|
if row.row_type == RowType.Stator:
|
|
125
|
-
stator_calc(row,upstream,downstream)
|
|
126
|
+
stator_calc(row,upstream,downstream) # type: ignore
|
|
126
127
|
compute_massflow(row)
|
|
127
128
|
elif row.row_type == RowType.Rotor:
|
|
128
129
|
rotor_calc(row,upstream)
|
|
@@ -162,11 +163,11 @@ class TurbineSpool(Spool):
|
|
|
162
163
|
|
|
163
164
|
if row.row_type == RowType.Stator:
|
|
164
165
|
bounds = [0,80]
|
|
165
|
-
|
|
166
|
+
else:# row.row_type == RowType.Rotor:
|
|
166
167
|
bounds = [-80,0]
|
|
167
168
|
if row.row_type != RowType.Inlet:
|
|
168
169
|
for j in range(1,self.num_streamlines):
|
|
169
|
-
res = minimize_scalar(massflow_loss_function, bounds=bounds,args=(j,row,upstream,downstream),tol=1E-3)
|
|
170
|
+
res = minimize_scalar(massflow_loss_function, bounds=bounds,args=(j,row,upstream,downstream),tol=1E-3)
|
|
170
171
|
if row.row_type == RowType.Rotor:
|
|
171
172
|
row.beta2[j] = np.radians(res.x)
|
|
172
173
|
# Initialize the value at the hub to not upset the mean
|
|
@@ -228,7 +229,7 @@ class TurbineSpool(Spool):
|
|
|
228
229
|
|
|
229
230
|
|
|
230
231
|
# Balance the massflow between Stages
|
|
231
|
-
def balance_massflows(x0:List[float],blade_rows:List[
|
|
232
|
+
def balance_massflows(x0:List[float],blade_rows:List[BladeRow],P0:npt.NDArray,P:npt.NDArray,balance_mean_pressure:bool=True):
|
|
232
233
|
"""Balance Massflows.
|
|
233
234
|
|
|
234
235
|
Steps:
|
|
@@ -247,18 +248,18 @@ class TurbineSpool(Spool):
|
|
|
247
248
|
Returns:
|
|
248
249
|
_type_: _description_
|
|
249
250
|
"""
|
|
250
|
-
blade_rows_backup = copy.deepcopy(blade_rows)
|
|
251
|
+
# blade_rows_backup = copy.deepcopy(blade_rows)
|
|
251
252
|
# try:
|
|
252
253
|
if balance_mean_pressure:
|
|
253
254
|
for j in range(self.num_streamlines):
|
|
254
255
|
Ps = outlet_pressure(x0,P0[j],P[j])
|
|
255
256
|
for i in range(1,len(blade_rows)-2):
|
|
256
|
-
blade_rows[i].P[j] = float(Ps[i-1])
|
|
257
|
-
blade_rows[-2].P = P
|
|
257
|
+
blade_rows[i].P[j] = float(Ps[i-1]) # type: ignore
|
|
258
|
+
blade_rows[-2].P = P # type: ignore
|
|
258
259
|
else:
|
|
259
260
|
for i in range(1,len(blade_rows)-1):
|
|
260
261
|
for j in range(self.num_streamlines):
|
|
261
|
-
blade_rows[i].P[j] = P[j]*x0[(i-1)*self.num_streamlines+j] # x0 size = num_streamlines -1
|
|
262
|
+
blade_rows[i].P[j] = P[j]*x0[(i-1)*self.num_streamlines+j] # type: ignore # x0 size = num_streamlines -1
|
|
262
263
|
# try:
|
|
263
264
|
calculate_massflows(blade_rows,True,self.fluid)
|
|
264
265
|
print(x0)
|
|
@@ -293,14 +294,14 @@ class TurbineSpool(Spool):
|
|
|
293
294
|
# Adjust the inlet: Set the massflow
|
|
294
295
|
self.blade_rows[0].massflow = np.linspace(0,1,self.num_streamlines)*self.blade_rows[1].total_massflow_no_coolant
|
|
295
296
|
self.blade_rows[0].total_massflow_no_coolant = self.blade_rows[1].total_massflow_no_coolant
|
|
296
|
-
self.blade_rows[0].total_massflow =
|
|
297
|
+
self.blade_rows[0].total_massflow = self.blade_rows[1].total_massflow_no_coolant
|
|
297
298
|
self.blade_rows[0].calculated_massflow = self.blade_rows[0].total_massflow_no_coolant
|
|
298
299
|
inlet_calc(self.blade_rows[0]) # adjust the inlet to match massflow
|
|
299
300
|
|
|
300
301
|
if self.adjust_streamlines:
|
|
301
302
|
adjust_streamlines(self.blade_rows[:-1],self.passage)
|
|
302
303
|
|
|
303
|
-
self.blade_rows[-1].transfer_quantities(self.blade_rows[-2])
|
|
304
|
+
self.blade_rows[-1].transfer_quantities(self.blade_rows[-2]) # This would be the outlet
|
|
304
305
|
self.blade_rows[-1].P = self.blade_rows[-1].get_static_pressure(self.blade_rows[-1].percent_hub_shroud)
|
|
305
306
|
|
|
306
307
|
past_err = err
|
|
@@ -388,7 +389,7 @@ class TurbineSpool(Spool):
|
|
|
388
389
|
json.dump(data, f, indent=4,cls=NumpyEncoder)
|
|
389
390
|
|
|
390
391
|
|
|
391
|
-
def calculate_massflows(blade_rows:List[BladeRow],calculate_vm:bool=False,fluid:Solution=None):
|
|
392
|
+
def calculate_massflows(blade_rows:List[BladeRow],calculate_vm:bool=False,fluid:Optional[Solution]=None):
|
|
392
393
|
"""Calculates the massflow
|
|
393
394
|
|
|
394
395
|
Args:
|
|
File without changes
|