Skip to content

models.feed_systems

Feed system models for liquid rocket engines. Defines how propellant is delivered from tanks to the combustion chamber.

The base FeedSystem class abstracts mass flow rate and tank pressure calculations. StackedTankPressureFedFeedSystem implements a pressure-fed configuration with oxidizer and fuel lines, accounting for line losses and piston pressure drops.

See tanks for the tank thermodynamic model.

machwave.models.feed_systems

FeedSystem

Bases: ABC

Abstract base class for a bipropellant feed system in a liquid rocket engine (LRE).

This class is responsible for determining oxidizer and fuel mass flows as a function of tank/pressurant states, pumps (if any), and current chamber conditions. Subclasses must implement the abstract methods to specify the actual flow calculations.

Source code in machwave/models/feed_systems/base.py
class FeedSystem(ABC):
    """
    Abstract base class for a bipropellant feed system in a liquid rocket engine (LRE).

    This class is responsible for determining oxidizer and fuel mass flows as a function of tank/pressurant states,
    pumps (if any), and current chamber conditions. Subclasses must implement the abstract methods to specify the
    actual flow calculations.
    """

    def __init__(self, fuel_tank: Tank, oxidizer_tank: Tank):
        """Initialize the FeedSystem with associated tank objects.

        Args:
            fuel_tank: Instance representing the fuel tank.
            oxidizer_tank: Instance representing the oxidizer tank.
        """
        self.fuel_tank = fuel_tank
        self.oxidizer_tank = oxidizer_tank

    def get_propellant_mass(self) -> float:
        """Compute and return the initial propellant mass in the system [kg]."""
        return self.fuel_tank.fluid_mass + self.oxidizer_tank.fluid_mass

    @abstractmethod
    def get_mass_flow_ox(self, *args, **kwargs) -> float:
        """Compute and return the current oxidizer mass flow rate [kg/s]."""
        pass

    @abstractmethod
    def get_mass_flow_fuel(self, *args, **kwargs) -> float:
        """Compute and return the current fuel mass flow rate [kg/s]."""
        pass

    @abstractmethod
    def get_oxidizer_tank_pressure(self) -> float:
        """Compute and return the current oxidizer tank pressure [Pa]."""
        pass

    @abstractmethod
    def get_fuel_tank_pressure(self) -> float:
        """Compute and return the current fuel tank pressure [Pa]."""
        pass

__init__(fuel_tank, oxidizer_tank)

Initialize the FeedSystem with associated tank objects.

Parameters:

Name Type Description Default
fuel_tank Tank

Instance representing the fuel tank.

required
oxidizer_tank Tank

Instance representing the oxidizer tank.

required
Source code in machwave/models/feed_systems/base.py
def __init__(self, fuel_tank: Tank, oxidizer_tank: Tank):
    """Initialize the FeedSystem with associated tank objects.

    Args:
        fuel_tank: Instance representing the fuel tank.
        oxidizer_tank: Instance representing the oxidizer tank.
    """
    self.fuel_tank = fuel_tank
    self.oxidizer_tank = oxidizer_tank

get_fuel_tank_pressure() abstractmethod

Compute and return the current fuel tank pressure [Pa].

Source code in machwave/models/feed_systems/base.py
@abstractmethod
def get_fuel_tank_pressure(self) -> float:
    """Compute and return the current fuel tank pressure [Pa]."""
    pass

get_mass_flow_fuel(*args, **kwargs) abstractmethod

Compute and return the current fuel mass flow rate [kg/s].

Source code in machwave/models/feed_systems/base.py
@abstractmethod
def get_mass_flow_fuel(self, *args, **kwargs) -> float:
    """Compute and return the current fuel mass flow rate [kg/s]."""
    pass

get_mass_flow_ox(*args, **kwargs) abstractmethod

Compute and return the current oxidizer mass flow rate [kg/s].

