示例#1
0
def total_power_single_channel(T_wall, w_channel, Nu_func, T_inlet, T_chamber,
                               T_ref, p_ref, m_dot, h_channel,
                               w_channel_margin, emmisivity, fp):
    """ 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 (-): Nusselt function
        T_inlet (K): Chamber inlet temperature
        T_chamber (K): Chamber outlet temperature (same as T_c in IRT)
        T_ref (K): Reference temperature for the Nusselt relation and flow similary parameters
        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
        emmisivity (-) Emmisivity of the chamber material (for calculation of radation losses)
        fp (-  ): [description]
    """

    ## NOTE: just a test, assumptions are a bit sloppy, and this is just to test optimization approach at this stage

    A_channel = w_channel * h_channel  # [m^2] Channel area
    print("A_channel: {}".format(A_channel))
    wetted_perimeter = wetted_perimeter_rectangular(
        w_channel=w_channel, h_channel=h_channel
    )  # [m] Distance of channel cross-section in contact with fluid
    print("wetted_perimeter: {}".format(wetted_perimeter))
    # Reference length is hydraulic diameter
    D_hydraulic = hydraulic_diameter_rectangular(
        w_channel=w_channel, h_channel=h_channel)  # [m] Hydraulic diameter

    cp = chamber_performance_from_Nu(Nu_func=Nu_func,
                                     T_inlet=T_inlet,
                                     T_chamber=T_chamber,
                                     T_ref=T_ref,
                                     T_wall=T_wall,
                                     p_ref=p_ref,
                                     m_dot=m_dot,
                                     A_channel=A_channel,
                                     L_ref=D_hydraulic,
                                     fp=fp)
    ## Assume single-sided heater heat chamber material through-out at T-wall, and all along the wetted perimeter heat flows equally to teh propellant
    A_heater = cp['A_heater']  # [m^2]
    assert (A_heater > 0)
    L_channel = A_heater / wetted_perimeter  # [m] Required length of channel to achieve required heat flow
    print("L_channel: {}".format(L_channel))
    A_chip = required_chip_area(
        L_channel=L_channel,
        w_channel=w_channel,
        w_channel_margin=w_channel_margin
    )  # [m^2] Assume radiation occurs from silicon on just a single side of the heater
    print("A_microheater: {}".format(A_chip))
    P_radiation = radiation_loss(T=T_wall, A=A_chip,
                                 emmisivity=emmisivity)  # [W] Radiation loss
    P_total = P_radiation + cp[
        'Q_dot']  # [W] Total power consumption, the variable to minimize
    print("Heat loss {}".format(P_radiation / P_total))

    return P_total
示例#2
0
    def test_simple_input(self):
        h = 1
        w = 1

        exp = 4
        res = chamber.wetted_perimeter_rectangular(w_channel=w, h_channel=h)
        self.assertEqual(res, exp)

        h = 4

        exp = 10
        res = chamber.wetted_perimeter_rectangular(w_channel=w, h_channel=h)
        self.assertEqual(res, exp)

        w = 2
        exp = 12
        res = chamber.wetted_perimeter_rectangular(w_channel=w, h_channel=h)
        self.assertEqual(res, exp)
示例#3
0
def rectangular_multi_channel_homogenous_calculation(channel_amount, prepared_values, Nusselt_relations, pressure_drop_relations, w_channel, h_channel, m_dot, T_wall, p_inlet, fp: FluidProperties, area_ratio_contraction=None, wall_args=None):
    """Same as full_homogenous_calculation, but with channels combined

    Args:
        channel_amount (-): Number of channels
        prepared_values (dict): Dictionary with prepared thermodynamic variables
        Nusselt_relations (dict): Nusselt relations for different phases
        pressure_drop_relations (dict): Pressure drop relations for different phases and effects
        A_channel (m^2): Area of a single channel
        wetted_perimeter (m): Circumference of a single channel (fot heat flux purposes)
        D_hydraulic (m): Reference for Reynolds numbers etc...
        m_dot (kg/s): mass flow
        T_wall (K): Wall temperature
        p_ref (Pa): Pressure through channel
        fp (FluidProperties): Object to access propellant properties with

    Returns:
        Results {}: Return results which are relevant for optimization
    """
    m_dot_channel = m_dot / channel_amount # [kg/s] Mass flow for a single channel
    A_channel = w_channel * h_channel # [m^2] Area of a single channel
    D_hydraulic = hydraulic_diameter_rectangular(w_channel=w_channel, h_channel=h_channel) # [m] 
    wetted_perimeter = wetted_perimeter_rectangular(w_channel=w_channel, h_channel=h_channel) # [m] 

    # dP_contraction = None # [Pa] Contraction pressure drop is set to None by default, so it raises obvious errors if one attemps to use it without calculating it before (0 would hide errors)
    # # Contraction losses must be calculated here, as this pressure drop does significantly affect heat transfer
    # if pressure_drop_relations is not None:
    #     if 'contraction'  in pressure_drop_relations:
    #         area_ratio_contraction = w_channel*channel_amount / w_inlet_manifold # [-]
    #         dP_contraction = calc_contraction_loss(dP_func=pressure_drop_relations['contraction'])
            

    

    # Simulation of the flow resulting in desired channel length
    res = full_homogenous_calculation(
            prepared_values=prepared_values,
            Nusselt_relations=Nusselt_relations,
            pressure_drop_relations=pressure_drop_relations,
            A_channel=A_channel,
            wetted_perimeter=wetted_perimeter,
            D_hydraulic=D_hydraulic,
            m_dot=m_dot_channel,
            T_wall=T_wall,
            p_ref=p_inlet,
            fp=fp,
            area_ratio_contraction=area_ratio_contraction,
            wall_args=wall_args,
            )

    return res
