turbo-design 1.1.0__tar.gz → 1.1.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.
Files changed (32) hide show
  1. {turbo_design-1.1.0 → turbo_design-1.1.2}/PKG-INFO +1 -1
  2. {turbo_design-1.1.0 → turbo_design-1.1.2}/pyproject.toml +1 -1
  3. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/bladerow.py +11 -3
  4. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/inlet.py +3 -3
  5. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/passage.py +5 -3
  6. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/td_math.py +31 -50
  7. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/turbinespool.py +9 -5
  8. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/__init__.py +0 -0
  9. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/arrayfuncs.py +0 -0
  10. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/cantera_gas/co2.yaml +0 -0
  11. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/compressorspool.py +0 -0
  12. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/coolant.py +0 -0
  13. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/enums.py +0 -0
  14. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/isentropic.py +0 -0
  15. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/loss/__init__.py +0 -0
  16. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/loss/compressor/__init__.py +0 -0
  17. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/loss/losstype.py +0 -0
  18. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/loss/turbine/TD2.py +0 -0
  19. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/loss/turbine/__init__.py +0 -0
  20. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/loss/turbine/ainleymathieson.py +0 -0
  21. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/loss/turbine/craigcox.py +0 -0
  22. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/loss/turbine/fixedefficiency.py +0 -0
  23. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/loss/turbine/fixedpressureloss.py +0 -0
  24. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/loss/turbine/kackerokapuu.py +0 -0
  25. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/loss/turbine/traupel.py +0 -0
  26. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/lossinterp.py +0 -0
  27. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/outlet.py +0 -0
  28. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/radeq.py +0 -0
  29. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/rotor.py +0 -0
  30. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/solve_radeq.py +0 -0
  31. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/spool.py +0 -0
  32. {turbo_design-1.1.0 → turbo_design-1.1.2}/turbodesign/stage.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: turbo-design
3
- Version: 1.1.0
3
+ Version: 1.1.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
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "turbo-design"
3
- version = "1.1.0"
3
+ version = "1.1.2"
4
4
  description = "TurboDesign is a library used to design turbines and compressors using radial equilibrium."
5
5
  authors = ["Paht Juangphanich <paht.juangphanich@nasa.gov>"]
