turbo-design 1.3.8__py3-none-any.whl → 1.3.10__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.
Files changed (48) hide show
  1. {turbo_design-1.3.8.dist-info → turbo_design-1.3.10.dist-info}/METADATA +2 -1
  2. turbo_design-1.3.10.dist-info/RECORD +46 -0
  3. {turbo_design-1.3.8.dist-info → turbo_design-1.3.10.dist-info}/WHEEL +1 -1
  4. turbodesign/__init__.py +57 -4
  5. turbodesign/agf.py +346 -0
  6. turbodesign/arrayfuncs.py +31 -1
  7. turbodesign/bladerow.py +238 -155
  8. turbodesign/compressor_math.py +386 -0
  9. turbodesign/compressor_spool.py +941 -0
  10. turbodesign/coolant.py +18 -6
  11. turbodesign/deviation/__init__.py +5 -0
  12. turbodesign/deviation/axial_compressor.py +3 -0
  13. turbodesign/deviation/carter_deviation.py +79 -0
  14. turbodesign/deviation/deviation_base.py +20 -0
  15. turbodesign/deviation/fixed_deviation.py +42 -0
  16. turbodesign/enums.py +5 -6
  17. turbodesign/flow_math.py +158 -0
  18. turbodesign/inlet.py +126 -56
  19. turbodesign/isentropic.py +59 -15
  20. turbodesign/loss/__init__.py +3 -1
  21. turbodesign/loss/compressor/OTAC_README.md +39 -0
  22. turbodesign/loss/compressor/__init__.py +54 -0
  23. turbodesign/loss/compressor/diffusion.py +61 -0
  24. turbodesign/loss/compressor/lieblein.py +1 -0
  25. turbodesign/loss/compressor/otac.py +799 -0
  26. turbodesign/loss/compressor/references/schobeiri-2012-shock-loss-model-for-transonic-and-supersonic-axial-compressors-with-curved-blades.pdf +0 -0
  27. turbodesign/loss/fixedpolytropic.py +27 -0
  28. turbodesign/loss/fixedpressureloss.py +30 -0
  29. turbodesign/loss/losstype.py +2 -30
  30. turbodesign/loss/turbine/TD2.py +25 -29
  31. turbodesign/loss/turbine/__init__.py +0 -1
  32. turbodesign/loss/turbine/ainleymathieson.py +6 -5
  33. turbodesign/loss/turbine/craigcox.py +6 -5
  34. turbodesign/loss/turbine/fixedefficiency.py +8 -7
  35. turbodesign/loss/turbine/kackerokapuu.py +7 -5
  36. turbodesign/loss/turbine/traupel.py +17 -16
  37. turbodesign/outlet.py +81 -22
  38. turbodesign/passage.py +98 -63
  39. turbodesign/row_factory.py +129 -0
  40. turbodesign/solve_radeq.py +9 -10
  41. turbodesign/{td_math.py → turbine_math.py} +144 -185
  42. turbodesign/turbine_spool.py +1219 -0
  43. turbo_design-1.3.8.dist-info/RECORD +0 -33
  44. turbodesign/compressorspool.py +0 -60
  45. turbodesign/loss/turbine/fixedpressureloss.py +0 -25
  46. turbodesign/rotor.py +0 -38
  47. turbodesign/spool.py +0 -317
  48. turbodesign/turbinespool.py +0 -543
turbodesign/passage.py CHANGED
@@ -1,4 +1,4 @@
1
- from typing import List, Tuple, Union
1
+ from typing import List, Optional, Tuple, Union
2
2
  import numpy as np
3
3
  import numpy.typing as npt
4
4
  from scipy.interpolate import PchipInterpolator, interp1d
@@ -30,7 +30,7 @@ class Passage:
30
30
 
31
31
  def __init__(self,xhub:Union[npt.NDArray,List[float]],rhub:Union[npt.NDArray,List[float]],
32
32
  xshroud:Union[npt.NDArray,List[float]],rshroud:Union[npt.NDArray,List[float]],
33
- passageType:PassageType=PassageType.Axial):
33
+ passageType:PassageType=PassageType.Axial, zero_phi: bool = False):
34
34
  """_summary_
35
35
 
36
36
  Args:
@@ -42,6 +42,7 @@ class Passage:
42
42
  """
43
43
  assert len(xhub) == len(xshroud), "xHub and xShroud should be the same length"
44
44
  assert len(rhub) == len(rshroud), "rHub and rShroud should be the same length"
45
+ self.zero_phi = zero_phi
45
46
 
46
47
  hub_arc_len = xr_to_mprime(np.vstack([xhub,rhub]).transpose())[1]
47
48
  self.hub_arc_len = hub_arc_len[-1]
@@ -81,15 +82,14 @@ class Passage:
81
82
  r_streamline = t_streamline.copy()*0
82
83
  x_streamline = t_streamline.copy()*0
83
84
  for i,t in enumerate(t_streamline):
84
- xhub = self.xhub(t)
85
- rhub = self.rhub(t)
86
- xshroud = self.xshroud(t)
87
- rshroud = self.rshroud(t)
88
- x_streamline[i] ,r_streamline[i] = line2D([xhub,rhub],[xshroud,rshroud]).get_point(t_radial)
85
+ xhub = float(self.xhub(t))
86
+ rhub = float(self.rhub(t))
87
+ xshroud = float(self.xshroud(t))
88
+ rshroud = float(self.rshroud(t))
89
+ x_streamline[i] ,r_streamline[i] = line2D((xhub,rhub),(xshroud,rshroud)).get_point(t_radial)
89
90
  return t_streamline,x_streamline,r_streamline
90
91
 
91
- @staticmethod
92
- def streamline_curvature(x_streamline:npt.NDArray,r_streamline:npt.NDArray) -> Tuple[npt.NDArray,npt.NDArray,npt.NDArray]:
92
+ def streamline_curvature(self, x_streamline:npt.NDArray,r_streamline:npt.NDArray) -> Tuple[npt.NDArray,npt.NDArray,npt.NDArray]:
93
93
  """Hub and casing values of streamline angles of inclination and curvature
94
94
 
95
95
  x_streamline[axial,radial]
@@ -113,14 +113,16 @@ class Passage:
113
113
  phi = np.zeros(shape=x_streamline.shape)
114
114
  r = np.zeros(shape=x_streamline.shape)
115
115
  radius_curvature = np.zeros(shape=x_streamline.shape)
116
+ if self.zero_phi:
117
+ return phi, radius_curvature, r_streamline
116
118
  # Have to make sure there isn't a divide by zero which could happen if there is a vertical line somewhere
117
119
  indices = np.where(np.abs(np.diff(x_streamline))>np.finfo(float).eps)[0]
118
120
 
119
121
  d_dx = FinDiff(0,x_streamline[indices[0]:indices[-1]],1)
120
122
  d2_dx2 = FinDiff(0,x_streamline[indices[0]:indices[-1]],2)
121
123
 
122
- dr_dx = d_dx(r_streamline[indices[0]:indices[-1]])
123
- d2r_dx2 = d2_dx2(r_streamline[indices[0]:indices[-1]])
124
+ dr_dx = d_dx(r_streamline[indices[0]:indices[-1]]) # type: ignore
125
+ d2r_dx2 = d2_dx2(r_streamline[indices[0]:indices[-1]]) # type: ignore
124
126
 
125
127
  radius_curvature[indices[0]:indices[-1]] = np.power((1+np.power(dr_dx,2)),1.5)
126
128
  radius_curvature[indices[0]:indices[-1]] = np.divide(radius_curvature[indices[0]:indices[-1]], np.abs(d2r_dx2))
@@ -170,7 +172,7 @@ class Passage:
170
172
  total_area += area
171
173
  return total_area
172
174
 
173
- def get_cutting_line(self, t_hub:float) -> Tuple[line2D,float,float]:
175
+ def get_cutting_line(self, t_hub:float,t_shroud:Optional[float]=None) -> Tuple[line2D,float,float]:
174
176
  """Gets the cutting line perpendicular to hub and shroud
175
177
 
176
178
  Args:
@@ -181,65 +183,90 @@ class Passage:
181
183
 
182
184
  cut (line2D): line from hub to shroud
183
185
  t_hub (float): Percentage along hub arc length
184
- t_shroud (float): t corresponding to intersection of bisector of hub
186
+ t_shroud (Optional[float]): t corresponding to intersection of bisector of hub. Defaults to None
185
187
 
