Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MNT: EmptyMotor class inherits from Motor(ABC) #779

Merged
merged 4 commits into from
Mar 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ Attention: The newest changes should be on top -->

### Added

- DOC: ASTRA Flight Example [#770](https://github.com/RocketPy-Team/RocketPy/pull/770))
- DOC: ASTRA Flight Example [#770](https://github.com/RocketPy-Team/RocketPy/pull/770)

### Changed

-
- MNT: EmptyMotor class inherits from Motor(ABC) [#779](https://github.com/RocketPy-Team/RocketPy/pull/779)

### Fixed

Expand Down
3 changes: 2 additions & 1 deletion rocketpy/motors/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from .empty_motor import EmptyMotor
from .fluid import Fluid
from .hybrid_motor import HybridMotor
from .liquid_motor import LiquidMotor
from .motor import EmptyMotor, GenericMotor, Motor
from .motor import GenericMotor, Motor
from .solid_motor import SolidMotor
from .tank import (
LevelBasedTank,
Expand Down
78 changes: 78 additions & 0 deletions rocketpy/motors/empty_motor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
from rocketpy.mathutils import Function, funcify_method
from rocketpy.motors.motor import Motor


class EmptyMotor(Motor):
"""Class that represents an empty motor with no mass and no thrust."""

def __init__(self):
"""Initializes an empty motor with no mass and no thrust."""

super().__init__(
thrust_source=0,
dry_inertia=(0, 0, 0),
nozzle_radius=0,
center_of_dry_mass_position=0,
dry_mass=0,
nozzle_position=0,
burn_time=1,
reshape_thrust_curve=False,
interpolation_method="linear",
coordinate_system_orientation="nozzle_to_combustion_chamber",
)

# Mass properties
self.propellant_mass = Function(0, "Time (s)", "Propellant Mass (kg)")
self.total_mass = Function(0, "Time (s)", "Total Mass (kg)")
self.total_mass_flow_rate = Function(
0, "Time (s)", "Mass Depletion Rate (kg/s)"
)
self.center_of_mass = Function(0, "Time (s)", "Center of Mass (kg)")

# Inertia properties
self.I_11 = Function(0)
self.I_22 = Function(0)
self.I_33 = Function(0)
self.I_12 = Function(0)
self.I_13 = Function(0)
self.I_23 = Function(0)

@funcify_method("Time (s)", "Center of Propellant Mass (kg)", "linear", "zero")
def center_of_propellant_mass(self):
return 0

@funcify_method("Time (s)", "Exhaust Velocity (m/s)", "linear", "zero")
def exhaust_velocity(self):
return 0

@property
def propellant_initial_mass(self):
return 0

@funcify_method("Time (s)", "Propellant I_11 (kg m²)", "linear", "zero")
def propellant_I_11(self):
return 0

@funcify_method("Time (s)", "Propellant I_12 (kg m²)", "linear", "zero")
def propellant_I_12(self):
return 0

@funcify_method("Time (s)", "Propellant I_13 (kg m²)", "linear", "zero")
def propellant_I_13(self):
return 0

@funcify_method("Time (s)", "Propellant I_22 (kg m²)", "linear", "zero")
def propellant_I_22(self):
return 0

@funcify_method("Time (s)", "Propellant I_23 (kg m²)", "linear", "zero")
def propellant_I_23(self):
return 0

@funcify_method("Time (s)", "Propellant I_33 (kg m²)", "linear", "zero")
def propellant_I_33(self):
return 0

@property
def structural_mass_ratio(self):
return 0
54 changes: 1 addition & 53 deletions rocketpy/motors/motor.py
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,7 @@ def all_info(self):
self.plots.all()


# TODO: move this class to a separate file, needs a breaking change warning
class GenericMotor(Motor):
"""Class that represents a simple motor defined mainly by its thrust curve.
There is no distinction between the propellant types (e.g. Solid, Liquid).
Expand Down Expand Up @@ -1601,56 +1602,3 @@ def from_dict(cls, data):
nozzle_position=data["nozzle_position"],
interpolation_method=data["interpolate"],
)


class EmptyMotor:
"""Class that represents an empty motor with no mass and no thrust."""

# TODO: This is a temporary solution. It should be replaced by a class that
# inherits from the abstract Motor class. Currently cannot be done easily.
# pylint: disable=too-many-statements
def __init__(self):
"""Initializes an empty motor with no mass and no thrust.

Notes
-----
This class is a temporary solution to the problem of having a motor
with no mass and no thrust. It should be replaced by a class that
inherits from the abstract Motor class. Currently cannot be done easily.
"""
self._csys = 1
self.dry_mass = 0
self.nozzle_radius = 0
self.thrust = Function(0, "Time (s)", "Thrust (N)")
self.propellant_mass = Function(0, "Time (s)", "Propellant Mass (kg)")
self.propellant_initial_mass = 0
self.total_mass = Function(0, "Time (s)", "Total Mass (kg)")
self.total_mass_flow_rate = Function(
0, "Time (s)", "Mass Depletion Rate (kg/s)"
)
self.burn_out_time = 1
self.nozzle_position = 0
self.nozzle_radius = 0
self.center_of_dry_mass_position = 0
self.center_of_propellant_mass = Function(
0, "Time (s)", "Center of Propellant Mass (kg)"
)
self.center_of_mass = Function(0, "Time (s)", "Center of Mass (kg)")
self.dry_I_11 = 0
self.dry_I_22 = 0
self.dry_I_33 = 0
self.dry_I_12 = 0
self.dry_I_13 = 0
self.dry_I_23 = 0
self.propellant_I_11 = Function(0, "Time (s)", "Propellant I_11 (kg m²)")
self.propellant_I_22 = Function(0, "Time (s)", "Propellant I_22 (kg m²)")
self.propellant_I_33 = Function(0, "Time (s)", "Propellant I_33 (kg m²)")
self.propellant_I_12 = Function(0, "Time (s)", "Propellant I_12 (kg m²)")
self.propellant_I_13 = Function(0, "Time (s)", "Propellant I_13 (kg m²)")
self.propellant_I_23 = Function(0, "Time (s)", "Propellant I_23 (kg m²)")
self.I_11 = Function(0)
self.I_22 = Function(0)
self.I_33 = Function(0)
self.I_12 = Function(0)
self.I_13 = Function(0)
self.I_23 = Function(0)
2 changes: 1 addition & 1 deletion rocketpy/rocket/rocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from rocketpy.control.controller import _Controller
from rocketpy.mathutils.function import Function
from rocketpy.mathutils.vector_matrix import Matrix, Vector
from rocketpy.motors.motor import EmptyMotor
from rocketpy.motors.empty_motor import EmptyMotor
from rocketpy.plots.rocket_plots import _RocketPlots
from rocketpy.prints.rocket_prints import _RocketPrints
from rocketpy.rocket.aero_surface import (
Expand Down
3 changes: 2 additions & 1 deletion rocketpy/stochastic/stochastic_rocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
from random import choice

from rocketpy.mathutils.vector_matrix import Vector
from rocketpy.motors.motor import EmptyMotor, GenericMotor, Motor
from rocketpy.motors.empty_motor import EmptyMotor
from rocketpy.motors.motor import GenericMotor, Motor
from rocketpy.motors.solid_motor import SolidMotor
from rocketpy.rocket.aero_surface import (
EllipticalFins,
Expand Down
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"tests.fixtures.motor.liquid_fixtures",
"tests.fixtures.motor.hybrid_fixtures",
"tests.fixtures.motor.solid_motor_fixtures",
"tests.fixtures.motor.empty_motor_fixtures",
"tests.fixtures.motor.tanks_fixtures",
"tests.fixtures.motor.tank_geometry_fixtures",
"tests.fixtures.motor.generic_motor_fixtures",
Expand Down
14 changes: 14 additions & 0 deletions tests/fixtures/motor/empty_motor_fixtures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import pytest

from rocketpy.motors.empty_motor import EmptyMotor


@pytest.fixture
def empty_motor():
"""An example of an empty motor with zero thrust and mass.

Returns
-------
rocketpy.EmptyMotor
"""
return EmptyMotor()
2 changes: 1 addition & 1 deletion tests/fixtures/motor/solid_motor_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def dimensionless_cesaroni_m1670(kg, m): # old name: dimensionless_motor
@pytest.fixture
def dummy_empty_motor():
# Create a motor with ZERO thrust and ZERO mass to keep the rocket's speed constant
# TODO: why don t we use these same values to create EmptyMotor class?
# TODO: Maybe we should simple use the new `EmptyMotor` class?
return SolidMotor(
thrust_source=1e-300,
burn_time=1e-10,
Expand Down
16 changes: 16 additions & 0 deletions tests/integration/test_empty_motor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from unittest.mock import patch


@patch("matplotlib.pyplot.show")
def test_empty_motor_info(mock_show, empty_motor): # pylint: disable=unused-argument
"""Tests the LiquidMotor.all_info() method.

Parameters
----------
mock_show : mock
Mock of the matplotlib.pyplot.show function.
empty_motor : rocketpy.EmptyMotor
The EmptyMotor object to be used in the tests.
"""
assert empty_motor.info() is None
assert empty_motor.all_info() is None
3 changes: 2 additions & 1 deletion tests/unit/test_rocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

from rocketpy import Function, NoseCone, Rocket, SolidMotor
from rocketpy.mathutils.vector_matrix import Vector
from rocketpy.motors.motor import EmptyMotor, Motor
from rocketpy.motors.empty_motor import EmptyMotor
from rocketpy.motors.motor import Motor


@patch("matplotlib.pyplot.show")
Expand Down