Part III: ODE SolversChapter 3 of 6

ODE Integration Methods

Marching forward in time: from Euler's simple step to adaptive Runge-Kutta, implicit methods for stiff systems, and symplectic integrators that conserve energy for Hamiltonian dynamics.

The Initial Value Problem

Given \(\frac{dy}{dt} = f(t, y)\) with \(y(t_0) = y_0\), compute \(y(t)\) for\(t > t_0\). This is the core problem of dynamics: planetary orbits, chemical kinetics, neural networks, population models, circuit simulation.

Key questions: How small must \(h = \Delta t\) be? Is the method stable? Does it conserve physical invariants (energy, symplectic structure)?

1. Euler's Method

The simplest ODE integrator: step along the tangent line at the current point.

\(y_{n+1} = y_n + h \, f(t_n, y_n)\)

First-order method: local error \(O(h^2)\), global error \(O(h)\)

Error Analysis

Taylor expand: \(y(t+h) = y(t) + h y'(t) + \frac{h^2}{2} y''(t) + \cdots\)Euler keeps only the first two terms, so the local truncation error is\(\tau = \frac{h^2}{2} y''(\xi) = O(h^2)\). Over \(N = T/h\) steps, errors accumulate to give global error \(O(h)\).

Euler Method: Simple but Instructive

Python
script.py36 lines

Click Run to execute the Python code

Code will be executed with Python 3 on the server

2. The Classic Runge-Kutta 4 (RK4)

The workhorse of ODE integration. Four function evaluations per step yield fourth-order accuracy:

\(k_1 = h \, f(t_n, y_n)\)

\(k_2 = h \, f(t_n + h/2, \; y_n + k_1/2)\)

\(k_3 = h \, f(t_n + h/2, \; y_n + k_2/2)\)

\(k_4 = h \, f(t_n + h, \; y_n + k_3)\)

\(y_{n+1} = y_n + \frac{1}{6}(k_1 + 2k_2 + 2k_3 + k_4)\)

Local error \(O(h^5)\), global error \(O(h^4)\). The most popular fixed-step ODE solver.

RK4 Implementation and Convergence Test

Python
script.py47 lines

Click Run to execute the Python code

Code will be executed with Python 3 on the server

3. Adaptive Step Size: RK45

Fixed step sizes waste effort in smooth regions and miss features in rapidly changing regions. Embedded Runge-Kutta pairs (like Dormand-Prince RK45) compute two solutions of different order to estimate the local error, then adjust \(h\) automatically.

Step Size Control

Estimate error \(\hat{e} = |y_5 - y_4|\) (difference between 5th and 4th order solutions). If \(\hat{e} > \text{tol}\), reject step and shrink \(h\). If \(\hat{e} \ll \text{tol}\), accept and grow \(h\). Optimal step factor: \(h_{\text{new}} = h \cdot 0.9 \cdot (\text{tol}/\hat{e})^{1/5}\).

Adaptive ODE Solving with scipy.integrate

Python
script.py43 lines

Click Run to execute the Python code

Code will be executed with Python 3 on the server

4. Stiff Systems and Implicit Methods

A system is stiff when it contains both fast and slow timescales. Explicit methods must use tiny steps (dictated by the fast scale) even when tracking the slow dynamics. Implicit methods like backward Euler and BDF (backward differentiation formulas) remain stable with large steps.

Backward Euler (implicit)

\(y_{n+1} = y_n + h \, f(t_{n+1}, y_{n+1})\)

A-stable: stable for any \(h > 0\) on \(y' = \lambda y\) with Re(\(\lambda\)) < 0

Forward Euler (explicit)

\(y_{n+1} = y_n + h \, f(t_n, y_n)\)

Stable only if \(|1 + h\lambda| < 1\), requires \(h < 2/|\lambda|\)

Stiff System: Explicit vs Implicit

Python
script.py46 lines

Click Run to execute the Python code

Code will be executed with Python 3 on the server

5. Symplectic Integrators

For Hamiltonian systems \(H(q,p) = T(p) + V(q)\), standard integrators cause energy to drift over long times. Symplectic integrators preserve the symplectic structure of phase space, keeping energy bounded (oscillating, not drifting) forever.

Stormer-Verlet (Leapfrog)

\(p_{n+1/2} = p_n - \frac{h}{2} \nabla V(q_n)\) (half-kick)

\(q_{n+1} = q_n + h \, p_{n+1/2} / m\) (drift)

\(p_{n+1} = p_{n+1/2} - \frac{h}{2} \nabla V(q_{n+1})\) (half-kick)

Second-order, time-reversible, symplectic. Used in molecular dynamics, celestial mechanics, particle physics.

Symplectic vs Non-Symplectic: Energy Conservation

Python
script.py64 lines

Click Run to execute the Python code

Code will be executed with Python 3 on the server

6. Stability Regions

For the test equation \(y' = \lambda y\), a method is stable if the numerical solution does not blow up. The stability region is the set of\(h\lambda \in \mathbb{C}\) for which \(|y_{n+1}/y_n| \leq 1\).

Forward Euler

\(y_{n+1} = (1 + h\lambda) y_n\), stable when \(|1 + h\lambda| \leq 1\): a disk of radius 1 centered at \(-1\).

Backward Euler

\(y_{n+1} = \frac{y_n}{1 - h\lambda}\), stable when \(|1 - h\lambda| \geq 1\): the complement of a disk. A-stable!

Stability Region Computation

Python
script.py52 lines

Click Run to execute the Python code

Code will be executed with Python 3 on the server