186
188
  """
187
- xhub = self.xhub(t_hub)
188
- rhub = self.rhub(t_hub)
189
-
190
- if t_hub>0 and t_hub<1:
191
- dx = self.xhub(t_hub+0.0001) - self.xhub(t_hub-0.0001)
192
- dr = self.rhub(t_hub+0.0001) - self.rhub(t_hub-0.0001)
193
- elif t_hub>0:
194
- dx = self.xhub(t_hub) - self.xhub(t_hub-0.0001)
195
- dr = self.rhub(t_hub) - self.rhub(t_hub-0.0001)
196
- elif t_hub<1:
197
- dx = self.xhub(t_hub+0.0001) - self.xhub(t_hub)
198
- dr = self.rhub(t_hub+0.0001) - self.rhub(t_hub)
199
-
200
- if self.passageType == PassageType.Centrifugal:
201
- if np.abs(dr)>1e-6:
202
- # Draw a line perpendicular to the hub.
203
- # Find the intersection point to the shroud.
204
- h = -dx/dr # Slope of perpendicular line
189
+ xhub = float(self.xhub(t_hub))
190
+ rhub = float(self.rhub(t_hub))
191
+ if t_shroud is None:
192
+ if t_hub>0 and t_hub<1:
193
+ dx = self.xhub(t_hub+0.0001) - self.xhub(t_hub-0.0001)
194
+ dr = self.rhub(t_hub+0.0001) - self.rhub(t_hub-0.0001)
195
+ elif t_hub>0:
196
+ dx = self.xhub(t_hub) - self.xhub(t_hub-0.0001)
197
+ dr = self.rhub(t_hub) - self.rhub(t_hub-0.0001)
198
+ else: # t_hub<1:
199
+ dx = self.xhub(t_hub+0.0001) - self.xhub(t_hub)
200
+ dr = self.rhub(t_hub+0.0001) - self.rhub(t_hub)
205
201
 
206
- f = lambda t: h*(self.xshroud(t) - xhub)+rhub # line from hub to shroud
207
- fun = lambda t: np.abs(f(t)-self.rshroud(t)) # find where it intersects
208
- res = minimize_scalar(fun,bounds=[0,1],tol=1E-3)
209
- t_shroud = res.x
202
+ if self.passageType == PassageType.Centrifugal:
203
+ if np.abs(dr)>1e-6:
204
+ # Draw a line perpendicular to the hub.
205
+ # Find the intersection point to the shroud.
206
+ h = -dx/dr # Slope of perpendicular line
207
+
208
+ f = lambda t: h*(self.xshroud(t) - xhub)+rhub # line from hub to shroud
209
+ fun = lambda t: np.abs(f(t)-self.rshroud(t)) # find where it intersects
210
+ res = minimize_scalar(fun,bounds=[0,1],tol=1E-3)
211
+ t_shroud = res.x # type: ignore
212
+ else:
213
+ t_shroud = t_hub # Vertical line
210
214
  else:
211
- t_shroud = t_hub # Vertical line
212
- else:
213
- t_shroud = t_hub
215
+ t_shroud = t_hub
216
+
217
+ xshroud = float(self.xshroud(t_shroud))
218
+ rshroud = float(self.rshroud(t_shroud))
214
219
 
215
- xshroud = self.xshroud(t_shroud)
216
- rshroud = self.rshroud(t_shroud)
217
- return line2D([xhub,rhub],[xshroud,rshroud]), t_hub, t_shroud
220
+ return line2D((xhub,rhub),(xshroud,rshroud)), t_hub, t_shroud # type: ignore
218
221
 
219
- def get_xr_slice(self,t_span:float,percent_hub:Tuple[float,float],resolution:int=100):
220
- """Returns the xr coordinates of a streamline, a line that is parallel to both hub and shroud
221
-
222
+ def get_xr_slice(self, t_span: float, percent_hub: Tuple[float, float],
223
+ percent_shroud: Optional[Tuple[float, float]] = None, resolution: int = 100) -> npt.NDArray[np.float64]:
224
+ """
225
+ Return the (x, r) coordinates of a *straight* streamline segment that
226
+ connects corresponding hub and shroud points, sampled uniformly along
227
+ each surface between the given percent limits.
228
+
229
+ The point returned on each connecting line is at parametric position
230
+ `t_span` in [0, 1], where 0 = hub point and 1 = shroud point.
231
+
222
232
  Args:
223
- t_span (float): _description_
224
- meridional_location (float): _description_
225
- resolution (int): number of points to resolve
233
+ t_span: Interpolation parameter along each hub→shroud connector (0..1).
234
+ percent_hub: (start, end) fractional arc-length positions along the hub (0..1).
235
+ percent_shroud: Optional (start, end) along the shroud (0..1). If None,
236
+ the shroud uses the same normalized range as `percent_hub`.
237
+ resolution: Number of sample points along the streamwise direction.
226
238
 
227
239
  Returns:
228
- np.NDArray: _description_
240
+ (resolution, 2) array of [x, r] coordinates.
229
241
  """