6
6
  packages = [
@@ -97,6 +97,8 @@ class BladeRow:
97
97
  phi:npt.NDArray = field(default_factory=lambda: np.array([0])) # Inclination angle x,r plane. AY td2.f
98
98
  rm: npt.NDArray = field(default_factory=lambda: np.array([0])) # Curvature
99
99
  incli_curve_radii: npt.NDArray = field(default_factory=lambda: np.array([0])) # radius at which curvature was evaluated
100
+ mprime:npt.NDArray = field(default_factory=lambda: np.array([0])) # Mprime distance
101
+ axial_chord:float = 0
100
102
 
101
103
  Yp: float = 0 # Pressure loss
102
104
  power:float = 0 # Watts
@@ -104,7 +106,8 @@ class BladeRow:
104
106
  P0_P:float = 0 # Total to Static Pressure Ratio
105
107
  Power_Type:PowerType
106
108
  euler_power:float = 0
107
-
109
+ Reynolds:float = 0
110
+
108
111
  # Used for loss calculations
109
112
  _blade_to_blade_gap:float = 0.025 # Gap between blade in terms of percent chord.
110
113
 
@@ -118,7 +121,7 @@ class BladeRow:
118
121
  _tip_clearance:float = 0 # Clearance as a percentage of span or blade height
119
122
 
120
123
  _inlet_to_outlet_pratio = [0.06,0.95]
121
-
124
+
122
125
  @property
123
126
  def inlet_to_outlet_pratio(self) -> Tuple[float,float]:
124
127
  """This is what is varied by the optimization.
@@ -474,6 +477,7 @@ class BladeRow:
474
477
  "P":self.P.tolist(),
475
478
  "T":self.T.tolist(),
476
479
  "rho":self.rho.tolist(),
480
+ "mu":self.mu,
477
481
  "Yp":self.Yp,
478
482
  "Power":self.power,
479
483
  "P0_P": self.P0_P,
@@ -482,7 +486,11 @@ class BladeRow:
482
486
  "euler_power":self.euler_power,
483
487
  "axial_chord":self.axial_chord,
484
488
  "aspect_ratio":self.aspect_ratio,
485
- "area": self.area
489
+ "num_blades":self.num_blades,
490
+ "area": self.area,
491
+ "mprime":self.mprime[-1],
492
+ "Reynolds":self.Reynolds,
493
+ "axial_chord":self.axial_chord
486
494
  }
487
495
 
488
496
  return data
@@ -54,7 +54,8 @@ class Inlet(BladeRow):
54
54
  self.beta2_metal = [0]
55
55
  self.P0_fun = interp1d(self.percent_hub_shroud,P0)
56
56
  self.T0_fun = interp1d(self.percent_hub_shroud,T0)
57
-
57
+ self.mprime = [0]
58
+
58
59
 
59
60
  def initialize_velocity(self,passage:Passage,num_streamlines:int):
60
61
  """Initialize velocity calculations. Assumes streamlines and inclination angles have been calculated
@@ -67,7 +68,6 @@ class Inlet(BladeRow):
67
68
 
68
69
  cutline,_,_ = passage.get_cutting_line(self.axial_location)
69
70
  self.x,self.r = cutline.get_point(np.linspace(0,1,num_streamlines))
70
-
71
71
  for _ in range(10):
72
72
  T0_T = (1+(self.gamma-1)/2 * self.M**2)
73
73
 
@@ -115,7 +115,7 @@ class Inlet(BladeRow):
115
115
  Area += 2*np.pi*C*(S/2*dx**2+self.r[j-1]*dx)
116
116
 
117
117
  self.calculated_massflow = self.rho.mean()*self.Vm.mean() * Area
118
-
118
+
119
119
 
120
120
  def get_total_pressure(self,percent_hub_shroud:Union[float,npt.NDArray]):
121
121
  """Returns the static pressure at a certain percent hub_shroud
@@ -184,7 +184,7 @@ class Passage:
184
184
  rshroud = self.rshroud(t_shroud)
185
185
  return line2D([xhub,rhub],[xshroud,rshroud]), t_hub, t_shroud
186
186
 
187
- def get_xr_slice(self,t_span:float,axial_location:float):
187
+ def get_xr_slice(self,t_span:float,axial_location:Tuple[float,float]):
188
188
  """Returns the xr coordinates of a streamline, a line that is parallel to both hub and shroud
189
189
 
190
190
  Args:
@@ -194,7 +194,7 @@ class Passage:
194
194
  Returns:
195
195
  np.NDArray: _description_
196
196
  """
197
- t_hub = np.linspace(0,axial_location,100)
197
+ t_hub = np.linspace(axial_location[0],axial_location[1],100)
198
198
 
199
199
  shroud_pts_cyl = np.vstack([self.xshroud(t_hub),self.rshroud(t_hub)]).transpose()
200
200
  hub_pts_cyl = np.vstack([self.xhub(t_hub),self.rhub(t_hub)]).transpose()
@@ -228,7 +228,9 @@ class Passage:
228
228
  cut,_,_ = self.get_cutting_line(p)
229
229
  x,r = cut.get_point(np.linspace(0,1,10))
230
230
  plt.plot(x,r,label=f'{p}',linestyle='dashed')
231
-
231
+
232
+
233
+ plt.ylim([-self.rshroud_pts.max()*0.1, self.rshroud_pts.max()])
232
234
  plt.legend()
233
235
  plt.axis('scaled')
234
236
  plt.show()
@@ -5,6 +5,7 @@ import numpy.typing as npt
5
5
  from .bladerow import BladeRow, compute_gas_constants
6
6
  from .enums import RowType, LossType
7
7
  from scipy.integrate import trapezoid
8
+ from .passage import Passage
8
9
 
9
10
  def T0_coolant_weighted_average(row:BladeRow) -> float:
10
11
  """Calculate the new weighted Total Temperature array considering coolant
@@ -78,6 +79,36 @@ def compute_massflow(row:BladeRow) -> None:
78
79
  row.calculated_massflow = massflow[-1]
79
80
  row.area = total_area
80
81
 
82
+ def compute_reynolds(rows:List[BladeRow],passage:Passage):
83
+ """Calculates the Reynolds Number
84
+
85
+ Args:
86
+ rows (List[BladeRow]): Blade row to calculate the Reynolds number
87
+ passage (Passage): Passage
88
+ """
89
+
90
+ for i in range(1,len(rows)):
91
+ row = rows[i]
92
+ xr = passage.get_xr_slice(0.5,[rows[i-1].axial_location,row.axial_location])
93
+ dx = np.diff(xr[:,0])
94
+ dr = np.diff(xr[:,1])
95
+ c = np.sum(np.sqrt(dx**2+dr**2))
96
+ mp = [2/(xr[i,1]+xr[i-1,1])*np.sqrt(dr[i-1]**2 + dx[i-1]**2) for i in range(1,len(xr[:,1]))]
97
+ mp = np.hstack([[0],np.cumsum(mp)])
98
+
99
+ if row.row_type == RowType.Rotor:
100
+ V = row.W.mean()
101
+ else:
102
+ V = row.V.mean()
103
+ rho = row.rho.mean()
104
+ mu = row.mu
105
+ row.Reynolds = c*V*rho/mu
106
+ row.mprime = mp
107
+ row.axial_chord = max(c,1E-12) # Axial chord
108
+ # row.num_blades = int(2*np.pi*row.r.mean() / row.pitch_to_chord * row.axial_chord)
109
+
110
+
111
+
81
112
  def compute_power(row:BladeRow,upstream:BladeRow) -> None:
82
113
  """Calculates the power
83
114
 
@@ -169,56 +200,6 @@ def compute_quantities(row:BladeRow,upstream:BladeRow):
169
200
  row.T0R = row.T + row.W**2 / (2*row.Cp)
170
201
  row.P0R = row.P*(row.T0R/row.T)**((row.gamma)/(row.gamma-1))
171
202
 
172
- def compute_quantities_power(row:BladeRow,upstream:BladeRow):
173
- """Calculation of all quantites after radial equilibrium has been solved assuming we know the power at the exit
174
-
175
- Note:
176
- Radial Equilibrium gives P0, T0, Vm. This code assumes the loss either enthalpy or pressure loss has already been calculated
177
-
178
- compute_velocity has been called so we know W, Wt, V, Vt, U, M, M_rel
179
-
180
- Static Pressure and Temperature should come from Total Temperature and Pressure + Velocity
181
-
182
- Args:
183
- row (BladeRow): current blade row. All quantities are at exit
184
- upstream (BladeRow): upstream blade row. All quantities are at exit
185
-
186
- """
187
- if row.row_type == RowType.Rotor:
188
- Cp_avg = (row.Cp+upstream.Cp)/2
189
- row.T0R = upstream.T0R - T0_coolant_weighted_average(row) - (upstream.U**2-row.U**2)/(2*Cp_avg)
190
-
191
- # Factor in T0R_drop. Convert T0R drop to absolute terms
192
- T_drop = (upstream.T0R - row.T0R) - row.W**2/(2*row.Cp) # row.T0R contains the drop
193
- T0_drop = T_drop*(1+(row.gamma-1)/2*row.M**2)
194
-
195
- # Adjust Total Temperature to match power
196
- T0 = upstream.T0 - row.power/row.eta_total/(row.total_massflow*row.Cp) + T0_drop
197
-
198
- if row.loss_function == LossType.Pressure:
199
- row.P0R = upstream.P0R - row.Yp*(upstream.P0R-row.P)
200
- row.T0 = T0
201
- row.T = row.T0/(1+(row.gamma-1)/2*row.M**2)
202
- row.P = row.P0R*(row.T/row.T0R)**(row.gamma/(row.gamma-1))
203
-
204
- elif row.loss_function == LossType.Enthalpy:
205
- row.P0 = row.P*(T0/row.T)**(row.gamma/(row.gamma-1))
206
- row.T = T0 - row.W**2/(2*row.Cp) + T_drop
207
- row.T0 = T0
208
- row.P = row.P0*(row.T0/row.T)**(row.gamma/(row.gamma-1))
209
- row.P0R = row.P * (row.T0R/row.T)**((row.gamma)/(row.gamma-1))
210
-
211
- elif row.row_type == RowType.Stator:
212
- row.T0 = upstream.T0 - T0_coolant_weighted_average(row)
213
- if row.loss_function == LossType.Pressure:
214
- row.P0 = upstream.P0 - row.Yp*(upstream.P0-row.P)
215
- else:
216
- row.P0 = upstream.P0
217
- row.T = row.T0 * (1+(row.gamma-1)/2*row.M**2)
218
- row.P = row.P0 * (row.T/row.T0)**((row.gamma)/(row.gamma-1))
219
- row.T0R = row.T + row.W**2 / (2*row.Cp)
220
- row.P0R = row.P*(row.T0R/row.T)**((row.gamma)/(row.gamma-1))
221
-
222
203
  def stator_calc(row:BladeRow,upstream:BladeRow,downstream:BladeRow=None,calculate_vm:bool=True):
223
204
  """Given P0, T0, P, alpha2 of stator calculate all other quantities
224
205
 
@@ -8,7 +8,7 @@ from .passage import Passage
8
8
  from scipy.interpolate import interp1d
9
9
  import numpy as np
10
10
  import numpy.typing as npt
11
- from .td_math import inlet_calc,rotor_calc, stator_calc, compute_massflow, compute_power, compute_gas_constants
11
+ from .td_math import inlet_calc,rotor_calc, stator_calc, compute_massflow, compute_power, compute_gas_constants, compute_reynolds
12
12
  from .solve_radeq import adjust_streamlines, radeq
13
13
  from scipy.optimize import minimize_scalar, minimize, fmin_slsqp
14
14
  from .inlet import Inlet
@@ -136,7 +136,7 @@ class TurbineSpool(Spool):
136
136
  self.__match_massflow()
137
137
  elif self.massflow_constraint == MassflowConstraint.BalanceMassFlow:
138
138
  self.__balance_massflow()
139
-
139
+
140
140
 
141
141
  def __match_massflow(self):
142
142
  """ Matches the massflow between streamtubes by changing exit angles. Doesn't use radial equilibrium.
@@ -171,10 +171,11 @@ class TurbineSpool(Spool):
171
171
  row.alpha2[0] = 1/(len(row.alpha2)-1)*row.alpha2[1:].sum()
172
172
  upstream = compute_gas_constants(upstream)
173
173
  row = compute_gas_constants(row)
174
-
174
+
175
175
 
176
176
  # Step 3: Adjust streamlines to evenly divide massflow
177
177
  adjust_streamlines(self.blade_rows,self.passage)
178
+ compute_reynolds(self.blade_rows,self.passage)
178
179
 
179
180
  def __balance_massflow(self):
180
181
  """ Balances the massflow between rows. Use radial equilibrium.
@@ -284,7 +285,10 @@ class TurbineSpool(Spool):
284
285
  self.blade_rows[-1].P = self.blade_rows[-1].get_static_pressure(self.blade_rows[-1].percent_hub_shroud)
285
286
  err = calculate_error(self.blade_rows[:-1])
286
287
  print(f"Massflow convergenced error:{err}")
287
-
288
+
289
+ # calculate Reynolds number
290
+ compute_reynolds(self.blade_rows,self.passage)
291
+
288
292
  # finetune = True
289
293
  # if finetune:
290
294
  # print('Finetune static pressure between stages')
@@ -453,7 +457,7 @@ def calculate_massflows(blade_rows:List[BladeRow],calculate_vm:bool=False):
453
457
  row = compute_gas_constants(row)
454
458
  compute_massflow(row)
455
459
  compute_power(row,upstream)
456
-
460
+
457
461
  def massflow_loss_function(exit_angle:float,index:int,row:BladeRow,upstream:BladeRow,downstream:BladeRow=None):
458
462
  """Finds the blade exit angles that balance the massflow throughout the stage
459
463