示例#4
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
示例#5
0
                m_dot=m_dot, h_channel=h_channel, w_channel_margin=w_channel_margin,\
                    emmisivity=emmissivity, fp=fp)

print(x_result)

# Found optimum
T_superheat = x_result.x[0]  # [K]
w_channel = x_result.x[1]  # [m]

# Chamber performance following from optimum
T_wall = T_chamber + T_superheat  # [K] Wall temperature
A_channel = w_channel * h_channel  # [m^2] Channel area
mass_flux = m_dot / A_channel  # [kg/m^2] Used as reference for validity of many relations in micro-channel studies
print("A_channel: {}".format(A_channel))
wetted_perimeter = wetted_perimeter_rectangular(
    w_channel=w_channel, h_channel=h_channel
)  # [m] Distance of channel cross-section in contact with fluid
print("wetted_perimeter: {}".format(wetted_perimeter))
# Reference length is hydraulic diameter
D_hydraulic = hydraulic_diameter_rectangular(
    w_channel=w_channel, h_channel=h_channel)  # [m] Hydraulic diameter

cp = zD.chamber_performance_from_Nu(Nu_func=Nu_func, T_inlet=T_inlet, T_chamber=T_chamber,\
     T_ref=T_bulk, T_wall=T_wall, p_ref=p_inlet, m_dot=m_dot, A_channel=A_channel, L_ref=D_hydraulic, fp=fp)

L_channel = cp['A_heater'] / w_channel  # [m]
print("L_channel: {:3.4f} mm".format(L_channel * 1e3))
print("mass_flux: {}".format(mass_flux))
print("Mass flow: {:3.4f} mg/s".format(m_dot * 1e6))
## Print all results
print(ep)
示例#6
0
            'p_exit']  # [Pa] Nozzle exit pressure

# Calculate ideal power
h_inlet = fp.get_enthalpy(T=T_inlet,
                          p=p_chamber)  # [J/kg] Enthalpy at chamber inlet
delta_h = h_chamber - h_inlet  # [J/kg] Enthalpy change between inlet and chamber
Pt_ideal = m_dot * delta_h  # [W] Total ideal power consumption (no heat losses)

## Plot the results

fig, axs = plt.subplots(5, 2)

# Render the mass flow and throat width as a function of temperature and area ratios
w_throat = A_throat / h_channel  # [m] Throat width, determined by assuming channel depth
# Find out the hydraulic diameter for a rectangular channel
wetted_perimeter = wetted_perimeter_rectangular(
    w_channel=w_throat, h_channel=h_channel)  # [m] Wetted perimeter
D_hydraulic_throat = hydraulic_diameter(
    A=A_throat, wetted_perimeter=wetted_perimeter)  # [m] Hydraulic diameter
# Numpy and CoolProp don't play nicely together, so iterate over each element to calculate Reynolds's number
it_AR.reset()
for AR in it_AR:
    it_T = np.nditer(T_chamber, flags=['c_index'])
    for T in it_T:
        # Calculate Reynolds number at throat
        Re_throat[it_AR.index][it_T.index] = fp.get_Reynolds_from_velocity(T=T_throat[it_AR.index][it_T.index], p=p_throat[it_AR.index][it_T.index], \
             L_ref=D_hydraulic_throat[it_AR.index][it_T.index], u=u_throat[it_AR.index][it_T.index]) # [-] Reynolds number at throat

it_AR.reset()
for AR in it_AR:
    # Left side of plot
    axs[0][0].plot(T_chamber,