Example #1
0
    def test_table(self):
        # Test if the table of the original paper can be reproduced Span2000
        # Page 1410 of Span2000
        fp = FluidProperties("nitrogen")

        pressure = 1e5  # 1 bar of pressure

        # T in, density out
        # Density taken in kg/mol from table, divided by molar mass
        in_out = ((300, 1.12328452104, 4), (330, 1.0209512786000001, 4),
                  (450, 0.74846415864, 4), (600, 0.5613060987599999,
                                            4), (1000, 0.33680607004, 4))

        for T, rho, places in in_out:
            res_rho = fp.get_density(T=T, p=pressure)
            self.assertAlmostEqual(res_rho, rho, places=places)

        # Same again but for different pressure
        pressure = 1e6  # 10 bars of pressure

        # T in, density out
        # Density taken in kg/mol from table, divided by molar mass
        in_out = ((300, 11.248812894, 4), (330, 10.2058710336, 3),
                  (450, 7.459989724000001, 3), (600, 5.591490608,
                                                3), (1000, 3.3576957128, 3))

        for T, rho, places in in_out:
            res_rho = fp.get_density(T=T, p=pressure)
            self.assertAlmostEqual(res_rho, rho, places=places)
Example #2
0
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]
        }
Example #3
0
def prepare_single_phase_gas(T_outlet, steps, p_ref, m_dot, fp: FluidProperties):

    T_sat = fp.get_saturation_temperature(p=p_ref) # [K] Saturation temperature
    assert (T_outlet > T_sat)
    assert (steps > 1)

    # Temperature and other intermediate variable in channel section i=0...n
    T, dT = np.linspace(start=T_sat, stop=T_outlet, num=steps, retstep=True) # [K] Temperature T_i
    # 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 first values must be replaced with the correct values for the saturated gas 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[0] = fp.get_saturation_enthalpy_gas(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[0] = fp.get_vapour_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[0] = fp.get_saturation_Prandtl_gas(p_sat=p_ref) # [-] Saturation Prandtl
    # Thermal conductivity 
    kappa = fp.get_thermal_conductivity(T=T, p=p_ref) # [W/(m*K)] Conductivity
    kappa[0] = fp.get_gas_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[0] = fp.get_gas_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]
        }
Example #4
0
def h_conv_from_Stanton(Stanton, u, T_ref, p_ref, fp: FluidProperties):
    """Return heat transfer coefficient dependent on Stanton number and thermodynamic state\
        Temperature and pressure are passed instead of T and p, as these abstract away constant computations of cp and rho\
            and it is easier to pass around the same state variables time and time again

            WARNING: REFERENCE THERMODYNAMIC STATE (T_ref, p_ref) MUST BE EQUAL TO THOSE WITH WHICH NUSSELT NUMBER WAS DETERMINED

    Args:
        Stanton (-): Stanton number: dimensionless flow characteristic
        u (m/s): flow velocity
        T_ref (K): Temperature
        p_ref (Pa): Pressure
        fp (FluidProperties): object to use to obtain properties of fluid

    Returns:
        h_conv (W/(m^2*K)): convective heat transfer coefficient based on Stanton number, flow velocity and thermodynamic state
    """
    cp = fp.get_cp(T=T_ref, p=p_ref) # [J/kg] Specific heat capacity under constant pressure
    rho = fp.get_density(T=T_ref,p=p_ref) # [kg/m^3] Fluid density

    return Stanton*rho*u*cp # [W/(m^2*K)] h_conv: Convective heat transfer coefficient
Example #5
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
Example #6
0
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
    }
Example #7
0
    td['propellant'])  # Object to access fluid properties from
m_dot = td['m_dot'] / td['channel_amount']  # [kg/s] Mass flow
h_channel = td['h_channel']  # [m] Channel height/depth
w_channel = td['w_channel']  # [m] Channel width
L_channel = td['L_channel']  # [m] Channel length
T_outlet = td['T_chamber']  # [K] Outlet of channel
p_inlet = td['p_inlet']  # [Pa]
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))
Example #8
0
from thermo.prop import FluidProperties
import thermo.convection as conv
import basic.chamber

# Object to retrievere propellant properties from
fp = FluidProperties("water")

# Reference state for calculations
p = 5e5  # [Pa]
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]
Example #9
0
from thermo.prop import FluidProperties
from basic.chamber import ideal_enthalpy_change, required_power

fp = FluidProperties("water")

T_in = 300  # [K]
T_out = 450  # [K]
p_in = 5e5  # [Pa]

m_dot = 1.6667e-6  # [kg/s]

delta_h = ideal_enthalpy_change(T_inlet=T_in,
                                p_inlet=p_in,
                                T_outlet=T_out,
                                p_outlet=p_in,
                                fp=fp)  # [J/kg]
Q_dot = required_power(m_dot=m_dot, delta_h=delta_h)

rho_out = fp.get_density(T=T_out, p=p_in)

print("Density out: {:3.3f} kg/m^3".format(rho_out))
print("Required power: {}".format(Q_dot))
Example #10
0
# Which channel width gives the least power usage?
w_channel_min = 0.5e-5  # [m] Minimum channel width
w_channel_max = 5e-5  # [m] Maximum channel width
w_channel = np.linspace(
    start=w_channel_min,
    stop=w_channel_max)  # [m] Range of channel widths to evaluate

# Calculate some basic channel geometry
A_channel = w_channel * h_channel  # [m^2] Cross-sectional area of channel
Dh_channel = hydraulic_diameter_rectangular(
    w_channel=w_channel,
    h_channel=h_channel)  # [m] Hydraulic diameter of rectangular channels

# Calculate some basic flow parameter at the inlet
rho_inlet = fp.get_density(T=T_inlet, p=p_inlet)  # [kg/m^3]
u_inlet = velocity_from_mass_flow(
    m_dot=m_dot, rho=rho_inlet,
    A=A_channel)  # [m/s] Flow velocity inside channel

# Storing results
Re_bulk = np.zeros(
    (T_wall.shape[0], w_channel.shape[0]))  # [-] Bulk Reynolds number
Pr_bulk = np.zeros_like(Re_bulk)  # [-] Bulk Prandtl number
u_bulk = np.zeros_like(Re_bulk)  # [-] Velocity under bulk condition
Nusselt = np.zeros_like(Re_bulk)  # [-] Nusselt number
Stanton = np.zeros_like(Re_bulk)  # [-] Stanton number
h_conv = np.zeros_like(
    Re_bulk)  # [W/(m^2*K)] Convective heat transfer coefficient
A_heater = np.zeros_like(
    Re_bulk
Example #11
0
    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)
print(cp)

## Print information for frictional pressure drop guesses
print(" --- FRICTIONAL PRESSURE DROP ESTIMATION ---")
f = 0.05  # [-] Friction factor (emperical based, 0.05 is just a guess)
rho_outlet = fp.get_density(T=T_chamber, p=p_inlet)  # [kg/m^3]
u_outlet = velocity_from_mass_flow(A=A_channel, m_dot=m_dot,
                                   rho=rho_outlet)  # [m/s]
delta_p = f * (L_channel /
               D_hydraulic) * 0.5 * rho_outlet * u_outlet**2  # [Pa]
print("L/D: {} ".format(L_channel / D_hydraulic))
print("rho_outlet: {}".format(rho_outlet))
print("u_outlet: {}".format(u_outlet))
print("delta_p: {} bar".format(delta_p * 1e-5))
print("Relative pressure drop: {}".format(delta_p / p_inlet))