Feed System Calculations

Pressure Budget


In [6]:
from math import pi
g0 = 9.81 # Gravitational acceleration [m/s^2]

# Propellant properties
lox = {'M': 31.999 / 1000, # Molar mass [kg/mol]
       'T_e': 90.2, # Propellant temperature [K]
       'C_pl': 1.70 * 1000, # Liquid phase specific heat [J/kg*K]
       'C_pv': 0.91 * 1000, # Vapor phase secific heat (cosntant pressure) [J/kg*K]
       'h_v': 213.05 * 1000, # Heat of vaporization [J/kg]
       'T_v': 90.2, # Vaporization temperature [K]
       'R_p': R / (31.999 / 1000), # Specific gas constant 
       'p_t': (350+70) * 1.1 * 6894, # Propellant tank initial pressure [Pa]
       'a': 1.382 / 10, # van der Wall constant A [Pa*m^6/mol^2]
       'b': 0.03186 / 1000, # van der Wall constant B [m^3/mol]
       'rho': 71.38, # [lbf/ft^3]
       'mu': 0.000013999, # [lb/s*in]
       'mdot': 1.13, # [lbf/s]
       'name': 'lox'
      }

ipa = {'M': 60.1 / 1000, # Molar mass [kg/mol]
       'T_e': 293, # Propellant temperature [K]
       'C_pl': 7.25 * 1000 * (60.1 / 1000), # Liquid phase specific heat [J/kg*K]
       'C_pv': 1.75 * 1000, # Vapor phase secific heat (cosntant pressure) [J/kg*K]
       'h_v': 36800 * (60.1 / 1000), # Heat of vaporization [J/kg]
       'T_v': 355.8, # Vaporization temperature [K]
       'R_p': R / (60.1 / 1000), # Specific gas constant 
       'p_t': ((350 #Chamber pressure [psi]
             + 145 # Regen pressure drop [psi]
             + 70) # Injector pressure drop [psi]
             * 1.1 * 6894), # Propellant tank initial pressure [Pa]
       'a': 12.18 / 10, # van der Wall constant A [Pa*m^6/mol^2]
       'b': 0.08407 / 1000, # van der Wall constant B [m^3/mol]
       'rho': 55.249, # [lbf/ft^3]
       'mu': 0.000067197, #[lb/in*s]
       'mdot':  0.94, # [lbf/s]
       'name': 'ipa'
      }

In [11]:
#constants
P_ch = 350*6894.76 #chamber pressure [Pa]
P_t = {'lox': 750*6894.76,
       'ipa': 750*6894.76} #tank pressure
P_inj = {'lox': 0.15*P_ch,
         'ipa': 0.15*P_ch} #injector drop
P_cooling = {'lox': 0,
             'ipa': 140*6894.76} #regen cooling channel drop
D = {'lox': 0.5*0.0254,
     'ipa': 0.5*0.0254 } #tube diameter
l = {'lox':12*3*0.0254,
     'ipa': 12*3*0.0254} #tube_length
K_l = {'elbow_90_threaded': 1.5,
       'elbow_45_threaded': 0.4,
       'tee_line_theaded': 0.9,
       'tee_branch_threaded': 2.0}#minor loss coefficients

def Cv(): 
    return

def Q(prop):
    return prop['mdot']/prop['rho'] #volumetric flow rate

def U():
    return Q/(pi*D**2/4) #flow velocity

def Re(prop):
    return rho*U*D/mu #Reynolds number

def blasius():
    return 0.316/Re(prop)**0.25 #Basius friction factor

def major_losses(l, V):
    return blasius()*l*V**2/(D*2*g0) #Darcy-Weisbach equation 

def minor_losses():
    return K_l*U**2/(2*g0) #orifices, bends, suddend expansions & contractions

minors = [['ipa', K_l[0], K_l[0], K_l[0], K_l[1], K_l[2], K_l[3]],['lox', K_l[0], K_l[0], K_l[0], K_l[1], K_l[2], K_l[3]]]
valve_list = {'mov': 0.05,
          'mfv': 0.05}

for types in minors:
    P_minor += minor_losses(types)

for valves in valve_list:
    P_valves += Cv(valves)

P_total = sum(P_t) - P_inj[] - P_cooling[] - major_losses() - P_minor[] - P_valves

print('Pressure budget (LOX) = {0:.2f} kpa'.format(P_total['lox']))
print('Pressure budget (IPA) = {0:.2f} kpa'.format(P_total['ipa']))


  File "<ipython-input-11-b3f7fc7afa40>", line 49
    P_total = sum(P_t) - P_inj[] - P_cooling[] - major_losses() - P_minor[] - P_valves
                               ^
SyntaxError: invalid syntax

Pressurant Volume

Most of the following discussion follows from Huzel & Huang (1992) Ch 5. guidlines on gas-pressurized propellant feed systems. We need a starting place, particularly some assumptions and/pr constraints regarding:

  • Operating temperatures of feed-system components
  • Propellant properties at the expected extrema of operating conditions
  • Tank ullage volume
  • Trapped-propellant volumes at the end of expulsion
  • Operating tank pressures
  • Test campaign duration and engine test firing time

The following analysis will also make the following assumptions:

  • Ullage pressurization occurs slowly, e.g. the pressurant is initally in thermal equilibrium with the tank walls and propellant bulk
  • Tests are short enough that no heat transfer occurs between tank walls, pressurant and propellant (probably a bad assumption)
  • The N2 pressurant is insoluble in the isopropynol fuel
  • (For now) N2 pressurant is insoluble in LOX oxidizer

Finally these are the key design requirements:

  • Sufficient pressurant supply to maintain chamber pressure for a single 60 second burn (but at what pressure?)

