Problem 3

In this first part we’ll learn to solve differential equations numerically in Python. In the second part we’ll use the code we write here to solve a much more complicated problem. As a motivating example, we will be proving Kepler’s first law numerically.

The force on a body of mass \(m\) at \(\boldsymbol{\mathrm{r}}\) due to a body of mass \(M\) at the origin is given by Newton’s law

\[ \boldsymbol{\mathrm{F}}= -\frac{GMm}{\left|\boldsymbol{r}\right|^3}\boldsymbol{r} \]

In two dimensions, where \(\boldsymbol{\mathrm{r}}=x\boldsymbol{\hat{\imath}} + y \boldsymbol{\hat{\jmath}}\), the components of the acceleration \(\boldsymbol{\mathrm{a}}=a_x \boldsymbol{\hat{\imath}} + a_y \boldsymbol{\hat{\jmath}}\) are given by

\[ a_x = \frac{\mathrm{d}v_x}{\mathrm{d}t} = - \frac{GMx}{\left(x^2 + y^2\right)^{3/2}},\quad a_y = \frac{\mathrm{d}v_y}{\mathrm{d}t} = - \frac{GMy}{\left(x^2 + y^2\right)^{3/2}} \]

A problem where we know the equations of motion and the starting point for the system is called an initial value problem and is a very common numerical problem in physics. Python comes with a few ways to easily solve initial value problems. Here we’ll use the scipy.integrate.solve_isp function.

We have to provide the function with three arguments to work (see the documentation for more). The first argument is a function \(\boldsymbol{\mathrm{F}}(t,\boldsymbol{\mathrm{X}})\) which ‘updates’ the system, this is where the equations of motion are set. This function must take the time, and a state vector as inputs and return the derivative (wrt time) of the state vector’s components. Our state vector we’ll call \(\boldsymbol{\mathrm{X}}\) and which just holds the current state of the system, in our case

\[ \boldsymbol{\mathrm{X}} = \left(x, y, v_x, v_y\right) \]

So it follows that the function \(\boldsymbol{\mathrm{F}}(t,\boldsymbol{\mathrm{X}})\) must return

\[ \boldsymbol{\mathrm{F}}(t,\boldsymbol{\mathrm{X}}) = \left(v_x, v_y, a_x, a_y\right) \]

The first two components are simply the last two components in the input. The second two components can be calculated from the acceleration equations above. The other arguments that scipy.integrate.solve_isp requires is the initial state of the system \(\boldsymbol{\mathrm{X}}_0\) and the time span over which to solve the equations.

A few tips:

  • You must set the method argument of solve_isp to ”Radau” to get a stable solution.

  • Set the t_eval to an array of time coordinates and the function will find \(\boldsymbol{\mathrm{X}}\) at those time coordinates.

  • The \((x, y, v_x, v_y)\) values are stored in array at result.y where result = solve_isp(…)

Example: Kepler’s First Law

States that

All planets move in elliptical orbits, with the sun at one focus.

To prove this numerically, start the solver with a body at \(x=1 \mathrm{AU}\), \(y=0\) and an initial velocity \(35\) km/s in the positive \(y\) direction. Plot the \(x\) and \(y\) values and you should see an elliptical orbit. Ensure you run the simulation over a sensible time-scale, e.g. a few years.

Now check if the orbit is elliptical. The equation of an ellipse is $\( \frac{x^2}{a^2} + \frac{y^2}{b^2} = 1 \)\( where \)a\( and \)b\( are the semi-minor and semi-major axes respectively. What are \)a\( and \)b$ for this orbit? The below figure shows what the orbit should look like.

_images/kepler_example_orbit.png

Fig. 1 The elliptical orbit for the Kepler’s law example.