def two_phase_single_channel(T_wall, w_channel, Nu_func_gas, Nu_func_liquid, T_inlet, T_chamber, p_ref, m_dot, h_channel, fp: FluidProperties, print_info=True): """ Function that calculates the total power consumption of a specific chamber, in order to optimize the chamber Args: T_wall (K): Wall temperature w_channel (m): Channel width Nu_func_gas (-): Nusselt function for gas phase Nu_func_liquid (-) Nusselt function for liquid phase T_inlet (K): Chamber inlet temperature T_chamber (K): Chamber outlet temperature (same as T_c in IRT) p_ref (Pa): Reference pressure for the Nusselt relation and flow similary parameters (same as inlet pressure as no pressure drop is assumed) m_dot (kg/s): Mass flow h_channel (m): Channel height w_channel_margin (m): The amount of margin around the chamber for structural reasons. Important because it also radiates heat fp (- ): [description] print_info(Bool): for debugging purposes """ # Calculate saturation temperature, to determine where transition from gas to liquid occurs T_sat = fp.get_saturation_temperature(p=p_ref) # [K] # Sanity check on input assert (T_chamber > T_sat) assert (T_wall > T_chamber) # Calculate the two reference temperatures for the separated phases T_bulk_gas = (T_sat + T_chamber) / 2 # [K] Bulk temperature gas phase T_bulk_liquid_multi = ( T_inlet + T_sat) / 2 # [K] Bulk temperature of liquid and multi-phase flow # Calculate the density at these reference points rho_bulk_gas = fp.get_density(T=T_bulk_gas, p=p_ref) # [kg/m^3] rho_bulk_liquid_multi = fp.get_density(T=T_bulk_liquid_multi, p=p_ref) # [kg/m^3] # Channel geometry A_channel = w_channel * h_channel # [m^2] Area through which the fluid flows wetted_perimeter = wetted_perimeter_rectangular( w_channel=w_channel, h_channel=h_channel ) # [m] Distance of channel cross-section in contact with fluid D_hydraulic = hydraulic_diameter_rectangular( w_channel=w_channel, h_channel=h_channel) # [m] Hydraulic diameter # Flow similarity parameters (for debugging and Nu calculatoin purposes) Re_bulk_gas = fp.get_Reynolds_from_mass_flow( m_dot=m_dot, p=p_ref, T=T_bulk_gas, L_ref=D_hydraulic, A=A_channel) # [-] Bulk Reynolds number in the gas phase Re_bulk_liquid_multi = fp.get_Reynolds_from_mass_flow( m_dot=m_dot, p=p_ref, T=T_bulk_liquid_multi, L_ref=D_hydraulic, A=A_channel) # [-] Bulk Reynolds number in the liquid/multi-phase Pr_bulk_gas = fp.get_Prandtl( T=T_bulk_gas, p=p_ref) # [-] Prandtl number in the gas phase Pr_bulk_liquid_multi = fp.get_Prandtl( T=T_bulk_liquid_multi, p=p_ref) # [-] Prandtl number in liquid/multi-phase Bo_sat = fp.get_Bond_number( p_sat=p_ref, L_ref=D_hydraulic ) # [-] Bond number at saturation pressure (assumed to be p_ref) # Calculate Nusselt number in both sections args_gas = { 'Re': Re_bulk_gas, # Arguments for Nusselt function (gas phase) 'Pr': Pr_bulk_gas, 'Bo': Bo_sat, } args_liquid_multi = { # Arguments for Nusselt function (liquid/multi phase) 'Re': Re_bulk_liquid_multi, 'Pr': Pr_bulk_liquid_multi, 'Bo': Bo_sat, } Nu_gas = Nu_func_gas(args=args_gas) Nu_liquid_multi = Nu_func_liquid(args=args_liquid_multi) # Calculate Stanton number in both sections St_gas = Stanton_from_Nusselt_and_velocity( Nu=Nu_gas, T_ref=T_bulk_gas, p_ref=p_ref, L_ref=D_hydraulic, m_dot=m_dot, A=A_channel, fp=fp) # [-] Stanton number in gas phase St_liquid_multi = Stanton_from_Nusselt_and_velocity( Nu_liquid_multi, T_ref=T_bulk_liquid_multi, p_ref=p_ref, L_ref=D_hydraulic, m_dot=m_dot, A=A_channel, fp=fp) # [-] Stanton number in liquid phase # Calculate velocity for convection parameter (bulk temp used as reference for phase) u_bulk_gas = velocity_from_mass_flow( A=A_channel, m_dot=m_dot, rho=rho_bulk_gas) # [m/s] Velocity at the gas bulk reference state u_bulk_liquid_multi = velocity_from_mass_flow( A=A_channel, m_dot=m_dot, rho=rho_bulk_liquid_multi ) # [m/s] Velocity at the liquid/multi-phase bulk reference state # Convective parameter h_conv_gas = h_conv_from_Stanton( Stanton=St_gas, u=u_bulk_gas, T_ref=T_bulk_gas, p_ref=p_ref, fp=fp ) # [W/(m^2*K)] Convective heat transfer coefficient at bulk gas state h_conv_liquid_multi = h_conv_from_Stanton( Stanton=St_liquid_multi, u=u_bulk_liquid_multi, T_ref=T_bulk_liquid_multi, p_ref=p_ref, fp=fp ) # [W/(m^2*K)] Convective heat transfer coefficient at bulk liquid/multi-phase state # Required specific enthalpy change for heating the separate sections h_outlet = fp.get_enthalpy( T=T_chamber, p=p_ref) # [J/kg] Specific enthalpy at the outlet h_sat_gas = fp.get_saturation_enthalpy_gas( p=p_ref) # [J/kg] Specific enthalpy of saturated gas h_inlet = fp.get_enthalpy(T=T_inlet, p=p_ref) # [J/kg] # Required specific enthalpy increases delta_h_gas = h_outlet - h_sat_gas # [J/kg] Enthalpy increase needed to go from saturated gas to outlet enthalpy delta_h_liquid_multi = h_sat_gas - h_inlet # [J/k] Enthalpy increase needed to go from inlet enthalpy to saturated gas # Required power for those enthalpy changes at the given mass flow Q_dot_gas = required_power(m_dot=m_dot, delta_h=delta_h_gas) # [W] Q_dot_liquid_multi = required_power(m_dot=m_dot, delta_h=delta_h_liquid_multi) # [W] # Required heater area to achieve the required power A_heater_gas = required_heater_area(Q_dot=Q_dot_gas, h_conv=h_conv_gas, T_wall=T_wall, T_ref=T_bulk_gas) # [m^2] A_heater_liquid_multi = required_heater_area( Q_dot=Q_dot_liquid_multi, h_conv=h_conv_liquid_multi, T_wall=T_wall, T_ref=T_bulk_liquid_multi) # [m^2] # Required length to achieve desired area L_channel_gas = A_heater_gas / wetted_perimeter # [m] Length of channel after gas is saturated L_channel_liquid_multi = A_heater_liquid_multi / wetted_perimeter # [m] Length of channel after heater L_channel = L_channel_gas + L_channel_liquid_multi # [m] L_hydrodynamic_entrance = D_hydraulic * Re_bulk_liquid_multi * 0.04 # [m] Hydrodynamic entrance to estimate if the flow is fully developed assert (h_outlet > h_sat_gas) assert (h_sat_gas > h_inlet) if (print_info): print("\n--- SPECIFIC ENTHALPY AT DIFFERENT STATIONS ---") print("h_outlet: {:4.3f} J/kg".format(h_outlet)) print("h_sat_gas: {:4.3f} J/kg".format(h_sat_gas)) print("h_inlet: {:4.3f} J/kg".format(h_inlet)) print("\n --- REQUIRED POWER ---") print("Q_dot_gas: {:2.5f} W".format(Q_dot_gas)) print("Q_dot_liquid_multi: {:2.5f} W".format(Q_dot_liquid_multi)) print("\n --- BULK GAS PHASE PARAMETERS --- ") print("u: {:3.2f} m/s".format(u_bulk_gas)) print("Nu: {}".format(Nu_gas)) print("Re: {}".format(Re_bulk_gas)) print("Pr: {}".format(Pr_bulk_gas)) print("St: {}".format(St_gas)) print("Bo_sat: {}".format(Bo_sat)) print("\n --- BULK LIQUID/MULTI-PHASE PARAMETERS ---") print("u: {:3.4f} m/s".format(u_bulk_liquid_multi)) print("Nu: {}".format(Nu_liquid_multi)) print("Re: {}".format(Re_bulk_liquid_multi)) print("Pr: {}".format(Pr_bulk_liquid_multi)) print("St: {}".format(St_liquid_multi)) print("\n --- CHARACTERISTIC GEOMETRIC VALUES --- ") print("Hydrodynamic entance length: {:3.3f} micron".format( L_hydrodynamic_entrance * 1e6)) print("Hydraulic diameter: {:3.3f} micron".format(D_hydraulic * 1e6)) print("L/D: {:4.2f} ".format(L_channel / D_hydraulic)) print("L/X_T {:4.2f}".format(L_channel / L_hydrodynamic_entrance)) print("\n --- RESULTING GEOMETRY ---") print("Total length: {:3.3f} mm".format(L_channel * 1e3)) print("Length (liquid/multi): {:3.3f} mm".format( L_channel_liquid_multi * 1e3)) print("Length (gas): {:3.4f} mm".format(L_channel_gas * 1e3)) print("Relative length (gas) {:3.3f} \%".format(L_channel_gas / L_channel * 100)) ## Return a dictionary with results and interesting intermediate values res = { "L_channel": L_channel, # [m] Total length of channel "D_hydraulic": D_hydraulic, # [m] Hydraulic diameter of channel "Nu_liquid_multi": Nu_liquid_multi, # [-] Nusselt number of liquid/multi-phase flow "Pr_bulk_liquid_multi": Pr_bulk_liquid_multi, # [-] Prandlt number of liquid/multi-phase flow "Re_bulk_liquid_multi": Re_bulk_liquid_multi, # [-] Reynolds number of liquid/multi-phase flow "St_liquid_multi": St_liquid_multi, # [-] Stanton number of liquid/multi-phase flow "h_conv_liquid_multi": h_conv_liquid_multi, # [W/(m^2*K)] Heat transfer coefficient "A_heater_liquid_multi": A_heater_liquid_multi, # [m^2] Required heater area for liquid/multi-phase flow "L_channel_liquid_multi": L_channel_liquid_multi, # [m] Length of channel to get required heater area "u_bulk_liquid_multi": u_bulk_liquid_multi, # [m/s] Bulk flow velocity of liquid/multi-phase flow "rho_bulk_liquid_multi": rho_bulk_liquid_multi, # [kg/m^3] Bulk density of liquid/multi-phase flow "T_bulk_liquid_multi": T_bulk_liquid_multi, # [K] Bulk temperature of liquid/multi-phase flow "delta_h_liquid_multi": delta_h_liquid_multi, # [J/kg] Enthalpy change from inlet to saturated gas "Q_dot_liquid_multi": Q_dot_liquid_multi, # [W] Power required for enthalpy change ## Same thing but for gas values "Nu_gas": Nu_gas, # [-] "Pr_bulk_gas": Pr_bulk_gas, # [-] "Re_bulk_gas": Re_bulk_gas, # [-] "St_gas": St_gas, # [-] "h_conv_gas": h_conv_gas, # [W/(m^2*K)] "A_heater_gas": A_heater_gas, # [m^2] "L_channel_gas": L_channel_gas, # [m] "u_bulk_gas": u_bulk_gas, # [m/s] "rho_bulk_gas": rho_bulk_gas, # [kg/m^3] "T_bulk_gas": T_bulk_gas, # [K] "delta_h_gas": delta_h_gas, # [J/kg] "Q_dot_gas": Q_dot_gas, # [W] } return res
def chamber_performance_from_Nu(Nu_func, T_inlet, T_chamber, T_ref, T_wall, p_ref, m_dot, A_channel, L_ref, fp: FluidProperties): """ Function that calculates the power consumption and heating area for a specific chamber Args: Nu_func (-): Nusselt function, that implement the emperical relation of choice T_inlet (K): Chamber inlet temperature T_chamber (K): Chamber outlet temperature (same as T_chamber for IRT) T_ref (K): Reference temperature for the Nusselt relation and flow similary parameters T_wall (K): Wall temperature p_ref (Pa): Chamber pressure (no pressure drop assumed) m_dot (kg/s): Mass flow A_channel (m^2): Cross-sectional area of the chamber, through which the fluid flows L_ref (m): Reference length for Nusselt relation and flow similarty parameters fp (FluidProperties): Object from which Fluid Properties are determined Returns: dictionary with heater area, power required to heat up flow and Nusselt number """ ## Make sure all parameters are calculated at the same reference state (including velocity!) # Pr and Re parameters needed for most Nusselt relation rho_ref = fp.get_density(T=T_ref, p=p_ref) # [kg/m^3] Reference density u_ref = velocity_from_mass_flow( A=A_channel, m_dot=m_dot, rho=rho_ref) # [m/s] Speed at reference state print("u_ref {} m/s".format(u_ref)) Re_ref = fp.get_Reynolds_from_mass_flow( T=T_ref, p=p_ref, L_ref=L_ref, m_dot=m_dot, A=A_channel) # [-] Reynolds number at reference state Pr_ref = fp.get_Prandtl(T=T_ref, p=p_ref) # [-] Prandtl number at reference state # Now the Nusselt can be determined Nusselt = Nu_func(args={ 'Re': Re_ref, 'Pr': Pr_ref }) # [-] Nusselt number at given state (used for plotting purposes) Stanton = Stanton_from_Nusselt_func_and_velocity( Nu_func=Nu_func, m_dot=m_dot, A=A_channel, T_ref=T_ref, p_ref=p_ref, L_ref=L_ref, fp=fp) # [-] Stanton number at reference state h_conv = h_conv_from_Stanton(Stanton=Stanton, u=u_ref, T_ref=T_ref, p_ref=p_ref, fp=fp) # Now determine how much energy must be convected delta_h = ideal_enthalpy_change(T_inlet=T_inlet, p_inlet=p_ref, T_outlet=T_chamber, p_outlet=p_ref, fp=fp) # [J/kg] Q_dot = required_power( m_dot=m_dot, delta_h=delta_h) # [W] Required power to achieve delta_h A_heater = required_heater_area(Q_dot=Q_dot, h_conv=h_conv, T_wall=T_wall, T_ref=T_ref) # [m^2] assert (A_heater > 0) # Return a dictionary with interesting values return { 'A_heater': A_heater, 'Q_dot': Q_dot, 'Nusselt': Nusselt, 'Re_ref': Re_ref, 'Pr_ref': Pr_ref }
p_outlet = p_inlet # [Pa] Outlet pressure (assumed roughly equal to inlet) T_inlet = td['T_inlet'] # [K] # Geometry calculations D_h = hydraulic_diameter_rectangular( w_channel=w_channel, h_channel=h_channel) # [m] Hydraulic diameter A_channel = w_channel * h_channel # Inlet conditions rho_inlet = fp.get_density(T=T_inlet, p=p_inlet) # [kg/m^3] u_inlet = velocity_from_mass_flow(A=A_channel, m_dot=m_dot, rho=rho_inlet) # Outlet conditions rho_outlet = fp.get_density(T=T_outlet, p=p_outlet) u_outlet = velocity_from_mass_flow(A=A_channel, m_dot=m_dot, rho=rho_outlet) Re_outlet = fp.get_Reynolds_from_mass_flow(T=T_outlet, p=p_outlet, L_ref=D_h, m_dot=m_dot, A=A_channel) print("\n\nTHRUSTER NAME: {}".format(td['name'])) print("\n --- GEOMETRY ---") print("Channel length: {:4.3f} mm".format(L_channel * 1e3)) print("Hydraulic diameter: {:4.3f} um".format(D_h * 1e6)) print("L/D: {:3.2f} ".format(L_channel / D_h)) print("\n --- INLET FLOW CONDITIONS --- ") print("Density: {:3.2f} kg/m^3".format(rho_inlet)) print("\n --- OUTLET FLOW CONDITIONS ---") print("Mass flow: {:1.3f} mg/s".format(m_dot * 1e6)) print("Density: {:1.3f} kg/m^3".format(rho_outlet))
T_liquid = 300 # [K] T_gas = 500 # [K] m_dot = 1e-6 # [kg/s] For Kandlikar relation. #h_c = 100e-6 # [m] Channel depth/height # Density is needed to reverse calculate the reference length for Re, so it can be applied in other flow similarity parameters rho_liquid = fp.get_density(T=T_liquid, p=p) mu_liquid = fp.get_viscosity(T=T_liquid, p=p) # Range of Reynolds numbers to consider Reynolds = np.logspace(start=0, stop=2.8) D_hydraulic = np.logspace(start=-4.93, stop=-2.93) A_channel = D_hydraulic**2 Reynolds_2 = fp.get_Reynolds_from_mass_flow(T=T_liquid, p=p, L_ref=D_hydraulic, m_dot=m_dot, A=A_channel) # Range of hydraulic diameter that fit this Reynolds number #w_channel = 2*m_dot/( Reynolds_100 * mu_liquid ) - h_c # [m] #A_channel = h_c * w_channel # [m^2] #D_hydraulic = basic.chamber.hydraulic_diameter_rectangular(w_channel=w_channel,h_channel=h_c) # [m] #Reynolds_check = fp.get_Reynolds_from_mass_flow(T=T_liquid, p=p, L_ref=D_hydraulic, m_dot=m_dot, A=A_channel) # [-] Bond = fp.get_Bond_number(p_sat=p, L_ref=D_hydraulic) # [m] # Prandtl number in both reference states Pr_liquid = fp.get_Prandtl(T=T_liquid, p=p) # [-] Pr_gas = fp.get_Prandtl(T=T_gas, p=p) # [-] # Conductivity in reference state conductivity_liquid = fp.get_thermal_conductivity(T=T_liquid, p=p)
it_T = np.nditer(T_wall, flags=['c_index']) # [K] To iterate over all T_chamber values for T in it_T: ## Make sure all parameters are calculated at the same reference state (including velocity) # Calculate all the bulk conditions required to determine the Nusselt number relation T_bulk = (T_inlet + T_chamber) / 2 # [K] Bulk temperature as reference rho_bulk = fp.get_density( T=T_bulk, p=p_inlet ) # [kg/m^3] Bulk density is required to get the correct velocity at the reference temperature u_bulk[it_T.index, :] = velocity_from_mass_flow( m_dot=m_dot, rho=rho_bulk, A=A_channel) # [m/s] The velocity at the bulk reference state Re_bulk[it_T.index, :] = fp.get_Reynolds_from_mass_flow(T=T_bulk, p=p_inlet, L_ref=Dh_channel, m_dot=m_dot, A=A_channel) # [-] Pr_bulk[it_T.index, :] = fp.get_Prandtl(T=T_bulk, p=p_inlet) # [-] # Now the convection parameters can be determined, taking care that the reference temperature and flow conditions are evaluated in the same location Nusselt[it_T.index, :] = Nu_func(args={ 'Re': Re_bulk[it_T.index, :], 'Pr': Pr_bulk[it_T.index, :] }) # [-] Not necessary, but useful for plots Stanton[it_T.index, :] = Stanton_from_Nusselt_func_and_velocity( Nu_func=Nu_func, m_dot=m_dot, A=A_channel, T_ref=T_bulk, p_ref=p_inlet, L_ref=Dh_channel,
def optim_P_total(channel_amount, w_channel, h_channel, inlet_manifold_length_factor, inlet_manifold_width_factor, l_exit_manifold, w_channel_spacing, w_outer_margin, T_wall, p_ref, m_dot, \ prepared_values, Nusselt_relations, pressure_drop_relations, convergent_half_angle, divergent_half_angle, F_desired, p_back, AR_exit, w_throat, emissivity_top, fp: FluidProperties, wall_args=None): # First calculate area ratio at entrance so it can be provided to contraction pressure drop function w_inlet_manifold = chamber.inlet_manifold_width(\ channel_amount=channel_amount, w_channel=w_channel, w_channel_spacing=w_channel_spacing, inlet_manifold_width_factor=inlet_manifold_width_factor) # [m] Total width of inlet manifold area_ratio_contraction = chamber.area_ratio_contraction(\ w_inlet_manifold=w_inlet_manifold, w_channel=w_channel, channel_amount=channel_amount) # [-] Area ratio of sudden contraction def x(T): wall_args[ 'T_wall_bottom'] = T # [K] Add the bottom wall temperature in the wall argument dictionary # Calculate heat transfer to determine channel length res = oneD.rectangular_multi_channel_homogenous_calculation(\ channel_amount=channel_amount, prepared_values=prepared_values, Nusselt_relations=Nusselt_relations, pressure_drop_relations=pressure_drop_relations, w_channel=w_channel, h_channel=h_channel, m_dot=m_dot, T_wall=T_wall, p_inlet=p_ref, fp=fp, area_ratio_contraction=area_ratio_contraction, wall_args=wall_args) #print(res['Q_total_bottom_plane_heat_balance']) return res['Q_total_bottom_plane_heat_balance'] ## ROOT FINDING PROBLEM FOR T_WALL_BOTTOM # The proper bounds for the optimization are very sensitive to wall temperature and chamber temperature # It is hard to pick bounds that are valid for a wide range of those parameters # The problem is that that a too low lower bound results in model results that are wholly invalid and break the optimization # Too high a lower bound results in the solution not being within the bounds at all. # The quick and dirty solution here is to stepwise move the bounds down until the valid solution is between it. # The stepsize must be small enough to reliably avoid the scenario where the calculations are completely incorrect. delta_T_bounds = 25 # [K] The size of the bound shift could determine how low the bounds can go to the final chamber temperature without resulting into incorrection calculations ## The resultant channel length, pressure drops, etc, depends on bottom wall temperature. It must be iterated towards here. T_wall_bottom_min = T_wall - delta_T_bounds # [K] Minimum temperature is in practice probably not lower than chamber temperature (not impossible, though) T_wall_bottom_max = T_wall bounds_are_correct = False # [bool] Is False until a solution has been found # The bounds are correct once they get the opposite sign while not bounds_are_correct: a = x(T_wall_bottom_max) b = x(T_wall_bottom_min) # If the solutions have the same sign, subtract delta_T_bounds if np.sign(a) == np.sign(b): T_wall_bottom_min -= delta_T_bounds T_wall_bottom_max -= delta_T_bounds else: bounds_are_correct = True root_result = root_scalar(x, bracket=([T_wall_bottom_min, T_wall_bottom_max])) if root_result.converged: T_wall_bottom = root_result.root # [m^2] wall_args['T_wall_bottom'] = T_wall_bottom #print(" T_wall_bottom: {:3.2f} K".format(T_wall_bottom)) else: raise Exception("No solution found for given temperature") res = oneD.rectangular_multi_channel_homogenous_calculation(\ channel_amount=channel_amount, prepared_values=prepared_values, Nusselt_relations=Nusselt_relations, pressure_drop_relations=pressure_drop_relations, w_channel=w_channel, h_channel=h_channel, m_dot=m_dot, T_wall=T_wall, p_inlet=p_ref, fp=fp, area_ratio_contraction=area_ratio_contraction, wall_args=wall_args) # Check if these solutions are eventually valid assert (np.all(res['res_l']['delta_L'] >= 0)) assert (np.all(res['res_tp']['delta_L'] >= 0)) assert (np.all(res['res_g']['delta_L'] >= 0)) l_channel = res['L_total'] # [m] Channel length p_chamber = res[ 'p_chamber'] # [Pa] Pressure out channel outlet/inlet of nozzle according to IRT T_chamber = res['T_chamber'] # Nozzle performance must be recalculated, if pressure drop occured assert (pressure_drop_relations is not None) # Just check is one was calculated if p_chamber <= 0: # If pressure drop was so large p_chamber was negative, the solution is invalid, and NaNs must be returned # Return the same dictionary, but all NaN. return { 'P_loss': np.nan, # [W] Current approximation of heat loss 'l_channel': np.nan, # [m] Channel length 'pressure_drop': np.nan, # [Pa] Total pressure drop 'dP_contraction': np.nan, # [Pa] Pressure drop de to contraction 'w_total': np.nan, # [m] Total chip width 'l_total': np.nan, # [m] Total chip length 'is_channel_choked': np.nan, 'Re_channel_exit': np.nan, # [-] Reynolds number at channel exit } # This only runs if pressure drop was not too large. # In that case the throat area must be recalculated still else: ep = engine_performance_from_F_and_T(F_desired=F_desired, p_chamber=p_chamber, T_chamber=T_chamber, AR_exit=AR_exit, p_back=p_back, fp=fp) # New throat widtl_inlet_manifoldmined from desired performance parameter w_throat_new = ep['A_throat'] / h_channel # [m] # Check if new pressure, does not cause choked heating channels is_channel_choked = ( w_channel * h_channel * channel_amount < ep['A_throat'] ) # [bool] If combined channel area is smaller than throat, they are choked. # Check new Reynolds number at channel exit for laminar/turbulent flow assumptions hydraulic_diameter = chamber.hydraulic_diameter_rectangular( w_channel=w_channel, h_channel=h_channel) Re_channel_exit = fp.get_Reynolds_from_mass_flow( T=T_chamber, p=p_chamber, L_ref=hydraulic_diameter, m_dot=m_dot, A=h_channel * w_channel) l_outlet = chamber.outlet_length(\ w_channel=w_channel, w_channel_spacing=w_channel_spacing, channel_amount=channel_amount, convergent_half_angle=convergent_half_angle, w_throat=w_throat_new, divergent_half_angle=divergent_half_angle, AR_exit=AR_exit, l_exit_manifold=l_exit_manifold ) l_inlet_manifold = chamber.inlet_manifold_length( w_inlet_manifold=w_inlet_manifold, inlet_manifold_length_factor=inlet_manifold_length_factor) l_total = chamber.total_chip_length(l_inlet_manifold=l_inlet_manifold, l_channel=l_channel, l_outlet=l_outlet) w_total = chamber.total_chip_width(\ w_inlet_manifold=w_inlet_manifold, w_outer_margin=w_outer_margin, w_throat=w_throat_new, AR_exit=AR_exit) A_chip = l_total * w_total # [m^2] P_rad_loss_top = chamber.radiation_loss( T=T_wall, A=A_chip, emmisivity=emissivity_top ) # [W] Radiation loss through top of chip P_rad_loss_bottom = chamber.radiation_loss( T=wall_args['T_wall_bottom'], A=A_chip, emmisivity=wall_args['emissivity_chip_bottom'] ) # Radiation loss through bottom of chip P_loss = P_rad_loss_top + P_rad_loss_bottom # [W] Total heat loss return { 'P_loss': P_loss, # [W] Current approximation of heat loss 'l_channel': l_channel, # [m] Channel length 'pressure_drop': res['dP_total'], # [Pa] Total pressure drop 'dP_contraction': res['dP_contraction'], # [Pa] Pressure drop due to contraction 'w_total': w_total, # [m] Total chip width 'l_total': l_total, # [m] Total chip length 'is_channel_choked': is_channel_choked, # [bool] 0 and 1 in this case, to check if channels are not too small 'Re_channel_exit': Re_channel_exit, # [-] Check Reynolds number to see if laminar flow assumptions still hold }