230
- t_hub = np.linspace(percent_hub[0],percent_hub[1],resolution)
231
- t_hub = convert_to_ndarray(t_hub)*self.hub_length
232
-
233
- shroud_pts_cyl = np.vstack([self.xshroud(t_hub),self.rshroud(t_hub)]).transpose()
234
- hub_pts_cyl = np.vstack([self.xhub(t_hub),self.rhub(t_hub)]).transpose()
235
- n = len(t_hub)
236
-
237
- xr = np.zeros((n,2))
238
- for j in range(n):
239
- l = line2D(hub_pts_cyl[j,:],shroud_pts_cyl[j,:])
240
- xr[j,0],xr[j,1] = l.get_point(t_span)
241
-
242
- return xr
242
+ # ---- validation
243
+ if not (0.0 <= t_span <= 1.0):
244
+ raise ValueError("t_span must be in [0, 1].")
245
+ if resolution < 2:
246
+ raise ValueError("resolution must be >= 2.")
247
+ if not (0.0 <= percent_hub[0] <= 1.0 and 0.0 <= percent_hub[1] <= 1.0):
248
+ raise ValueError("percent_hub values must be in [0, 1].")
249
+ if percent_shroud is not None and not (
250
+ 0.0 <= percent_shroud[0] <= 1.0 and 0.0 <= percent_shroud[1] <= 1.0
251
+ ):
252
+ raise ValueError("percent_shroud values must be in [0, 1].")
253
+
254
+ # ---- parameterize along hub and shroud (use each surface's own length!)
255
+ t_hub = np.linspace(percent_hub[0], percent_hub[1], resolution) * self.hub_length
256
+ if percent_shroud is None:
257
+ t_shroud = np.linspace(percent_hub[0], percent_hub[1], resolution) * self.shroud_length
258
+ else:
259
+ t_shroud = np.linspace(percent_shroud[0], percent_shroud[1], resolution) * self.shroud_length
260
+
261
+ # ---- sample hub & shroud curves (x, r)
262
+ hub_pts = np.column_stack([self.xhub(t_hub), self.rhub(t_hub)]) # (N, 2)
263
+ shroud_pts = np.column_stack([self.xshroud(t_shroud), self.rshroud(t_shroud)]) # (N, 2)
264
+
265
+ # ---- vectorized interpolation along each connector: hub + t*(shroud - hub)
266
+ xr = hub_pts + (shroud_pts - hub_pts) * float(t_span) # (N, 2)
267
+
268
+ return xr.astype(np.float64, copy=False)
269
+
243
270
 
244
271
  def get_m(self,t_span:float,resolution:int=100) -> npt.NDArray:
245
272
  """Meridional cooridnates
@@ -251,7 +278,7 @@ class Passage:
251
278
  Returns:
252
279
  npt.NDArray: _description_
253
280
  """
254
- xr = self.get_xr_slice(t_span,(0,1),resolution)
281
+ xr = self.get_xr_slice(t_span=t_span,percent_hub=(0,1),resolution=resolution)
255
282
  dx = np.diff(xr[:,0])
256
283
  dr = np.diff(xr[:,1])
257
284
  m = np.concat([[0],np.cumsum(np.sqrt(dx**2 + dr**2))])
@@ -269,7 +296,7 @@ class Passage:
269
296
  (float) : returns the derivative
270
297
  """
271
298
  m = self.get_m(t_span,resolution)
272
- return PchipInterpolator(np.linspace(0,1,resolution),np.diff(m))(location)
299
+ return PchipInterpolator(np.linspace(0,1,resolution),np.diff(m))(location) # type: ignore
273
300
 
274
301
  @property
275
302
  def hub_length(self):
@@ -279,6 +306,14 @@ class Passage:
279
306
  """
280
307
  return np.sum(np.sqrt(np.diff(self.xhub_pts)**2 + np.diff(self.rhub_pts)**2))
281
308
 
309
+ @property
310
+ def shroud_length(self):
311
+ """returns the computed length of the shroud
312
+ Returns:
313
+ _type_: _description_
314
+ """
315
+ return np.sum(np.sqrt(np.diff(self.xshroud_pts)**2 + np.diff(self.rshroud_pts)**2))
316
+
282
317
  def plot_cuts(self,percent_axial:List[float]=[]):
