Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/examples/orbit.ipynb
Views: 531
Orbiting the Sun
Modeling and Simulation in Python
Copyright 2021 Allen Downey
License: Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
In a previous example, we modeled the interaction between the Earth and the Sun, simulating what would happen if the Earth stopped in its orbit and fell straight into the Sun.
Now let's extend the model to two dimensions and simulate one revolution of the Earth around the Sun, that is, one year.
At perihelion, the distance from the Earth to the Sun is 147.09 million km and its velocity is 30,290 m/s.
Here are the other constants we'll need, all with about 4 significant digits.
Exercise: Put the initial conditions in a State
object with variables x
, y
, vx
, and vy
. Create a System
object with variables init
and t_end
.
Exercise: Write a function called universal_gravitation
that takes a State
and a System
and returns the gravitational force of the Sun on the Earth as a Vector
.
Test your function with the initial conditions; the result should be a Vector with approximate components:
Exercise: Write a slope function that takes a timestamp, a State
, and a System
and computes the derivatives of the state variables.
Test your function with the initial conditions. The result should be a sequence of four values, approximately
Exercise: Use run_solve_ivp
to run the simulation. Save the return values in variables called results
and details
.
You can use the following function to plot the results.
You will probably see that the earth does not end up back where it started, as we expect it to after one year. The following cells compute the error, which is the distance between the initial and final positions.
The problem is that the algorithm used by run_solve_ivp
does not work very well with systems like this. There are two ways we can improve it.
run_solve_ivp
takes a keyword argument, rtol
, that specifies the "relative tolerance", which determines the size of the time steps in the simulation. Lower values of rtol
require smaller steps, which yield more accurate results. The default value of rtol
is 1e-3
.
Exercise: Try running the simulation again with smaller values, like 1e-4
or 1e-5
, and see what effect it has on the magnitude of offset
.
The other way to improve the results is to use a different algorithm. run_solve_ivp
takes a keyword argument, method
, that specifies which algorithm it should use. The default is RK45
, which is a good, general-purpose algorithm, but not particularly good for this system. One of the other options is RK23
, which is usually less accurate than RK45
(with the same step size), but for this system it turns out to be unreasonably good, for reasons I don't entirely understand. Yet another option is 'DOP853', which is particularly good when rtol
is small.
Exercise: Run the simulation with one of these methods and see what effect it has on the results. To get a sense of how efficient the methods are, display details.nfev
, which is the number of times run_solve_ivp
called the slope function.
Animation
You can use the following draw function to animate the results, if you want to see what the orbit looks like (not in real time).