5

I've been trying to implement a higher order Runge-Kutta numerical integrator in MATLAB for a bit now with ambitions of n-body trajectory fun. Unfortunately, I have not had success in reaping the rewards of such higher order methods.

I have (I believe) a good grasp of how Runge-Kutta methods work and have ample experience with lower order methods like an RK4 or Dormand Prince.

Various answers on the site have suggested RK78 and RK89. I found Fehlberg's Technical Report (NTRS ID: 19680027281) describing both, as well as C++ source code from Trick and GMAT giving the Butcher tableaus (in a C++ structure) for each method. This gives me confidence that my coefficients are correct as I copied them into my MATLAB script (and only "translated" to MATLAB).

My simple test case is an object in a 2D 185 km orbit above "Earth", that is, a point mass with no atmosphere. I used a fixed 30 second time step (just trying to get one of the orders to work!).

For both of my RK78 & RK89 implementations I get nearly identical erroneous outputs of this growing spiral-like trajectory:


Edit: my specific energy plots were not correct, I have fixed those, the problem(s) still remain with the trajectory.


RK78:

RK78 results

RK89:

RK89 results

These results occur regardless of whether I select the 7th or 8th (or 8th or 9th) order output.

Compare these to a much more reasonable result from a Dormand Price integration programmed in the same structure (trajectory plot excluded because it's expectedly benign):

RK45 specific energy

Here is a code snippet of the core iteration scheme:

% k is a m x 4 matrix where m is the number of stages, 16 for RK89 (shown), 13 for RK78.
% multiplying the weights (C, m x 1, transposed) by k (m x 4) gives the output 'slopes' (1 x 4)

while 1 % Runge-Kutta Slopes for j = 1:16 % k_j (individual k slopes) input = zi(i,:); for jj = 1:16 % (component of k slopes, B matrix) input = input + B(j,jj)*k(jj,:); end k(j,:) = dz(input,G,M_E)'; % call physics model for j'th node end

% Forward local extrapolation
i = i+1; % move time forward

% Break Conditions
...

% Integrate
zi(i,:) = zi(i-1,:) + dt*(C'*k); % next state

end

% force model function 'dz': function dzdt = dz(z,G,M_E) aG_E = G*M_E/(z(1)^2 + z(2)^2); % gravitational acceleration (m/s^2)

% State Variable Definitions: % z1 = x, z2 = y, % z3 = Vx, z4 = Vy

% 'slopes': dzdt(1) = z(3); dzdt(2) = z(4); dzdt(3) = -aG_Ez(1)/sqrt(z(1)^2 + z(2)^2); dzdt(4) = -aG_Ez(2)/sqrt(z(1)^2 + z(2)^2); end

Does anyone have any clues as to what is going (so horribly) wrong?

BrendanLuke15
  • 9,755
  • 2
  • 26
  • 80
  • 3
    BTW, you should use the standard gravitational parameter rather than the mass. Horizons gives 398600.435436 km^3/s^2 for Earth. – PM 2Ring Jan 27 '22 at 05:58
  • 4
    I agree 1000% with @PM2Ring. Never use G*M. Use the standard gravitational parameter instead. Using G*M is a way to chop accuracy down to 4 or 5 decimal places. – David Hammen Jan 27 '22 at 13:26
  • @DavidHammen I agree, this is just a 2D sandbox I borrowed from long ago (just trying to get the Runge-Kutta working) – BrendanLuke15 Jan 27 '22 at 13:30
  • 2
    I've had limited (being nice) success using adaptive RK techniques. There are multiple commercial vendors whose adaptive integrators are <> awful. RK techniques address the problem of solving first order differential equations. Gravitation is a second order differential equation. When one piles the position and velocity together the result is oftentimes a pile of <>. You are throwing out geometry by doing so (that the underlying equations are second order ODEs is geometry), and the result of flushing geometry down the toilet is oftentimes garbage. – David Hammen Jan 27 '22 at 13:43
  • 2
    Sure, the G*M isn't the cause of your problem here, which is why I said 'BTW'. Another option to investigate when doing gravity sims on simple systems is the use of a symplectic integrator, eg Leapfrog with Yoshida coefficients. On more complex systems, you need a more sophisticated integrator. If you try to simulate a system with some bodies with periods of a day or so and other bodies with periods >100 years, using a single time step isn't fun. Also , what David H just said. ;) – PM 2Ring Jan 27 '22 at 13:54
  • 2
    When you come across a technique that spirals in or out, you have two choices: Determine if you have implemented it incorrectly, or toss it. The explicit RK techniques conserve neither energy nor angular momentum. Canonical RK4 is amazingly stable in this regard compared to both higher and lower order RK techniques. It does spiral, but does so rather slowly. There are second order adaptations of the RK techniques (e.g., Runge-Kutta-Nyström techniques) that do a better job, and some of them are adaptive. – David Hammen Jan 27 '22 at 13:54
  • 2
    One last thing: Do not roll your own. This is a field where people work for years on a single technique to shake out the bugs in that technique. There are lots and lots of integrators that target orbital mechanics on GitHub (for example). Investigate those. That alone will take a good deal of time, but it will be time well spent compared to the time wasted if you do decide to roll your own. – David Hammen Jan 27 '22 at 13:58
  • 1
    I disagree slightly with David H. I think "rolling your own" gravity sim can be a fun and instructive exercise. And it's ok if you just want an approximate solution. But if the goal is to calculate real positions of actual bodies in space, forget it. Use a solution that has the benefit of years of expertise and testing. – PM 2Ring Jan 27 '22 at 14:04
  • @DavidHammen re: don't roll your own. I've seen you comment this before on this site, it seems I am falling for that trap! – BrendanLuke15 Jan 27 '22 at 14:07
  • 3
    @PM2Ring I also slightly disagree with myself. It is educational to roll your own RK4, or your own low order symplectic integrator. But rolling your own adaptive integrator? That is not a good idea. A much better idea is to try using something like ODEPACK (LSODE, LSODA, ...). This also involves lots of "fun", "fun" in quotes. A lot of the well-developed integration techniques have FORTRAN-style interfaces (aka "fun"). This is educational. It is not fun in any reasonable sense of the word "fun". – David Hammen Jan 27 '22 at 14:34
  • 3
    However, there are boatloads of numerical techniques that date back to the 1950s / 1960s that inherently have FORTRAN (not just Fortran but FORTRAN) style interfaces. They might be hiding behind f2c (I prefer the more vulgar eff2c) transformations, but they ultimately are FORTRAN-style interfaces. Learning how to deal with that ugliness can be useful. – David Hammen Jan 27 '22 at 14:36

2 Answers2

4

When in doubt, do what my high school physics teacher taught; use dimensional analysis and check your units. dz/dt should be an acceleration in length per time squared. GM is length cubed per time squared.


$$a_G = -GM \frac{\mathbf{r}}{r^3} = -GM \frac{\mathbf{\hat{r}}}{r^2}$$

which usually works out to something like

$$a_x = GM\frac{x}{(x^2+y^2)^{1.5}}$$

$$a_y = GM\frac{y}{(x^2+y^2)^{1.5}}$$

or acc = pos * ((pos**2).sum())**-1.5

Either that, or you've discovered a new force!

And here's how to add $J_2$ as well.

uhoh
  • 148,791
  • 53
  • 476
  • 1,473
1

Foiled by my own eyes! (and MATLAB's indexing)

Lackluster, but expected. There was a bug in my code where the indices were off by one because MATLAB indexes from 1 instead of 0 I didn't look hard enough.

The comments are insightful and I offer these insights in return:

  • Same test case: 30s fixed step (7th order solution), point mass 2D Earth

specific energy w.r.t surface

Where the spread (min max) of specific energies (w.r.t. Earth's surface) is on the order of 10's of micro-Joules (per kg), though I think this is stretching the limits of double precision. The orbit only drifts inwards by ~16 micrometers.

BrendanLuke15
  • 9,755
  • 2
  • 26
  • 80
  • All of the specific energy plots are incorrect (including in question), but its just a constant offset (km's used instead of meters for Earth surface potential) so I won't bother fixing it :) – BrendanLuke15 Feb 03 '22 at 17:15