Source code in machwave/models/feed_systems/base.py
@abstractmethod
def get_mass_flow_ox(self, *args, **kwargs) -> float:
    """Compute and return the current oxidizer mass flow rate [kg/s]."""
    pass

get_oxidizer_tank_pressure() abstractmethod

Compute and return the current oxidizer tank pressure [Pa].

Source code in machwave/models/feed_systems/base.py
@abstractmethod
def get_oxidizer_tank_pressure(self) -> float:
    """Compute and return the current oxidizer tank pressure [Pa]."""
    pass

get_propellant_mass()

Compute and return the initial propellant mass in the system [kg].

Source code in machwave/models/feed_systems/base.py
def get_propellant_mass(self) -> float:
    """Compute and return the initial propellant mass in the system [kg]."""
    return self.fuel_tank.fluid_mass + self.oxidizer_tank.fluid_mass

StackedTankPressureFedFeedSystem

Bases: FeedSystem

Represents a bipropellant liquid rocket engine feed system with stacked tanks.

A stacked tank system is a type of pressure-fed system where the oxidizer and fuel tanks are arranged in a vertical stack. The tanks are separated by a piston and the fuel is pressurized by the oxidizer tank.

Source code in machwave/models/feed_systems/pressure_fed.py
class StackedTankPressureFedFeedSystem(FeedSystem):
    """
    Represents a bipropellant liquid rocket engine feed system with stacked tanks.

    A stacked tank system is a type of pressure-fed system where the oxidizer and fuel tanks are arranged in a
    vertical stack. The tanks are separated by a piston and the fuel is pressurized by the oxidizer tank.
    """

    def __init__(
        self,
        oxidizer_line_diameter: float,
        oxidizer_line_length: float,
        fuel_line_diameter: float,
        fuel_line_length: float,
        fuel_tank: Tank,
        oxidizer_tank: Tank,
        piston_loss: float = 0.0,
    ):
        """
        Initialize the StackedTankPressureFedFeedSystem with feedline dimensions, tank objects, and fluid densities.

        Args:
            oxidizer_line_diameter: Diameter of the oxidizer feedline [m].
            oxidizer_line_length: Length of the oxidizer feedline [m].
            fuel_line_diameter: Diameter of the fuel feedline [m].
            fuel_line_length: Length of the fuel feedline [m].
            fuel_tank: An instance representing the fuel tank.
            oxidizer_tank: An instance representing the oxidizer tank.
            piston_loss: Pressure loss across the piston [Pa]. Default is 0.0.
        """
        super().__init__(fuel_tank, oxidizer_tank)

        self.oxidizer_line_diameter = oxidizer_line_diameter
        self.oxidizer_line_length = oxidizer_line_length
        self.fuel_line_diameter = fuel_line_diameter
        self.fuel_line_length = fuel_line_length

        self.piston_loss = piston_loss

        # Tank objects
        self.fuel_tank = fuel_tank
        self.oxidizer_tank = oxidizer_tank

    def get_mass_flow_ox(
        self,
        chamber_pressure: float,
        discharge_coefficient: float,
        injector_area: float,
    ) -> float:
        """
        Compute the current oxidizer mass flow rate via get_mass_flow_orifice().

        Args:
            chamber_pressure: Chamber pressure [Pa].
            discharge_coefficient: Discharge coefficient for the injector (dimensionless).
            injector_area: Effective flow area for the oxidizer injector [m^2].

        Returns:
            Oxidizer mass flow rate [kg/s].
        """
        p_up = self.get_oxidizer_tank_pressure()
        p_down = chamber_pressure
        oxidizer_density = self.oxidizer_tank.get_density()

        return get_mass_flow_orifice(
            discharge_coefficient=discharge_coefficient,
            area=injector_area,
            density=oxidizer_density,
            pressure_upstream=p_up,
            pressure_downstream=p_down,
        )

    def get_mass_flow_fuel(
        self,
        chamber_pressure: float,
        discharge_coefficient: float,
        injector_area: float,
    ) -> float:
        """
        Compute the current fuel mass flow rate via get_mass_flow_orifice().
        The pressure upstream will be the same as the oxidizer tank pressure, since this is a model for a stacked tank.

        Args:
            chamber_pressure: Chamber pressure [Pa].
            discharge_coefficient: Discharge coefficient for the injector (dimensionless).
            injector_area: Effective flow area for the fuel injector [m^2].

        Returns:
            Fuel mass flow rate [kg/s].
        """
        p_up = self.get_oxidizer_tank_pressure() - self.piston_loss
        p_down = chamber_pressure
        fuel_density = self.fuel_tank.get_density()

        return get_mass_flow_orifice(
            discharge_coefficient=discharge_coefficient,
            area=injector_area,
            density=fuel_density,
            pressure_upstream=p_up,
            pressure_downstream=p_down,
        )

    def get_oxidizer_tank_pressure(self) -> float:
        """
        Returns the tank pressure [Pa].
        """
        return self.oxidizer_tank.get_pressure()

    def get_fuel_tank_pressure(self) -> float:
        """
        Returns the fuel-side upstream pressure [Pa].

        In a stacked-tank system the fuel is pressurized by the oxidizer
        through the piston, so the fuel-side pressure is the oxidizer tank
        pressure minus the piston pressure loss.
        """
        return self.get_oxidizer_tank_pressure() - self.piston_loss

__init__(oxidizer_line_diameter, oxidizer_line_length, fuel_line_diameter, fuel_line_length, fuel_tank, oxidizer_tank, piston_loss=0.0)

Initialize the StackedTankPressureFedFeedSystem with feedline dimensions, tank objects, and fluid densities.

Parameters:

Name Type Description Default
oxidizer_line_diameter float

Diameter of the oxidizer feedline [m].

required
oxidizer_line_length float

Length of the oxidizer feedline [m].

required
fuel_line_diameter float

Diameter of the fuel feedline [m].

required
fuel_line_length float

Length of the fuel feedline [m].

required
fuel_tank Tank

An instance representing the fuel tank.

required
oxidizer_tank Tank

An instance representing the oxidizer tank.

required
piston_loss float

Pressure loss across the piston [Pa]. Default is 0.0.

0.0
Source code in machwave/models/feed_systems/pressure_fed.py
def __init__(
    self,
    oxidizer_line_diameter: float,
    oxidizer_line_length: float,
    fuel_line_diameter: float,
    fuel_line_length: float,
    fuel_tank: Tank,
    oxidizer_tank: Tank,
    piston_loss: float = 0.0,
):
    """
    Initialize the StackedTankPressureFedFeedSystem with feedline dimensions, tank objects, and fluid densities.

    Args:
        oxidizer_line_diameter: Diameter of the oxidizer feedline [m].
        oxidizer_line_length: Length of the oxidizer feedline [m].
        fuel_line_diameter: Diameter of the fuel feedline [m].
        fuel_line_length: Length of the fuel feedline [m].
        fuel_tank: An instance representing the fuel tank.
        oxidizer_tank: An instance representing the oxidizer tank.
        piston_loss: Pressure loss across the piston [Pa]. Default is 0.0.
    """
    super().__init__(fuel_tank, oxidizer_tank)

    self.oxidizer_line_diameter = oxidizer_line_diameter
    self.oxidizer_line_length = oxidizer_line_length
    self.fuel_line_diameter = fuel_line_diameter
    self.fuel_line_length = fuel_line_length

    self.piston_loss = piston_loss

    # Tank objects
    self.fuel_tank = fuel_tank
    self.oxidizer_tank = oxidizer_tank

get_fuel_tank_pressure()

Returns the fuel-side upstream pressure [Pa].

In a stacked-tank system the fuel is pressurized by the oxidizer through the piston, so the fuel-side pressure is the oxidizer tank pressure minus the piston pressure loss.

Source code in machwave/models/feed_systems/pressure_fed.py
def get_fuel_tank_pressure(self) -> float:
    """
    Returns the fuel-side upstream pressure [Pa].

    In a stacked-tank system the fuel is pressurized by the oxidizer
    through the piston, so the fuel-side pressure is the oxidizer tank
    pressure minus the piston pressure loss.
    """
    return self.get_oxidizer_tank_pressure() - self.piston_loss

get_mass_flow_fuel(chamber_pressure, discharge_coefficient, injector_area)

Compute the current fuel mass flow rate via get_mass_flow_orifice(). The pressure upstream will be the same as the oxidizer tank pressure, since this is a model for a stacked tank.

Parameters:

Name Type Description Default
chamber_pressure float

Chamber pressure [Pa].

required
discharge_coefficient float

Discharge coefficient for the injector (dimensionless).

required
injector_area float

Effective flow area for the fuel injector [m^2].

required

Returns:

Type Description
float

Fuel mass flow rate [kg/s].

Source code in machwave/models/feed_systems/pressure_fed.py
def get_mass_flow_fuel(
    self,
    chamber_pressure: float,
    discharge_coefficient: float,
    injector_area: float,
) -> float:
    """
    Compute the current fuel mass flow rate via get_mass_flow_orifice().
    The pressure upstream will be the same as the oxidizer tank pressure, since this is a model for a stacked tank.

    Args:
        chamber_pressure: Chamber pressure [Pa].
        discharge_coefficient: Discharge coefficient for the injector (dimensionless).
        injector_area: Effective flow area for the fuel injector [m^2].

    Returns:
        Fuel mass flow rate [kg/s].
    """
    p_up = self.get_oxidizer_tank_pressure() - self.piston_loss
    p_down = chamber_pressure
    fuel_density = self.fuel_tank.get_density()

    return get_mass_flow_orifice(
        discharge_coefficient=discharge_coefficient,
        area=injector_area,
        density=fuel_density,
        pressure_upstream=p_up,
        pressure_downstream=p_down,
    )

get_mass_flow_ox(chamber_pressure, discharge_coefficient, injector_area)

Compute the current oxidizer mass flow rate via get_mass_flow_orifice().

Parameters:

Name Type Description Default
chamber_pressure float

Chamber pressure [Pa].

required
discharge_coefficient float

Discharge coefficient for the injector (dimensionless).

required
injector_area float

Effective flow area for the oxidizer injector [m^2].

required

Returns:

Type Description
float

Oxidizer mass flow rate [kg/s].

Source code in machwave/models/feed_systems/pressure_fed.py
def get_mass_flow_ox(
    self,
    chamber_pressure: float,
    discharge_coefficient: float,
    injector_area: float,
) -> float:
    """
    Compute the current oxidizer mass flow rate via get_mass_flow_orifice().

    Args:
        chamber_pressure: Chamber pressure [Pa].
        discharge_coefficient: Discharge coefficient for the injector (dimensionless).
        injector_area: Effective flow area for the oxidizer injector [m^2].

    Returns:
        Oxidizer mass flow rate [kg/s].
    """
    p_up = self.get_oxidizer_tank_pressure()
    p_down = chamber_pressure
    oxidizer_density = self.oxidizer_tank.get_density()

    return get_mass_flow_orifice(
        discharge_coefficient=discharge_coefficient,
        area=injector_area,
        density=oxidizer_density,
        pressure_upstream=p_up,
        pressure_downstream=p_down,
    )

get_oxidizer_tank_pressure()

Returns the tank pressure [Pa].

Source code in machwave/models/feed_systems/pressure_fed.py
def get_oxidizer_tank_pressure(self) -> float:
    """
    Returns the tank pressure [Pa].
    """
    return self.oxidizer_tank.get_pressure()