/* Main program to perform a point-mass integration of the * Solar system, with relativistic corrections. The initial * conditions are those of the JPL DE200 numerical integration. * The final solution, given in the vector yn1[], is taken from * the DE200 for 100 days later. A test run of 400 steps in double * precison IEEE arithmetic with step size = 1/4 day and 11th * order Adams integration yielded agreement to about 10^-10 au * for the inner planets, 10^-12 au for Pluto, and 10^-8 au * for the Moon. The DE200, of course, included Earth-Moon figure * effects and five of the asteroids, and its arithmetic was * probably higher than double precision. * * If the Adams order is set to N, the first N+1 steps are * performed by the Runge-Kutta subroutine rungek.c. These * take about 7 times longer than the subsequent ones done * by the Adams-Bashforth-Moulton routine adams.c. * * Neither the step size nor the approximation order has been * made self-adjusting. Some experimentation is recommended, to * achieve the desired balance of speed and accuracy. The * example above was chosen to give about the same theoretical * error per day as specified in the DE102 reference below. * * -Steve Moshier */ # include # include # include "ode_moshier.h" /* Compute relativity corrections, or not: */ #define DOREL 1 /* Include the Moon as a separate body, or not: */ #define MOON 1 /* Constrain the relativistic barycenter of the solar * system to stay at the origin. Note, with the asteroids * (10^-9 solar masses) missing, this step is possibly useless * and was omitted in the test example. The code for it is * supplied at the end of this file. */ #define BARYC 0 double sqrt(); #if MOON #define NBODY 11 #define IMOON 9 #else #define NBODY 10 #endif #define ISUN (NBODY-1) #define NTOTAL (NBODY) #define NEQ (6*NBODY) #define MAXORD 13 #if DOREL #if BARYC #define NEQC (NEQ-6) #else #define NEQC NEQ #endif #else #define NEQC (NEQ) #endif static double vnewt[NEQ]; static double awork[ (NEQ*(MAXORD+2))+(MAXORD+2)+(6*NEQ) ]; static double rwork[(MAXRUNG+2)*NEQ]; static double Rij[NTOTAL][NTOTAL]; /* Speed of light. Note, all dimensions are in astronomical * units (au) and days (86,400 seconds). */ #define C 173.1446328 /* Solar system barycentric velocity and position * state of Mercury, Venus, EMB, ..., Pluto, MOON, Sun * in the order dx/dt, x, dy/dt, y, dz/dt, z for each object. * * EMB is the arithmetic average of Earth and Moon, weighted by * their masses. The coordinates of the MOON variable are the difference * between the solar system barycentric coordinates of the Moon * minus those of the Earth. */ /* Julian date of the initial state yn[] * June 28.0, 1969: */ #define JD0 2440400.50 static double yn[] = { 3.367492758813184e-003, /* Mercury */ 3.617650084026384e-001, 2.489452047536652e-002, -9.077580081092690e-002, 1.294630071041128e-002, -8.571250013597834e-002, 1.095206748972985e-002, /* Venus */ 6.127542336221157e-001, 1.561768454932838e-002, -3.483591895730089e-001, 6.331105550175031e-003, -1.952758215816601e-001, 1.681126759384403e-002, /* EMB */ 1.205197129002194e-001, 1.748308899617618e-003, -9.258323035784091e-001, 7.582041930175932e-004, -4.015377611192672e-001, 1.448165239083299e-002, /* Mars */ -1.101837696063662e-001, 2.424628123494023e-004, -1.327593278911103e+000, -2.815196436092114e-004, -6.058866834707231e-001, 1.092015004926191e-003, /* Jupiter */ -5.379703845550703e+000, -6.518116265389094e-003, -8.304767428789135e-001, -2.820782997470719e-003, -2.248295252614748e-001, -3.217557586964646e-003, /* Saturn */ 7.894394222587950e+000, 4.335809727271375e-003, 4.596483181197301e+000, 1.928645932522133e-003, 1.558697670343092e+000, 2.211920155513113e-004, /* Uranus */ -1.826538634212984e+001, -3.762477278855801e-003, -1.161959795438843e+000, -1.651014777644869e-003, -2.501080003472951e-001, 2.642773506889557e-003, /* Neptune */ -1.605499953831724e+001, -1.498309226803948e-003, -2.394216805154041e+001, -6.790394433396178e-004, -9.400159225576589e+000, 3.221893230538327e-004, /* Pluto */ -3.048349217668479e+001, -3.143582327761257e-003, -8.724432817555443e-001, -1.077956399281471e-003, 8.911620591248875e+000, #if MOON 6.010848314829119e-004, -8.081772358351251e-004, -1.674454691500606e-004, -1.994630037441996e-003, -8.556208109904861e-005, -1.087262721620868e-003, #endif -3.524457445683394e-007, /* Sun */ 4.504795855674601e-003, 5.177637780672221e-006, 7.732544746890742e-004, 2.229113252400401e-006, 2.685039985573271e-004 }; /* Julian date of the state yn1[]: */ #define JD1 2440500.50 static double yn1[] = { -2.457085900366332e-002, 2.381597794693489e-001, 1.851778146680485e-002, 1.996323209474686e-001, 1.244039124191612e-002, 8.216842968554781e-002, -1.619513532964599e-002, -4.288838589850871e-001, -1.160656795724704e-002, 5.131125475173164e-001, -4.195286108659672e-003, 2.581368657564266e-001, -4.148833933015173e-003, 9.784941438766318e-001, 1.532745170011609e-002, 2.074410311959717e-001, 6.646462310684277e-003, 8.989091702317244e-002, 8.350422878366247e-003, 1.151108827619137e+000, 1.172723634265029e-002, -6.894717355437423e-001, 5.152260844982779e-003, -3.474143803147213e-001, 2.061461649176091e-003, -5.221785914203378e+000, -6.307486608326940e-003, -1.472733759859347e+000, -2.754121811344123e-003, -5.039994787357370e-001, -3.506509603502537e-003, 7.558106559699063e+000, 4.155902532833776e-003, 5.021213850462841e+000, 1.866781421893536e-003, 1.748532556433840e+000, 3.093738240936483e-004, -1.823885644320201e+001, -3.755962489549436e-003, -1.537896840580550e+000, -1.649410160709415e-003, -4.151358646421778e-001, 2.659694712570950e-003, -1.578987378978514e+001, -1.472781001534497e-003, -2.409072389641744e+001, -6.690116571980626e-004, -9.467562384490781e+000, 3.504107115900905e-004, -3.044986307301521e+001, -3.142629755658865e-003, -1.186756347889178e+000, -1.086164460786462e-003, 8.803414050220775e+000, #if MOON -4.181662799524538e-004, -1.749747307712349e-003, -3.263107309648734e-004, 1.807047780153076e-003, -1.847196922506988e-004, 9.595533885666276e-004, #endif -1.063378525544779e-006, 4.434825780648206e-003, 5.049061922605073e-006, 1.283313197720549e-003, 2.188756349489559e-006, 4.887462262250162e-004 }; /* Earth's mass divided by Moon's mass */ #define EMRAT 81.300587 /* GM's of the solar system bodies * These are scaled such that GMsun = k^2 * (k = Gaussian gravitational constant). */ double GMs[] = { 4.912547451450812e-011, /* Mercury */ 7.243456209632766e-010, /* Venus */ #if MOON (8.997011658557308e-010*EMRAT)/(1.0+EMRAT), /* Earth */ #else 8.997011658557308e-010, /* EMB */ #endif 9.549528942224058e-011, /* Mars */ 2.825342103445926e-007, /* Jupiter */ 8.459468504830660e-008, /* Saturn */ 1.288816238138035e-008, /* Uranus */ 1.532112481284276e-008, /* Neptune */ 2.276247751863699e-012, /* Pluto */ #if MOON (8.997011658557308e-010)/(1.0+EMRAT), /* Moon */ #endif 2.959122082855911e-004 /* Sun */ }; /******************************************************************************/ int main ( ) /******************************************************************************/ { double t, err, h; int i, ii, j, nsteps, ord; double adstep(); orlup: printf ( "Adams order ? " ); scanf( "%d", &ord ); if( (ord > MAXORD) || (ord < 1) ) { printf( "order must be between 1 and %d\n", MAXORD ); goto orlup; } printf( "step size, days ? " ); scanf( "%lf", &h ); printf( "Number of steps ? " ); scanf( "%d", &nsteps ); for( i=0; i<((MAXRUNG+2)*NEQ); i++ ) rwork[i] = 0.0; printf( "initializing...\n" ); t = JD0; err = 0.0; rkstart( NEQ, rwork ); adstart( h, yn, awork, NEQ, ord, t ); printf( "initialized.\n" ); for( j=1; j<=nsteps; j++ ) { err += adstep( &t, yn, NEQC ); printf( "%5d %11.2lf %.3e\n", j, t, err ); } printf( "Final x, y, z, positions and errors:\n" ); ii = 0; for (i=0; i