Welcome back! In our last lesson, we developed a mathematical model for rocket thrust, linking it to exhaust velocity and mass flow rate. We now have the "push" that gets our rocket moving. This lesson focuses on a direct and critical consequence of that push: the rocket's changing mass.
As a rocket expels propellant to generate thrust, its total mass decreases. This is not a minor detail—it's fundamental to why rockets are so effective. As the mass () in Newton's second law () decreases, the same amount of thrust () produces a greater acceleration (). Our goal today is to implement this time-varying mass in our simulation, a crucial step toward building a realistic model of rocket flight.
The Physical Model: A System Losing Mass
Let's begin by visualizing the process. At any moment, the total system we are interested in includes both the rocket and the fuel it is about to expel.

The diagram perfectly captures our scenario. The key variables are:
- Wet Mass (): The total initial mass of the rocket, including its structure, payload, and all propellant. This corresponds to in part (a) of the diagram.
- Dry Mass (): The mass of the rocket after all propellant has been consumed.
- Propellant Mass (): The total mass of the fuel that will be burned. Therefore, .
During the engine burn, the mass of the rocket at any time can be found by subtracting the amount of propellant burned from the initial wet mass.
From Model to Code: Two Implementation Strategies
In the previous lesson, we established the concept of mass flow rate (), which is the mass of propellant consumed per second (in kg/s). Assuming this rate is constant, the mass of the rocket at any time during the burn is:
Once the burn is complete (at burn_time), the mass remains constant at .
This logic can be implemented in code in two primary ways, both of which are useful in different simulation contexts.
Strategy 1: The Vectorized Approach with NumPy
If we are simulating the entire flight at once, we can pre-calculate the rocket's mass at every single time step and store it in a NumPy array. This is an efficient, vectorized approach that leverages NumPy's strengths.
The following article provides a clear, practical example of this method.
Making a simple flight simulation for model rockets in Python
This article walks through setting up the initial parameters for a model rocket simulation. It shows how to translate physical properties into NumPy arrays for calculation.
First, read the beginning of the article to see how the initial properties are defined, including the mass variables and the calculation of massFlowRate. Next, focus on the core of the implementation. The author creates a mass array that holds the rocket's mass at every time step. Study this line of code carefully.
Let's break down that key line of code:mass = np.append(np.repeat(totalMass, index) - time[0:index] * massFlowRate, np.repeat(dryMass, len(time) - index))
time[0:index] * massFlowRate: This calculates the total mass expelled at each time step during the burn.np.repeat(totalMass, index) - ...: This subtracts the expelled mass from the initialtotalMassfor all time steps up to the end of the burn (index). This gives us the changing mass during the thrust phase.np.repeat(dryMass, len(time) - index): This creates an array where the mass is constant atdryMassfor all time steps after the burn.np.append(...): This joins the two pieces together, creating a single array representing the rocket's mass over the entire simulation time.
This method is elegant and computationally efficient, making it a great choice for this type of simulation.
Strategy 2: The Step-by-Step Simulation Loop
The alternative is to update the mass at each iteration within the simulation loop itself. This approach is more in line with the Euler method we implemented in Module 2 and is highly flexible for more complex simulations where conditions might change unexpectedly.
The logic inside the loop looks like this:
# Inside the simulation loop, for each time step 'dt'
if current_time < burn_time:
current_mass = current_mass - mass_flow_rate * dt
In this model, the current_mass variable is updated at each step, reflecting the continuous consumption of fuel. After burn_time, this update no longer occurs, and the mass stabilizes at the dry mass.
The following tutorial implements a simulation using this step-by-step logic. While the code is more complex and uses data from an external file, the principle is the same.
[PDF] Python Model Rocket Trajectory Simulator Tutorial - SpaceLab Illinois
This tutorial describes a more advanced simulation that reads motor data from a file. We are interested in how it updates mass inside its main simulation loop.
In the document, find the section "Python Code Explanation" and locate the subsection describing the "Loop to simulate values...". Within the code block shown there, you will find this line that updates the mass. Here, massval is an array of propellant mass values from a data file, so massval[k] - massval[k+1] represents the mass consumed in one time step, which is conceptually identical to our mass_flow_rate * dt.
This iterative update is the core of how dynamic systems are modeled numerically. The fact that the rocket's mass is changing is precisely why we need these numerical methods. An analytical, "closed-form" solution is generally not possible for such a system.
The following video provides a concise explanation of this exact point.
Simulating Rocket Trajectories with Python
This video from Miscellaneous Bits explains the fundamentals of simulating trajectories and why numerical methods are necessary for complex problems like rocketry.
Watch the segment from "FAL MX dot" to understand why a non-constant mass or force necessitates a numerical "brute force" approach. Then, skip ahead to see how mass properties are set up for a simulation. The video specifies initial masses and a mass flow rate, M dot, as key inputs. Finally, see how this is used within the function that defines the system's physics, where the creator notes, "The mass of the rocket is also defined here", showing it's a variable that changes based on the simulation state (i.e., whether the engine is burning).
Conclusion
In this lesson, you have tackled a fundamental aspect of rocket physics: its changing mass. This is not just an added detail for realism; it is a core feature that dictates the performance and trajectory of the vehicle.
Here are the key takeaways:
- A rocket's mass is not constant. It decreases from an initial wet mass to a final dry mass as it consumes propellant.
- This change can be modeled using the mass flow rate (), which we assume to be constant for our initial simulation.
- In Python, you can implement this by either pre-calculating a mass array using NumPy's vectorized operations or by updating the mass iteratively within your simulation loop.
You now have the two most important components for our first launch simulation: a thrust force that pushes the rocket up and a changing mass that makes this push increasingly effective. In our next lesson, we will combine these elements with gravity to simulate a 1D vertical rocket launch from liftoff to motor burnout.