# Simple Blowdown System Performance Estimate

June 22, 2020

Here we'll briefly walk through a simple performance estimate for a blowdown propulsion system. This is useful for assessing the orbital maneuver capability of a proposed design and determining the end-of-life (EOL) pressure.

In this case we'll assume the system is using LMP-103S and the associated monopropellant thrusters for $\Delta V$ burns.

## Model Definition

We start with importing a few packages and declaring the characteristics of the propellant & pressurant as:

import numpy as np
import matplotlib.pyplot as plt

import itertools
from math import exp, sqrt, pi, acos, sin, cos, log

class Propellant(object):
def density(T):
# Input: T = temperature in deg C
# Output: density in kg/m3
return 4E-15 * T ** 2 - 0.8436 * T + 1259.1

def vapor_press(T):
# Input: T = temperature in deg C
# Output: vapor pressure in bar
return 0.000002 * T ** 3 - 0.00003 * T ** 2 + 0.0032 * T + 0.0418

def helium_z(p):
# Input: p = pressure in bar
# Output: non dimensional compressibility factor
return -5E-17 * (p * 100) ** 3 + 3E-12 * (p * 100) ** 2 + 5E-6 * (p * 100) + 1


Now we'll write the performance models for the thrusters our system is using, here we have the 1N HPGP thruster:

class ECAPS_Model(object):
def thrust(p):
# Input: p = pressure in bar
# Output: thrust in N (from ATP family data)
return -0.000214 * p ** 2 + 0.052037 * p - 0.019460

def isp(p):
# Input: p = pressure in bar
# Output: isp in seconds (steady state)
return (243.68 * np.log(p) + 1594 - 0.1 * p ** 2.15) / 9.806


With the propellant and the performance models finished, we need to write a simple function that takes a given system definition and calculates the blowdown performance at discrete propellant mass steps:

def Delta_V(tank_vol, m_dry, m_prop, temp, initial_press):
# Inputs: tank volume in liters, spacecraft dry mass in kg, propellant mass in kg,
#         temperature in C, and intiitaly system pressure in bar
# Output: Delta-V profile in m/s, propellant mass profile in kg,
#         system pressure profile in bar

def ullage(tank_vol, m_prop, temp):
# Inputs: take volume in liters, propellant mass, and propellant temperature in C
# Outputs: ullage volume in m3
return (tank_vol * 0.001) - (m_prop / Propellant.density(temp))

# calculate helium mass in the system
m_helium = ((initial_press * 100 - Propellant.vapor_press(temp) * 100) \
* ullage(tank_vol, m_prop, temp)) / (Propellant.helium_z(initial_press) \
* 2.0772 * (temp + 273.15))

# define stop condition, we'll assume 98% expulsion
residual = m_prop - (m_prop * 0.98)

# total dry mass of the spacecraft as residual could be large depending on design
m_dry = m_dry + m_helium + residual

# define results storage
DV_total = 
m_prop_list = [m_prop]
pressure_profile = [initial_press]

# calculate delta-V with the rocket equation through the blowdown
while m_prop >= residual:

# step through propellant mass
step_start_mass = m_dry + m_prop
m_prop -= 0.1
step_end_mass = m_dry + m_prop

# calculate new system pressure after mass is consumed
press = ((m_helium * Propellant.helium_z(initial_press / 2) * \
2.0772 * (temp + 273.15)) / ullage(tank_vol, m_prop, temp)) / 100

# calc the delta-V imparted by this mass 'chunk' at this system state
DV_step = ECAPS_Model.isp(press) * 9.806 * np.log(step_start_mass / step_end_mass)

# store results
m_prop_list.append(m_prop)
DV_total.append(DV_total[-1] + DV_step)
pressure_profile.append(press)

return DV_total, m_prop_list, pressure_profile


The above function is a good estimate of the blowdown system's performance given an initial state.

## System Design Evaluation

With our model completed, we can evaluate the performance of a given system design by taking the following as inputs:

ParameterValueUnit
Spacecraft Dry Mass100kg
Propellant Mass10kg
Total Tank Volume11.5liters
Temperature20C
Initial Pressure18.5bar

Now we call our Delta_V function defined about to step through the blowdown curve as mass is expelled from the system:

DV_total, m_prop_list, pressure_profile = Delta_V(total_tank_vol, m_dry, m_prop, \
temp, initial_press)


And we plot the results with:

# define the axes
fig, ax1 = plt.subplots(figsize = (16, 8))
ax2 = ax1.twinx()

# plot the data
ax1.plot(m_prop_list, pressure_profile, color = 'blue')
ax2.plot(m_prop_list, DV_total, ls = '--', color = next(colors), label = 'Thruster Mode: SS')

# dress up the axes
ax1.set_ylabel('Tank Pressure [bar]', fontsize = 14)
ax1.set_xlabel('Propellant Remaining [kg]', fontsize = 14)
ax1.set_title('Estimated System Performance', fontsize = 14)
ax1.grid(True)
ax1.set_xlim(xmin = 0)
ax1.set_ylim(ymin = 4)

ax2.set_ylabel('Cumulative Delta V [m/s] (dashed line)', fontsize = 14)
ax2.set_ylim(ymin = 0)
ax2.invert_xaxis()
ax2.legend(loc = 9, prop = {'size': 14})

ax1.tick_params(axis = 'both', which = 'major', labelsize = 14)
ax2.tick_params(axis = 'y', which = 'major', labelsize = 14)


Which displays a plot of the pressure profile and cumulative $\Delta V$ similar to: