def prepare_homogenous_transition(p, m_dot, steps, fp: FluidProperties): x = np.linspace(start=0, stop=1, num=steps) # [-] Vapour quality range ## NOTE: subscript sat for sat has been dropped for readability # Calculate saturation parameters at edges T_sat = fp.get_saturation_temperature(p=p) # [K] Saturation temperature rho_l = fp.get_liquid_density_at_psat(p_sat=p) # [kg/m^3] rho_g = fp.get_vapour_density_at_psat(p_sat=p) # [kg/m^3] Gas saturation density # Void fraction is precalculated because it allow for simple evaluation of velocity when geometry changes alpha = tp.homogenous_void_fraction(x=x, rho_g=rho_g, rho_l=rho_l) # [-] Void fraction rho = tp.mixture_density(alpha=alpha, rho_g=rho_g, rho_l=rho_l) # [kg/m^3] Mixture density of two-phase flow # Mean viscosity has no obvious way to be calculated and as such, a relation must simply be chosen [10.42] from Carey2008 is used. mu_l = fp.get_liquid_saturation_viscosity(p_sat=p) # [Pa*s] mu_g = fp.get_gas_saturation_viscosity(p_sat=p) # [Pa*s] mu = tp.mean_viscosity(mu_g=mu_g, mu_l=mu_l, rho_l=rho_l, rho_g=rho_g, x=x) # [Pa*s] # Thermal conductivity at saturation kappa_l = fp.get_liquid_saturation_conductivity(p_sat=p) # [W/(m*K)] kappa_g = fp.get_gas_saturation_conductivity(p_sat=p) # [W/(m*K)] # Mean conductivity kappa = tp.mean_conductivity(kappa_g=kappa_g, kappa_l=kappa_l, rho_l=rho_l, rho_g=rho_g, x=x) # [W/(m^2*K)] # Prandtl numbers at saturation, Pr_l = fp.get_saturation_Prandtl_liquid(p_sat=p) # [-] Pr_g = fp.get_saturation_Prandtl_gas(p_sat=p) # [-] # Mean Prandtl Pr = tp.mean_Prandtl(Pr_g=Pr_g, Pr_l=Pr_l, rho_l=rho_l, rho_g=rho_g, x=x) # [-] # Saturation enthalpies h_sat_liquid = fp.get_saturation_enthalpy_liquid(p=p) # [J/kg] h_sat_gas = fp.get_saturation_enthalpy_gas(p=p) # [J/kg] # Enthalpy as function of vapour quality x h = h_sat_liquid + (h_sat_gas-h_sat_liquid) * x # [J/kg] Saturation enthalpy as flow quality increases delta_h = delta_enthalpy_per_section(h=h) # [J/kg] Enthalpy difference per section Q_dot = required_power(m_dot=m_dot, delta_h=delta_h) # [W] Heating power required to increase enthalpy in each sections return { 'x': x, 'alpha': alpha, 'T_sat': T_sat, 'rho': rho, 'rho_l': rho_l, 'rho_g': rho_g, 'mu': mu, 'mu_l': mu_l, 'mu_g': mu_g, 'Pr_l': Pr_l, 'Pr_g': Pr_g, 'Pr': Pr, 'kappa_l': kappa_l, 'kappa_g': kappa_g, 'kappa': kappa, 'h': h, 'Q_dot': Q_dot, }
def prepare_single_phase_liquid(T_inlet, steps, p_ref, m_dot, fp: FluidProperties): """ Prepare numpy arrays for calculating channel length in a liquid single-phase section of a channel. NOTE: This is done to avoid recalculating arrays that are not dependent on channel geometry, therefore speeding up optimizations.\ After all, during optimization the geometry is what varies.\ Also it also ensure that temperature endpoint and enthalpy cleanly match with saturation temperature in the correct phase Args: T_inlet (K): Inlet temperature steps (-): Amount steps of dT taken to reach saturation temperature T_sat (dT = (T_sat-T_inlet)/2) p_ref (Pa): Pressure assumed constant along channel, equal to inlet pressure m_dot (kg/s): Mass flow fp (FluidProperties): Object to access propellant properties with """ T_sat = fp.get_saturation_temperature(p=p_ref) # [K] Saturation temperature assert ( T_inlet < T_sat) # Check input assert (steps > 1) # Temperature and other intermediate variable in channel section i=0...n T, dT = np.linspace(start=T_inlet, stop=T_sat, num=steps,retstep=True) # [K] Temperature T_i (also returns steps between sections) # The reference temperature for heat transfer calculations # The first value [0] should not be important. The heat transfer calculated at i is between i-1 and i # So, from T[i-1] to T[i]. So, if there reference temperature is the average dT/2 must SUBTRACTED #T_ref = T - dT/2 # [K] Reference temperature for heat transfer calculations ## Get all thermodynamic values that can be precalculated # NOTE: all last values must be replaced with the correct values for the saturated liquid state # Before the values are replaced, sometimes an error is thrown because the values are close to the saturation point # That, or NaNs and infinites show up. This shouldn't be a problem, unless the second-to-last points also start getting close to the saturation point # Enthalpy h = fp.get_enthalpy(T=T, p=p_ref) # [J/kg] Enthalpy h[-1] = fp.get_saturation_enthalpy_liquid(p=p_ref) # [J/kg] Saturation enthalpy at T_n = T_sat # Heating power required in section to increase temp by dT. Use enthalpy difference delta_h = delta_enthalpy_per_section(h=h) # [J/kg] Enthalpy difference per section Q_dot = required_power(m_dot=m_dot, delta_h=delta_h) # [W] # Density rho = fp.get_density(T=T, p=p_ref) # [kg/m^3] Density rho[-1] = fp.get_liquid_density_at_psat(p_sat=p_ref) # [kg/m^3] Saturation density # Prandtl number Pr = fp.get_Prandtl(T=T, p=p_ref) # [-] Prandtl number Pr[-1] = fp.get_saturation_Prandtl_liquid(p_sat=p_ref) # [-] Saturation Prandtl # Thermal conductivity kappa = fp.get_thermal_conductivity(T=T, p=p_ref) # [W/(m*K)] Conductivity kappa[-1] = fp.get_liquid_saturation_conductivity(p_sat=p_ref) # [W/(m*K)] Saturation conductivity # Viscosity mu = fp.get_viscosity(T=T, p=p_ref) # [Pa*s] Viscosity mu[-1] = fp.get_liquid_saturation_viscosity(p_sat=p_ref) # [Pa*s] Saturation viscosity return {\ "T":T, # [K] "dT": dT, # [K] "rho": rho, # [kg/m^3] "h": h, # [J/kg] "Q_dot": Q_dot, # [W] "Pr": Pr, # [-] "kappa": kappa, # [W/(m*K)] "mu": mu, # [Pa*s] }
# Design parameters p = 5e5 # Pressure through channel [Pa] m_dot = 200e-6 # [kg/s] A_channel = 1e-6 # [m^2] Channel cross sections D_h = 1e-6 * np.array((100, 200, 500)) # [m] Hydraulic diameters # Mass flux calculated for reference G = m_dot / A_channel # [kg/(m^2*s)] Mass flux print("Mass flux: {:3.1f} kg/(m^2*s)".format(G)) # Saturatoin conditions rho_l = fp.get_liquid_density_at_psat( p_sat=p) # [kg/m^3] Liquid density at saturation point rho_g = fp.get_vapour_density_at_psat( p_sat=p) # [kg/m^3] Vapour density at saturation point mu_l = fp.get_liquid_saturation_viscosity( p_sat=p) # [Pa*s] Viscosity at liquid saturatoin point (for Re_le) Bo = fp.get_Bond_number(p_sat=p, L_ref=D_h) # [-] Bond number # Calculate two-phase Nusselt number x = np.linspace(start=0, stop=1, num=10000) D_iter = np.nditer(D_h, flags=['c_index']) Nu_tp_laminar = np.zeros( (np.size(D_h), np.size(x) )) # [-] Storing two-phase Nusselt numbers for assumed laminar flow Nu_tp_turbulent = np.zeros_like( Nu_tp_laminar ) # [-] Storing two-phase Nusselt numbers for assumed turbulent flow for D in D_iter: i = D_iter.index # Flow parameters for entire flow as a liquid