Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
# 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)

Nu_DB_liquid = np.zeros_like(Reynolds)
Nu_DB_gas = np.zeros_like(Reynolds)
Nu_Kandlikar_liquid = np.zeros_like(Reynolds)
#Nu_Kandlikar_gas = np.zeros_like(Reynolds)
# Calculate Nusselt number for different relations

# Iterare over Reynolds numbers
# print(Reynolds)
# iter_Re = np.nditer(Reynolds, flags=['c_index'])
Ejemplo n.º 3
0
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
    Re_le = Reynolds_from_mass_flow(
Ejemplo n.º 4
0
def calc_homogenous_transition(p_sat, x, alpha, T_sat, rho_l, rho_g, rho, m_dot, mu_l, mu, Pr, Pr_l, kappa, kappa_l, Q_dot, T_wall, D_hydr, wetted_perimeter, A_channel, Nu_func_tp, Nu_func_le, Nu_func_dryout, fp: FluidProperties, wall_args=None):
    """[summary]

    Args:
        p_sat ([type]): [description]
        x ([type]): [description]
        alpha ([type]): [description]
        T_sat ([type]): [description]
        rho_l ([type]): [description]
        rho_g ([type]): [description]
        rho ([type]): [description]
        m_dot ([type]): [description]
        mu_l ([type]): [description]
        mu ([type]): [description]
        Pr ([type]): [description]
        Pr_l ([type]): [description]
        kappa ([type]): [description]
        kappa_l ([type]): [description]
        Q_dot ([type]): [description]
        T_wall ([type]): [description]
        D_hydr ([type]): [description]
        wetted_perimeter ([type]): [description]
        A_channel ([type]): [description]
        Nu_func_tp ([type]): [description]
        Nu_func_le ([type]): [description]
        Nu_func_dryout ([type]): [description]
        fp (FluidProperties): [description]
        wall_args ([type], optional): [description]. Defaults to None.

    Returns:
        [type]: [description]
    """
    # Calculate flow velocity 
    # Homogenous assumption means that liquid and gas velocity are equal, so one of two must be calculated.
    # Alpha (void fraction) has already been calculated to satisfy this condition
    # For both velocities there will be some issues with a singularity at (x=0, alpha =0) or (x=1, alpha=1), but the overal density rho does not have this problem
    #u_l = (m_dot / A_channel) * ( 1 - x ) /  (rho_l * ( 1- alpha )) # [m/s]
    #u_g = (m_dot / A_channel) *     x     /  (rho_g *     alpha) # [m/s]
    u = (m_dot / A_channel) / rho # [m/s]
    
    ## Calculate flow similarity/two-phase parameters that can only be known as soon as the geometry is known
    ## NOTE: mu is some form of weighted average and there are several ways to weight it (prepare_ function has the method)
    Re = Reynolds_from_mass_flow(m_dot=m_dot, A_channel=A_channel, L_ref=D_hydr, mu=mu) # [-]

    # Bond number
    Bo = fp.get_Bond_number(p_sat=p_sat,L_ref=D_hydr) # [-] Bond number

    # Nusselt number for entire flow as liquid (often used for two-phase relations)
    # NOTE: _le is often used as subscript, but _l might sometimes mean something else, such as G(1-x) * L / (A * mu_l). _le does NOT scale with (1-x) and is G * L / ( A * mu_l ) 
    Re_le = Reynolds_from_mass_flow(m_dot=m_dot, A_channel=A_channel, L_ref=D_hydr, mu=mu_l) # [-] Use viscosity of liquid phase to get Re_le
    args_le = { 'Re': Re_le,
                'Pr': Pr_l}
    
    Nu_le = Nu_func_le(args=args_le) # [-] Nusselt number as if entire flow was liquid.
    args_dryout = { 
        'Re': Re,
        'Pr': Pr,
        'kappa': kappa,
        'kappa_l': kappa_l,
    }
    Nu_dryout = Nu_func_dryout(args=args_dryout)

    ## Actual Nusselt number
    args = {    'Re': Re,
                'Pr': Pr_l,
                'Bo': Bo,
                'rho_g': rho_g,
                'rho_l': rho_l,
                'x': x,
                'Nu_le': Nu_le,
                'Nu_dryout': Nu_dryout,
                }
    Nu = Nu_func_tp(args=args) # [-] Two-phase Nusselt number

    # The Nusselt number is calculated in relation to liquid thermal conducitvity only
    h_conv = heat_transfer_coefficient_from_Nu(Nu=Nu, kappa=kappa_l, L_ref=D_hydr) # [W/(m^2 * K)] Heat transfer coefficient

    # For backwards compatability with test code, effect of wall temperature thickness can be activate separetly and is off by default
    we = None # Pass nothing to end result, if no wall arguments are passed
    if wall_args is not None: # If no information about wall is provided, skip this part
        # Call function to get dictionary of relevant wall effect parameters
        we = calc_wall_effect_parameters(\
            h_conv=h_conv,
            w_channel_spacing=wall_args['w_channel_spacing'],
            kappa_wall=wall_args['kappa_wall'], # Thermal conductivity of the wall
            h_channel=wall_args['h_channel'], # NOTE: these arguments were not already passed to this function, due to earlier design choices
            w_channel=wall_args['w_channel'],
            T_wall_top=T_wall, # The temperature of the top is simply the heater temperature at the top, which was earlier set to T_wall
            T_wall_bottom=wall_args['T_wall_bottom'], # IMPORTANT: The bottom wall temperature is the one that must be guessed or iterated towards!
            T_fluid=T_sat) # The fluid temperature is equal 
            
        T_wall = we['T_wall_effective'] # [K]

    # print("(Effective) wall temperature (K): ")
    # print(T_wall)

    # NOTE: T_wall may be replaced if T_wall is changed due to calculated wall effects
    A_heater = required_heater_area(Q_dot=Q_dot, h_conv=h_conv, T_wall=T_wall, T_ref=T_sat) # [m^2] Required heater area to heat up section with Q_dot
    delta_L = A_heater / wetted_perimeter # [m] Required channel section length for heating area
    #assert(np.all(delta_L>0))
    L = np.cumsum(delta_L) # [m] Cumulative channel length of two-phase section

    # Note, now the channel length is known, the heat transfer in the plane of the bottom wall can be calculated (which must be equal to radiation heat loss)
    # This is only necessary if wall effects are taken into account
    Q_bottom_plane_heat_balance = None # [W] Is None unless calculated to prevent use if not actually calculated
    if we is not None:
        Q_bottom_plane_heat_balance = calc_bottom_plane_heat_balance( 
            h_conv=h_conv,
            T_fluid=T_sat,
            we=we,
            wall_args=wall_args,
            delta_L=delta_L) 
        


    return {
        'L': L,
        'delta_L': delta_L,
        'u': u,
        'rho': rho,
        'Re': Re,
        'Nu': Nu,
        'Nu_le': Nu_le,
        'h_conv': h_conv,
        'Q_bottom_plane_heat_balance': Q_bottom_plane_heat_balance,
    }