283
318
  """_summary_
284
319
 
@@ -0,0 +1,129 @@
1
+ """Convenience helpers for constructing BladeRow objects with minimal boilerplate."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional, Sequence, Any
6
+
7
+ import numpy as np
8
+
9
+ from .bladerow import BladeRow
10
+ from .enums import RowType
11
+
12
+ __all__ = ["make_blade_row", "make_rotor_row", "make_stator_row"]
13
+
14
+
15
+ def make_blade_row(
16
+ *args: Any,
17
+ row_type: Optional[RowType] = None,
18
+ hub_location: Optional[float] = None,
19
+ shroud_location: Optional[float] = None,
20
+ stage_id: int = 0,
21
+ **attrs: Any,
22
+ ) -> BladeRow:
23
+ """Generic BladeRow factory that supports legacy calling styles.
24
+
25
+ Args mirror the original BladeRow constructor; any extra keyword arguments
26
+ are set as attributes on the created row for convenience.
27
+ """
28
+ # Allow positional legacy (hub_location, row_type, stage_id, shroud_location)
29
+ pos = list(args)
30
+ # Legacy positional usage: (RowType, power=...) or (hub_loc, RowType, ...)
31
+ if pos and isinstance(pos[0], RowType):
32
+ row_type = pos.pop(0)
33
+ if hub_location is None and pos:
34
+ hub_location = pos.pop(0)
35
+ if row_type is None and pos and isinstance(pos[0], RowType):
36
+ row_type = pos.pop(0)
37
+ if shroud_location is None and pos:
38
+ shroud_location = pos.pop(0)
39
+
40
+ hub_location = 0.0 if hub_location is None else float(hub_location)
41
+ row_type = row_type if row_type is not None else RowType.Stator
42
+
43
+ row = BladeRow(hub_location=hub_location, row_type=row_type, stage_id=stage_id, shroud_location=shroud_location)
44
+
45
+ # Apply extra attributes (e.g., loss_function, beta2_metal, etc.)
46
+ for key, val in attrs.items():
47
+ setattr(row, key, val)
48
+ return row
49
+
50
+ def _maybe_set_pitch(row: BladeRow, pitch_to_chord: Optional[float], solidity: Optional[float]) -> None:
51
+ """Apply pitch/solidity inputs to a blade row if provided."""
52
+ if pitch_to_chord is not None:
53
+ row.pitch_to_chord = pitch_to_chord
54
+ elif solidity is not None and solidity != 0:
55
+ row.pitch_to_chord = 1.0 / solidity
56
+
57
+
58
+ def make_rotor_row(
59
+ hub_location: float,
60
+ metal_exit_angle_deg: Optional[float | Sequence[float]] = None,
61
+ loss_function: Optional[object] = None,
62
+ P0_ratio: float = 1.0,
63
+ pitch_to_chord: Optional[float] = None,
64
+ solidity: Optional[float] = None,
65
+ num_blades: Optional[int] = None,
66
+ axial_chord: Optional[float] = None,
67
+ ) -> BladeRow:
68
+ """Create a Rotor blade row with common inputs.
69
+
70
+ Args:
71
+ hub_location: Streamwise position (0–1) for the row.
72
+ beta2_metal_deg: Exit metal angle(s) in degrees.
73
+ loss_function: Loss model to attach.
74
+ P0_ratio: Total-pressure ratio target across the row.
75
+ pitch_to_chord: Pitch-to-chord ratio (alternative to solidity).
76
+ solidity: Solidity (chord/pitch) if preferred over pitch_to_chord.
77
+ num_blades: Number of blades (used to derive pitch).
78
+ axial_chord: Axial chord length if known.
79
+ """
80
+ row = BladeRow(hub_location=hub_location, row_type=RowType.Rotor)
81
+ row.P0_ratio = P0_ratio
82
+ row.P0_ratio_target = P0_ratio
83
+ _maybe_set_pitch(row, pitch_to_chord, solidity)
84
+ if num_blades is not None:
85
+ row.num_blades = num_blades
86
+ if axial_chord is not None:
87
+ row.axial_chord = axial_chord
88
+ if metal_exit_angle_deg is not None:
89
+ row.metal_exit_angle = np.atleast_1d(metal_exit_angle_deg)
90
+ if loss_function is not None:
91
+ row.loss_function = loss_function
92
+ return row
93
+
94
+
95
+ def make_stator_row(
96
+ hub_location: float,
97
+ metal_exit_angle_deg: Optional[float | Sequence[float]] = None,
98
+ loss_function: Optional[object] = None,
99
+ P0_ratio: float = 1.0,
100
+ pitch_to_chord: Optional[float] = None,
101
+ solidity: Optional[float] = None,
102
+ num_blades: Optional[int] = None,
103
+ axial_chord: Optional[float] = None,
104
+ ) -> BladeRow:
105
+ """Create a Stator/IGV blade row with common inputs.
106
+
107
+ Args:
108
+ hub_location: Streamwise position (0–1) for the row.
109
+ alpha2_metal_deg: Exit metal angle(s) in degrees.
110
+ loss_function: Loss model to attach.
111
+ P0_ratio: Total-pressure ratio target across the row.
112
+ pitch_to_chord: Pitch-to-chord ratio (alternative to solidity).
113
+ solidity: Solidity (chord/pitch) if preferred over pitch_to_chord.
114
+ num_blades: Number of blades (used to derive pitch).
115
+ axial_chord: Axial chord length if known.
116
+ """
117
+ row = BladeRow(hub_location=hub_location, row_type=RowType.Stator)
118
+ row.P0_ratio = P0_ratio
119
+ row.P0_ratio_target = P0_ratio
120
+ _maybe_set_pitch(row, pitch_to_chord, solidity)
121
+ if num_blades is not None:
122
+ row.num_blades = num_blades
123
+ if axial_chord is not None:
124
+ row.axial_chord = axial_chord
125
+ if metal_exit_angle_deg is not None:
126
+ row.metal_exit_angle = np.atleast_1d(metal_exit_angle_deg)
127
+ if loss_function is not None:
128
+ row.loss_function = loss_function
129
+ return row
@@ -1,31 +1,30 @@
1
1
  from typing import List, Tuple
