Source code for turbigen.meanline.cascade

import numpy as np
from turbigen import util
import turbigen.flowfield


[docs] def forward( So1, span1, span2, Alpha1, Alpha2, Ma2, Yh=0.0, htr=0.99, RR=1.0, Beta=(0.0, 0.0) ): r"""Design the mean-line for a single-row stationary cascade. The minimal set of design choices are: spans, yaw angles, and exit Mach number. Optionally, loss can be acounted for using an energy loss coefficient. For annular cascades, a hub-to-tip ratio, radius change and pitch angles become additional free variables. Parameters ---------- So1: State Object specifing the working fluid and its state at inlet. span1, span2: float Inlet and outlet spans, :math:`H`. Alpha1: float Alpha2: float Inlet and outlet yaw angles, :math:`\alpha/^\circ`. Ma2: float Exit Mach number, :math:`\Ma_2`. Yh: float Estimate of the row energy loss coefficient, :math:`Y_h`. Uses compressor definition for diffusing passages, and turbine definition for contracting passages. htr: float Inlet hub-to-tip radius ratio, :math:`\htr`, defaults to just less than unity to approximate a linear cascade. RR: float Outlet to inlet radius ration, :math:`r_2/r_1`. Beta: (2,) array Inlet and outlet pitch angles, :math:`\beta/^\circ`. Only makes sense to be non-zero if radius ratio is not unity. Returns ------- ml: MeanLine An object specifying the flow along the mean line. """ span = np.array((span1, span2)) Alpha = np.array((Alpha1, Alpha2)) span = np.reshape(span, 2) Alpha = np.reshape(Alpha, 2) Beta = np.reshape(Beta, 2) # Trig cosBeta = util.cosd(Beta) cosAlpha = util.cosd(Alpha) tanAlpha = util.tand(Alpha) # Evaluate geometry first span_rm1 = (1.0 - htr) / (1.0 + htr) * 2.0 / cosBeta[0] rm1 = span[0] / span_rm1 rm = np.array([1.0, RR]) * rm1 rh = rm - 0.5 * span * cosBeta rt = rm + 0.5 * span * cosBeta rrms = np.sqrt(0.5 * (rh**2.0 + rt**2.0)) A = 2.0 * np.pi * rm * span Aflow = A * cosAlpha AR = Aflow[1] / Aflow[0] # We will have to guess an entropy rise, then update it according to the # loss coefficients and Mach number ds = 0.0 err = np.inf atol_Ma = 1e-7 Ma1 = 0.0 for i in range(10): # Conserve energy to get exit stagnation state So2 = So1.copy().set_h_s(So1.h, So1.s + ds) # Static states S2 = So2.to_static(Ma2) S1 = So1.to_static(Ma1) # Velocities from Mach number V2 = S2.a * Ma2 Vt2 = V2 * np.sqrt(tanAlpha[1] ** 2.0 / (1.0 + tanAlpha[1] ** 2.0)) Vm2 = np.sqrt(V2**2.0 - Vt2**2.0) # Mass flow and inlet static state mdot = S2.rho * Vm2 * A[-1] Vm1 = mdot / S1.rho / A[0] Vt1 = tanAlpha[0] * Vm1 V1 = np.sqrt(Vm1**2.0 + Vt1**2.0) # Update inlet Mach Ma1_new = V1 / S1.a err = Ma1 - Ma1_new Ma1 = Ma1_new if np.abs(err) < atol_Ma: break # Update loss using appropriate definition horef = So1.h if AR >= 1.0: # Compressor href = S1.h else: # Turbine href = S2.h # Ideal state is isentropic to the exit static pressure S2s = S2.copy().set_P_s(S2.P, So1.s) h2_new = S2s.h + Yh * (horef - href) S2_new = S2.copy().set_P_h(S2.P, h2_new) ds = S2_new.s - So1.s # Verify the loop has converged Yh_out = (S2.h - S2s.h) / (horef - href) assert np.isclose(Yh_out, Yh, atol=1e-3) # Assemble the data S = S1.stack((S1, S2)) Ma = np.array((Ma1, Ma2)) V = S.a * Ma Vxrt = np.stack(util.angles_to_velocities(V, Alpha, Beta)) Omega = np.zeros_like(Vxrt[0]) ml = turbigen.flowfield.make_mean_line(rrms, A, Omega, Vxrt, S) # Check mass, energy conserved assert np.ptp(ml.mdot) < ml.mdot[0] * 1e-3 assert np.ptp(ml.ho) / np.mean(ml.cp) < 0.1 return ml
[docs] def inverse(ml): """Reverse a cascade mean-line to design variables. Parameters ---------- ml: MeanLine A mean-line object specifying the flow in a cascade. Returns ------- out : dict Dictionary of aerodynamic design parameters with fields: `So1`, `span1`, `span2`, `Alpha1`, `Alpha2`, `Ma2`, `Yh`, `htr`, `RR`, `Beta`. The fields have the same meanings as in :func:`forward`. """ # Pull out states S2s = ml.empty().set_P_s(ml.P[-1], ml.s[0]) # Loss coefficient horef = ml.ho[0] if ml.ARflow[0] >= 1.0: # Compressor href = ml.h[0] else: # Turbine href = ml.h[1] Yh_out = (ml.h[1] - S2s.h) / (horef - href) out = { "So1": ml.stagnation[0], "span1": ml.span[0], "span2": ml.span[1], "Alpha1": ml.Alpha[0], "Alpha2": ml.Alpha[1], "Ma2": ml.Ma[1], "Yh": Yh_out, "htr": ml.htr[0], "RR": ml.RR[0], "Beta": ml.Beta.tolist(), } return out