Initial fill fraction of the propellant tanks will depend of test fire duration, thrust level, and total pressurization time and ambient air temperature among other things. The most conservative estimate is based on the case where an intially full tank (fill fraction is 100%) is completely emptied. If this is the case the pressurant mass required is determined from the equation of state and the isentropic gas equation. Given this ammount of pressurant gas the tank should become empty just as the pressurant supply tank pressure drops to the regulator set point pressure. Some important issues to consider in this analysis are propellant vaporization, and real gass effects.


In [5]:
# Constants
dia = 0.1 # Tank diameter [m]
A = pi * (dia / 2)**2 # Propellant surface area [m^2]
V = 2 # Propellant tank volume [m^3]
t = 60 # Maximum design burn time [s] 
y = 1.4 # Pressurant ratio of specific heats (assumed constant)
H = 2 # Heat transfer coefficient not really a constant / 
          # not sure how to calculate yet 
          #(the number is ok as 1st approx, actual value is a bit bs)
p_i = 3500 * 6894 # Pressurant tank initial pressure [Pa]
R = 8.3145 # Universal gas constant [Pa*m^3/K*mol]
M_g = 28.01/1000 # Nitrogen molar mass [kg/mol]
R_g = R / M_g
T_i = 293 # Nitrogen initial tank temperature [K]

# Compressibility factor using van der Wall polynomial expansion
def Z(fluid, tank, p, T):
    if fluid == 'ipa':
        a = ipa['a']
        b = ipa['b']
        M = ipa['M']
        #V_m = # Molar volume
    elif fluid == 'lox':
        a = lox['a']
        b = lox['b']
        M = lox['M']
        #V_m = # Molar volume
    elif fluid == 'N2':
        a = 0.1370
        b = 3.913E-5
        M = 28.01 / 1000
        #V_m = R * T / p # Molar volume
    else:
        print("There's an issue")
    if tank == 'prop':
        #V = # Whatever the propellant tank volume is [m^3]
        V_m = R * T / p # Molar volume
        return V_m / (V_m - b) - a / (R * T * V_m)
    elif tank == 'pres':
        V_m = R * T / p # Molar volume
        return V_m / (V_m - b) - a / (R * T * V_m)
    
# A much more realistic approximation
def pres_tank_volume(prop):
    #print(prop['name'])
    T_u = (prop['p_t'] / p_i)**((y - 1) / y) * T_i # Isentropic expansion of pressurant [K]
    Q = H * A * t * (T_u-prop['T_e']) # Heat transfer from pressurant gas to propellant vapor [J]
    m_v = (Q / (prop['C_pl'] * (prop['T_v'] - prop['T_e']) 
           + prop['h_v'] + prop['C_pv'] * (T_u - prop['T_v']))) # Mass of vaporized propellant [kg]
    V_v = ((m_v * Z(prop['name'], 'prop', prop['p_t'], T_u) 
           * prop['R_p'] * T_u) / prop['p_t']) # Partial volume of vaporized propellant [m^3]
    V_g = V - V_v # Pressurant volume at end of expulsion [m^3]
    m_g = ((prop['p_t'] * V_g * Z('N2','pres', prop['p_t'], T_u)) 
           / (R_g * T_u)) # Required pressurant mass [kg]
    V_gtank = (m_g * Z('N2', 'pres', p_i, T_i) 
               * R_g * T_i) / p_i #Requied pressurant volume (per propellant) [m^3]
    return V_gtank, Q, T_u
    #might need to solve simult T_u and (do I use N2 partial pressure at end of expulsion in T_u calc?)

sf = 2 # Safety factor
total_volume = (pres_tank_volume(lox)[0] + pres_tank_volume(ipa)[0]) * sf

print('Total required pressurant (for a single burn) = {0:.2f} m^3'.format(total_volume))
print('Final pressurant temperature (LOX) = {0:.2f} K'.format(pres_tank_volume(lox)[2]))
print('Final pressurant temperature (IPA) = {0:.2f} K'.format(pres_tank_volume(ipa)[2]))
print('Trapped LOX volume = {0:.2f} m^3'.format(pres_tank_volume(lox)[1]))
print('Trapped IPA volume = {0:.2f} m^3'.format(pres_tank_volume(ipa)[1]))


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-5-ead9cfcadbed> in <module>
     59 
     60 sf = 2 # Safety factor
---> 61 total_volume = (pres_tank_volume(lox)[0] + pres_tank_volume(ipa)[0]) * sf
     62 
     63 print('Total required pressurant (for a single burn) = {0:.2f} m^3'.format(total_volume))

NameError: name 'lox' is not defined

Valve Sizing

words words.

Valve Response

This is essential a summary of points made in NASA SP-8097 (Liquid Rocket Valve Assemblies).

Valve response time is defined as the total time elapsed from recipt of of an actuation signal to the time where the valve is either fully opened or fully closed. Various factors impact the valve timing:

  • Dynamic forces acting on the valve element and balancing chambers (e.g.)
  • Friction forces from bearings/shaft seals/lip seals, etc.
  • Displacement of fluid from balance chambers
  • Inertia of moving parts
  • Length or required actuator stroke
  • Spring rates of installed springs and bellows (where pertinant)

Some further considerations follow.

Pneumatics

Factors that affect response time of pneumatic actuators include flow capacity of the control valving, line sizes, initial total volume, and actuator swept volume. Another issue it the current thermodynamic state of the prussurant in the case were it is the same as main propellant pressurization gas (as in our design). Obviously near the end of a burn the regulated pressure supplied to the piston will be different than during the intial actuation due to the mostly-isentropic expansion of the pressurant gasses. Any other pressure transient that propagate up to the actuator taps will also affect their response time.

Friction


In [ ]: