Skip to content

models.propulsion.feed_systems

machwave.models.propulsion.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/propulsion/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/propulsion/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/propulsion/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/propulsion/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/propulsion/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/propulsion/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/propulsion/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/propulsion/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 tank pressure [Pa].
        """
        return self.oxidizer_tank.get_pressure()

__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/propulsion/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 tank pressure [Pa].

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

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/propulsion/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/propulsion/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/propulsion/feed_systems/pressure_fed.py
def get_oxidizer_tank_pressure(self) -> float:
    """
    Returns the tank pressure [Pa].
    """
    return self.oxidizer_tank.get_pressure()