2
2
  from .radeq import radeq
3
- from .enums import LossType, RowType, PowerType, MassflowConstraint
3
+ from .enums import LossType, RowType, PowerType
4
4
  from .bladerow import BladeRow
5
- from .td_math import compute_gas_constants
6
- from .td_math import compute_quantities, compute_power, compute_massflow
5
+ from .turbine_math import compute_gas_constants
6
+ from .turbine_math import compute_quantities, compute_power
7
+ from .flow_math import compute_massflow
7
8
  import numpy.typing as npt
8
9
  import numpy as np
9
10
  from scipy.interpolate import interp1d
10
11
  from scipy.optimize import minimize_scalar
11
12
  from .passage import Passage
12
13
 
13
- def adjust_streamlines(blade_rows:List[BladeRow],passage:Passage):
14
+ def adjust_streamlines(blade_rows:List[BladeRow],passage:Passage,massflow_fraction:np.ndarray):
14
15
  """Adjust the streamlines to evenly divide the massflow
15
16
 
16
17
  Args:
17
18
  blade_rows (List[BladeRow]): List of blade rows
18
19
  passage (Passage): passage object describing the hub and shroud
19
-
20
+ massflow_fraction (np.ndarray): array from 0 to 1 of how the massflow should be distributed from hub to shroud
20
21
  """
21
22
  for row_index,row in enumerate(blade_rows):
22
23
  print(f"Adjusting Streamlines to balance massflow Row: {row_index}")
23
- massflow_fraction = np.linspace(0,1,len(row.percent_hub_shroud))
24
24
  row.total_massflow = row.massflow[-1]
25
- ideal_massflow_fraction = row.massflow[-1] * massflow_fraction
26
25
 
27
- new_percent_streamline = interp1d(row.massflow,row.percent_hub_shroud)(ideal_massflow_fraction[1:-1])
28
- row.percent_hub_shroud[1:-1] = new_percent_streamline
26
+ new_percent_streamline = interp1d(row.massflow,row.percent_hub_shroud)(massflow_fraction[1:-1])
27
+ row.percent_hub_shroud[1:-1] = new_percent_streamline
29
28
 
30
29
  cut_line, thub,_ = passage.get_cutting_line(row.percent_hub)
31
30
  row.x,row.r = cut_line.get_point(row.percent_hub_shroud)
@@ -36,4 +35,4 @@ def adjust_streamlines(blade_rows:List[BladeRow],passage:Passage):
36
35
  row.phi[i] = float(interp1d(t_streamline,phi)(row.percent_hub))
37
36
  row.rm[i] = float(interp1d(t_streamline,rm)(row.percent_hub))
38
37
  row.r[i] = float(interp1d(t_streamline,r)(row.percent_hub))
39
- row.x[i] = float(interp1d(t_streamline,x_streamline)(row.percent_hub))
38
+ row.x[i] = float(interp1d(t_streamline,x_streamline)(row.percent_hub))