Source code for turbodesign.loss.turbine.traupel

import pickle, os
from typing import Dict
from ...bladerow import BladeRow, sutherland
from ...lossinterp import LossInterp
from ...enums import RowType, LossType
import numpy as np
import numpy.typing as npt
import pathlib
from ..losstype import LossBaseClass
import requests

[docs] class Traupel(LossBaseClass): def __init__(self): super().__init__(LossType.Enthalpy) path = pathlib.Path(os.path.join(os.environ['TD3_HOME'],"traupel"+".pkl")) if not path.exists(): url = "https://github.com/nasa/turbo-design/raw/main/references/Turbines/Traupel/traupel.pkl" response = requests.get(url, stream=True) with open(path.absolute(), mode="wb") as file: for chunk in response.iter_content(chunk_size=10 * 1024): file.write(chunk) with open(path.absolute(),'rb') as f: self.data = pickle.load(f) # type: ignore
[docs] def __call__(self,row:BladeRow, upstream:BladeRow) -> npt.NDArray: """Compute Traupel stage enthalpy efficiency from an upstream/downstream pair. Args: row (BladeRow): Blade row being evaluated (stator or rotor). upstream (BladeRow): Upstream blade row supplying inlet conditions. Returns: numpy.ndarray: Spanwise efficiency array matching ``row.r``. """ alpha1 = 90-np.degrees(upstream.alpha1.mean()) alpha2 = 90-np.degrees(upstream.alpha2.mean()) beta2 = 90 - np.degrees(row.beta1.mean()) beta3 = 90 - np.degrees(row.beta2.mean()) g = upstream.pitch # G is the pitch h_stator = upstream.r[-1] - upstream.r[0] h_rotor = row.r[-1] - row.r[0] if row.row_type == RowType.Rotor: turning = np.abs(np.degrees(upstream.beta2-row.beta2).mean()) F = self.data['Fig06'](float((upstream.W/row.W).mean()), float(turning)) # Inlet velocity else: turning = np.abs(np.degrees(upstream.alpha2-row.alpha2).mean()) F = self.data['Fig06'](float((upstream.V/row.V).mean()), float(turning)) # Inlet velocity H = self.data['Fig07'](float(alpha1-beta2), float(alpha2-beta3)) zeta_s = F*g/h_stator # Stator loss factor scaled by pitch-to-span zeta_r = F*g/h_rotor # Rotor loss factor scaled by pitch-to-span x_p_stator = self.data['Fig01'](float(alpha1), float(alpha2)) x_p_rotor = self.data['Fig01'](float(beta2), float(beta3)) zeta_p_stator = self.data['Fig02'](float(alpha1), float(alpha2)) x_m_stator = self.data['Fig03_0'](float(np.mean(upstream.M))) zeta_p_rotor = self.data['Fig02'](float(beta2), float(beta3)) x_m_rotor = self.data['Fig03_0'](float(np.mean(row.M_rel))) e_te = upstream.te_pitch * g o = upstream.throat ssen_alpha2 = e_te/o # Thickness of Trailing edge divide by throat ssen_beta2 = row.te_pitch*g / row.throat x_delta_stator = self.data['Fig05'](float(ssen_alpha2), float(alpha2)) zeta_delta_stator = self.data['Fig04'](float(ssen_alpha2), float(alpha2)) x_delta_rotor = self.data['Fig05'](float(ssen_beta2), float(beta3)) zeta_delta_rotor = self.data['Fig04'](float(ssen_beta2), float(beta3)) Dm = 2* (upstream.r[-1] + upstream.r[0])/2 # Mean diameter used for annulus friction zeta_f = 0.5 * (h_stator/Dm)**2 zeta_pr_stator = zeta_p_stator * x_p_stator * x_m_stator * x_delta_stator + zeta_delta_stator + zeta_f Dm = 2* (row.r[-1] + row.r[0])/2 # Mean diameter used for annulus friction zeta_f = 0.5 * (h_rotor/Dm)**2 zeta_pr_rotor = zeta_p_rotor * x_p_rotor * x_m_rotor * x_delta_rotor + zeta_delta_rotor + zeta_f if row.row_type == RowType.Stator: zeta_cl = 0 else: zeta_cl = self.data['Fig08'](float(row.tip_clearance)) # Clearance loss for unshrouded blades zeta_z = 0 # Disk friction loss not modeled # 1 - (internal) - (external) zeta_v = 0 zeta_off = 0 eta_stator = 1- (zeta_pr_stator + zeta_s + 0 + zeta_z) - (zeta_r+zeta_v) - zeta_off # Per Traupel formulation eta_rotor = 1 - (zeta_pr_rotor + zeta_r + zeta_cl + zeta_z) - (zeta_r+zeta_v) - zeta_off return (eta_stator+eta_rotor) + row.r*0