/** \file $Id: lunar.c,v 1.7 2004/02/13 22:58:57 rauch Exp $ \srclevel ISO C \mtlevel TBD \author Kevin P. Rauch \brief A simple custom driver adding the mean lunar quadrupole. This custom driver includes the extra kick and energy due to the Sun's attraction on the mean Earth-Moon quadrupole, as derived by Quinn, Duncan, & Tremaine (1991). If \c QTD_DRIVER is defined, the expansion of the lunar orbit due to tidal dissipation is included and the standard correction factor \a f = 0.9473 is used. This fully duplicates the Quinn et al. calculation. Otherwise (and by default), the dissipation is neglected (it is useful mainly when Earth-Moon rigid body dynamics are being calculated, and it also breaks energy conservation at the rate of 1e-13 per Myr), and the correction \a f = 0.8525 is used. The latter was found by Varadi, Runnegar, & Ghil (2003) to minimize long-term errors in Earth's orbital elements (note that this turns out to be at the expense of short-term accuracy, however.) \return EXIT_SUCCESS on success, else EXIT_FAILURE. \see hnb_argv_driver() */ #include #include void lunar_version(FILE *f, const char *prefix) { #ifdef QTD_DRIVER hnb_util_version(f, "QTD driver", "$Revision: 1.7 $", prefix); #else hnb_util_version(f, "Lunar driver", "$Revision: 1.7 $", prefix); #endif } static double lunar_scalar(double t, double GM) { /* R is mean Earth-Moon distance, in AU; t is the Julian day number. */ #ifdef QTD_DRIVER double f=0.9473, R=0.0025696*(1+2.65e-13*(t-2433280.5)); #else double f=0.8525, R=0.0025696; #endif return(0.25*GM*R*R*f/(2+81.3007+1/81.3007)); } void lunar_kick(double (*dv)[3], double t, double (*x)[3], const double m[], int nHL, int n, double dt, const hnb_data_t *sys) { /* Extra force due to the attraction of the Sun on Earth-Moon quadrupole. dv[] holds the velocity impulse, (dv/dt)*dt, and may contain partial impulse sums on input; always update (rather than overwrite) its contents. This routine assumes the Earth-Moon barycenter is index 3, and that lengths are in AU and times in days (if QTD is defined, t must be the Julian Day number, in fact). */ const double G=hnb_G(sys), *xe=x[3]; double x0=xe[0], x1=xe[1], x2=xe[2], ir=1/sqrt(x0*x0+x1*x1+x2*x2), *dve, fac=dt*3*lunar_scalar(t, G*m[0])*ir*ir*ir*ir*ir; dve=dv[3]; dve[0]-=fac*x0; dve[1]-=fac*x1; dve[2]-=fac*x2; } double lunar_energy(double t, double (*x)[3], double (*v)[3], const double m[], int nNL, const hnb_data_t *sys) { /* Compute extra potential energy associated with lunar_kick(). */ const double G=hnb_G(sys), *xe=x[3]; double ire=1/sqrt(xe[0]*xe[0]+xe[1]*xe[1]+xe[2]*xe[2]), fac=m[3]*lunar_scalar(t, G*m[0])*ire*ire*ire; return(-fac); } int main(int argc, char *argv[]) { exit(hnb_argv_driver(argc, argv, lunar_kick, NULL, NULL, NULL, lunar_energy, lunar_version)); }