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

DOCs: improve mass and inertia docs #445

Merged
merged 15 commits into from
Nov 12, 2023
Merged
Show file tree
Hide file tree
Changes from 13 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
48 changes: 36 additions & 12 deletions rocketpy/motors/hybrid_motor.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,20 @@ class HybridMotor(Motor):
HybridMotor.liquid : LiquidMotor
Liquid motor object that composes the hybrid motor.
HybridMotor.dry_mass : float
The total mass of the motor structure, including chambers
and tanks, when it is empty and does not contain any propellant.
The total mass of the motor structure, including chambers, bulkheads,
screws, tanks, and others. This should be taken when the motor is
empty and does not contain any propellant. You should not double
count a component that is already accounted for in the rocket class.
Gui-FernandesBR marked this conversation as resolved.
Show resolved Hide resolved
HybridMotor.propellant_initial_mass : float
Total propellant initial mass in kg.
Total propellant initial mass in kg. This is the sum of the initial
mass of fluids in each tank and the initial mass of the solid grains.
HybridMotor.total_mass : Function
Total motor mass in kg as a function of time, defined as the sum
of propellant and dry mass.
of the dry mass (motor's structure mass) and the propellant mass, which
varies with time.
HybridMotor.propellant_mass : Function
Total propellant mass in kg as a function of time.
Total propellant mass in kg as a function of time, this includes the
mass of fluids in each tank and the mass of the solid grains.
HybridMotor.total_mass_flow_rate : Function
Time derivative of propellant total mass in kg/s as a function
of time as obtained by the thrust source.
Expand Down Expand Up @@ -199,8 +204,11 @@ def __init__(

.. seealso:: :doc:`Thrust Source Details </user/motors/thrust>`
dry_mass : int, float
The total mass of the motor structure, including chambers
and tanks, when it is empty and does not contain any propellant.
The total mass of the motor structure, including chambers,
bulkheads, screws, tanks, and others. This should be taken when the
motor is empty and does not contain any propellant. You should not
double count a component that is already accounted for in the rocket
class.
dry_inertia : tuple, list
Tuple or list containing the motor's dry mass inertia tensor
components, in kg*m^2. This inertia is defined with respect to the
Expand Down Expand Up @@ -345,18 +353,19 @@ def exhaust_velocity(self):
@funcify_method("Time (s)", "Mass (kg)")
def propellant_mass(self):
"""Evaluates the total propellant mass of the motor as the sum
of each tank mass and the grains mass.
Gui-FernandesBR marked this conversation as resolved.
Show resolved Hide resolved
of fluids mass in each tank and the grains mass.

Returns
-------
Function
Total propellant mass of the motor, in kg.
Total propellant mass of the motor as a function of time, in kg.
"""
return self.solid.propellant_mass + self.liquid.propellant_mass

@cached_property
def propellant_initial_mass(self):
"""Returns the initial propellant mass of the motor.
"""Returns the initial propellant mass of the motor. See the docs of the
HybridMotor.propellant_mass property for more information.

Returns
-------
Expand All @@ -367,8 +376,8 @@ def propellant_initial_mass(self):

@funcify_method("Time (s)", "mass flow rate (kg/s)", extrapolation="zero")
def mass_flow_rate(self):
"""Evaluates the mass flow rate of the motor as the sum of each tank
mass flow rate and the grains mass flow rate.
"""Evaluates the mass flow rate of the motor as the sum of mass flow
rates from all tanks and the solid grains mass flow rate.

Returns
-------
Expand Down Expand Up @@ -486,6 +495,21 @@ def propellant_I_33(self):

@funcify_method("Time (s)", "Inertia I_12 (kg m²)")
def propellant_I_12(self):
"""Inertia tensor 12 component of the propellant, the inertia is
relative to the e_1 and e_2 axes, centered at the instantaneous
propellant center of mass.

Returns
-------
Function
Propellant inertia tensor 12 component at time t.

Notes
-----
This is assumed to be zero due to axial symmetry of the motor. This
could be improved in the future to account for the fact that the
motor is not perfectly symmetric.
"""
Gui-FernandesBR marked this conversation as resolved.
Show resolved Hide resolved
return 0

@funcify_method("Time (s)", "Inertia I_13 (kg m²)")
Expand Down
39 changes: 26 additions & 13 deletions rocketpy/motors/liquid_motor.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,15 @@ class LiquidMotor(Motor):
List containing the motor's added tanks and their respective
positions.
LiquidMotor.dry_mass : float
The total mass of the motor structure, including chambers
and tanks, when it is empty and does not contain any propellant.
The total mass of the motor structure, including chambers, bulkheads,
screws, tanks, and others. This should be taken when the motor is empty
and does not contain any propellant. You should not double count a
component that is already accounted for in the rocket class.
LiquidMotor.propellant_initial_mass : float
Total propellant initial mass in kg, includes
fuel and oxidizer.
Total propellant initial mass in kg, includes fuel and oxidizer.
LiquidMotor.total_mass : Function
Total motor mass in kg as a function of time, defined as the sum
of propellant and dry mass.
of propellant mass and the motor's dry mass (i.e. structure mass).
LiquidMotor.propellant_mass : Function
Total propellant mass in kg as a function of time, includes fuel
and oxidizer.
Expand Down Expand Up @@ -175,8 +176,11 @@ def __init__(

.. seealso:: :doc:`Thrust Source Details </user/motors/thrust>`
dry_mass : int, float
The total mass of the motor structure, including chambers
and tanks, when it is empty and does not contain any propellant.
The total mass of the motor structure, including chambers,
bulkheads, screws, tanks, and others. This should be taken when the
motor is empty and does not contain any propellant. You should not
double count a component that is already accounted for in the rocket
class.
dry_inertia : tuple, list
Tuple or list containing the motor's dry mass inertia tensor
components, in kg*m^2. This inertia is defined with respect to the
Expand Down Expand Up @@ -260,12 +264,19 @@ def exhaust_velocity(self):
-------
self.exhaust_velocity : Function
Gas exhaust velocity of the motor.

Notes
-----
The exhaust velocity is computed as the ratio of the thrust and the
mass flow rate. Therefore, this will vary with time if the mass flow
rate varies with time.
"""
return self.thrust / (-1 * self.mass_flow_rate)

@funcify_method("Time (s)", "Propellant Mass (kg)")
def propellant_mass(self):
"""Evaluates the mass of the motor as the sum of each tank mass.
"""Evaluates the mass of the motor as the sum of fluids mass in each
Gui-FernandesBR marked this conversation as resolved.
Show resolved Hide resolved
tank, which may include fuel and oxidizer and usually vary with time.

Returns
-------
Expand All @@ -281,7 +292,8 @@ def propellant_mass(self):

@cached_property
def propellant_initial_mass(self):
"""Property to store the initial mass of the propellant.
"""Property to store the initial mass of the propellant, this includes
fuel and oxidizer.

Returns
-------
Expand All @@ -292,8 +304,9 @@ def propellant_initial_mass(self):

@funcify_method("Time (s)", "Mass flow rate (kg/s)", extrapolation="zero")
def mass_flow_rate(self):
"""Evaluates the mass flow rate of the motor as the sum of each tank
mass flow rate.
"""Evaluates the mass flow rate of the motor as the sum of mass flow
rate from each tank, which may include fuel and oxidizer and usually
vary with time.

Returns
-------
Expand All @@ -317,12 +330,12 @@ def mass_flow_rate(self):
def center_of_propellant_mass(self):
"""Evaluates the center of mass of the motor from each tank center of
mass and positioning. The center of mass height is measured relative to
the motor nozzle.
the origin of the motor's coordinate system.

Returns
-------
Function
Center of mass of the motor, in meters.
Position of the propellant center of mass, in meters.
"""
total_mass = 0
mass_balance = 0
Expand Down
59 changes: 34 additions & 25 deletions rocketpy/motors/motor.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,19 @@ class Motor(ABC):
:doc:`Positions and Coordinate Systems </user/positions>` for more
information.
Motor.dry_mass : float
The total mass of the motor structure, including chambers
and tanks, when it is empty and does not contain any propellant.
The total mass of the motor structure, including chambers, bulkheads,
screws, tanks, and others. This should be taken when the motor is empty
and does not contain any propellant. You should not double count a
component that is already accounted for in the rocket class.
Motor.propellant_initial_mass : float
Total propellant initial mass in kg.
Total propellant initial mass in kg, including solid, liquid and gas
phases.
Motor.total_mass : Function
Total motor mass in kg as a function of time, defined as the sum
of propellant and dry mass.
of propellant mass and the motor's dry mass (i.e. structure mass).
Motor.propellant_mass : Function
Total propellant mass in kg as a function of time.
Total propellant mass in kg as a function of time, including solid,
liquid and gas phases.
Motor.total_mass_flow_rate : Function
Time derivative of propellant total mass in kg/s as a function
of time as obtained by the thrust source.
Expand Down Expand Up @@ -174,8 +178,11 @@ def __init__(
.. seealso:: :doc:`Thrust Source Details </user/motors/thrust>`

dry_mass : int, float
The total mass of the motor structure, including chambers
and tanks, when it is empty and does not contain any propellant.
The total mass of the motor structure, including chambers,
bulkheads, screws, tanks, and others. This should be taken when the
motor is empty and does not contain any propellant. You should not
double count a component that is already accounted for in the rocket
class.
center_of_dry_mass_position : int, float
The position, in meters, of the motor's center of mass with respect
to the motor's coordinate system when it is devoid of propellant.
Expand Down Expand Up @@ -378,19 +385,19 @@ def exhaust_velocity(self):
"""
pass

@funcify_method("Time (s)", "total mass (kg)")
@funcify_method("Time (s)", "Total mass (kg)")
def total_mass(self):
"""Total mass of the motor as a function of time. It is defined as the
propellant mass plus the dry mass.

Returns
-------
Function
Total mass as a function of time.
Motor total mass as a function of time.
"""
return self.propellant_mass + self.dry_mass

@funcify_method("Time (s)", "propellant mass (kg)")
@funcify_method("Time (s)", "Propellant mass (kg)")
def propellant_mass(self):
"""Total propellant mass as a Function of time.

Expand All @@ -403,11 +410,10 @@ def propellant_mass(self):
self.total_mass_flow_rate.integral_function() + self.propellant_initial_mass
)

@funcify_method("Time (s)", "mass dot (kg/s)", extrapolation="zero")
@funcify_method("Time (s)", "Mass dot (kg/s)", extrapolation="zero")
Gui-FernandesBR marked this conversation as resolved.
Show resolved Hide resolved
def total_mass_flow_rate(self):
"""Time derivative of propellant mass. Assumes constant exhaust
velocity. The formula used is the opposite of thrust divided by
exhaust velocity.
"""Time derivative of the propellant mass as a function of time. The
formula used is the opposite of thrust divided by exhaust velocity.

Returns
-------
Expand All @@ -427,10 +433,8 @@ def total_mass_flow_rate(self):
Notes
-----
This function computes the total mass flow rate of the motor by
dividing the thrust data by a constant approximation of the exhaust
velocity.
This approximation of the total mass flow rate is used in the
following manner by the child Motor classes:
dividing the thrust data by the exhaust velocity. This is an
approximation, and it is used by the child Motor classes as follows:

- The ``SolidMotor`` class uses this approximation to compute the
grain's mass flow rate;
Expand All @@ -449,7 +453,7 @@ def total_mass_flow_rate(self):
@property
@abstractmethod
def propellant_initial_mass(self):
"""Propellant initial mass in kg.
"""Propellant initial mass in kg, including solid, liquid and gas phases

Returns
-------
Expand Down Expand Up @@ -478,8 +482,8 @@ def center_of_mass(self):
@abstractmethod
def center_of_propellant_mass(self):
"""Position of the propellant center of mass as a function of time.
The position is specified as a scalar, relative to the motor's
coordinate system.
The position is specified as a scalar, relative to the origin of the
motor's coordinate system.

Returns
-------
Expand All @@ -501,7 +505,7 @@ def I_11(self):
Notes
-----
The e_1 direction is assumed to be the direction perpendicular to the
motor body axis.
motor body axis. Also, due to symmetry, I_11 = I_22.

References
----------
Expand Down Expand Up @@ -540,7 +544,8 @@ def I_22(self):
Notes
-----
The e_2 direction is assumed to be the direction perpendicular to the
motor body axis, and perpendicular to e_1.
motor body axis, and perpendicular to e_1. Also, due to symmetry,
I_22 = I_11.

References
----------
Expand Down Expand Up @@ -667,6 +672,7 @@ def I_23(self):
----------
https://en.wikipedia.org/wiki/Moment_of_inertia
"""
# wrt = with respect to
# Propellant inertia tensor 23 component wrt propellant center of mass
propellant_I_23 = self.propellant_I_23

Expand Down Expand Up @@ -1103,8 +1109,11 @@ def __init__(
coordinate system.
See :doc:`Positions and Coordinate Systems </user/positions>`
dry_mass : int, float
The total mass of the motor structure, including chambers
and tanks, when it is empty and does not contain any propellant.
The total mass of the motor structure, including chambers,
bulkheads, screws, tanks, and others. This should be taken when the
motor is empty and does not contain any propellant. You should not
double count a component that is already accounted for in the rocket
class.
propellant_initial_mass : int, float
The initial mass of the propellant in the motor.
center_of_dry_mass_position : int, float, optional
Expand Down
23 changes: 14 additions & 9 deletions rocketpy/motors/solid_motor.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ class SolidMotor(Motor):
SolidMotor.grain_initial_mass : float
Initial mass of each grain in kg.
SolidMotor.dry_mass : float
The total mass of the motor structure, including chambers
and tanks, when it is empty and does not contain any propellant.
The total mass of the motor structure, including chambers, bulkheads,
screws, and others. This should be taken when the motor is empty and
does not contain any propellant. You should not double count a component
that is already accounted for in the rocket class.
Gui-FernandesBR marked this conversation as resolved.
Show resolved Hide resolved
SolidMotor.propellant_initial_mass : float
Total propellant initial mass in kg.
SolidMotor.total_mass : Function
Expand All @@ -78,8 +80,8 @@ class SolidMotor(Motor):
Time derivative of propellant total mass in kg/s as a function
of time as obtained by the thrust source.
SolidMotor.center_of_mass : Function
Position of the motor center of mass in
meters as a function of time.
Position of the motor center of mass in meters as a function of time,
with respect to the motor's coordinate system.
See
:doc:`Positions and Coordinate Systems </user/positions>` for more
information regarding the motor's coordinate system.
Expand Down Expand Up @@ -226,8 +228,10 @@ def __init__(
nozzle_radius : int, float
Motor's nozzle outlet radius in meters.
dry_mass : int, float
The total mass of the motor structure, including chambers
and tanks, when it is empty and does not contain any propellant.
The total mass of the motor structure, including chambers,
bulkheads, screws, and others. This should be taken when the motor
is empty and does not contain any propellant. You should not double
count a component that is already accounted for in the rocket class.
dry_inertia : tuple, list
Tuple or list containing the motor's dry mass inertia tensor
components, in kg*m^2. This inertia is defined with respect to the
Expand Down Expand Up @@ -421,7 +425,8 @@ def mass_flow_rate(self):

@mass_flow_rate.setter
def mass_flow_rate(self, value):
"""Sets the mass flow rate of the motor.
"""Sets the mass flow rate of the motor. This includes all the grains
burning all at once.

Parameters
----------
Expand All @@ -432,10 +437,10 @@ def mass_flow_rate(self, value):
-------
None
"""
self._mass_flow_rate = value.reset("Time (s)", "grain mass flow rate (kg/s)")
self._mass_flow_rate = value.reset("Time (s)", "Grain mass flow rate (kg/s)")
self.evaluate_geometry()

@funcify_method("Time (s)", "center of mass (m)", "linear")
@funcify_method("Time (s)", "Center of Propellant Mass (m)", "linear")
def center_of_propellant_mass(self):
"""Position of the propellant center of mass as a function of time.
The position is specified as a scalar, relative to the motor's
Expand Down
Loading
Loading