VSOP87 full set and data pointers

This commit is contained in:
Gustavo A. Corradi 2022-12-30 08:28:35 -03:00
parent 0a1b50503b
commit 65bc8e7a45
14 changed files with 32128 additions and 88 deletions

View File

@ -80,7 +80,14 @@ OBJS = \
umoon.o \
twobody.o \
vsop87.o \
vsop87_data.o
vsop87_ear.o \
vsop87_jup.o \
vsop87_mar.o \
vsop87_mer.o \
vsop87_nep.o \
vsop87_sat.o \
vsop87_ura.o \
vsop87_ven.o
libastro.a: $(HS) $(OBJS)
ar rv $@ $(OBJS)

View File

@ -808,7 +808,7 @@ extern void utc_gst (double m, double utc, double *gst);
extern void gst_utc (double m, double gst, double *utc);
/* vsop87.c */
extern int vsop87 (double m, int obj, double prec, double *ret);
extern int vsop87 (double m, int obj, double *ret);
#endif /* _ASTRO_H */

View File

@ -10,7 +10,7 @@
static void pluto_ell (double mj, double *ret);
static void chap_trans (double mj, double *ret);
static void planpos (double mj, int obj, double prec, double *ret);
static void planpos (double mj, int obj, double *ret);
/* coordinate transformation
* from:
@ -79,18 +79,18 @@ double *ret) /* ecliptic coordinates {l,b,r} at equinox of date */
* (not corrected for light-time)
*/
static void
planpos (double mj, int obj, double prec, double *ret)
planpos (double mj, int obj, double *ret)
{
if (mj >= CHAP_BEGIN && mj <= CHAP_END) {
if (obj >= JUPITER) { /* prefer Chapront */
chap95(mj, obj, prec, ret);
chap95(mj, obj, 0.0, ret);
chap_trans (mj, ret);
} else { /* VSOP for inner planets */
vsop87(mj, obj, prec, ret);
vsop87(mj, obj, ret);
}
} else { /* outside Chapront time: */
if (obj != PLUTO) { /* VSOP for all but Pluto */
vsop87(mj, obj, prec, ret);
vsop87(mj, obj, ret);
} else { /* Pluto mean elliptic orbit */
pluto_ell(mj, ret);
}
@ -175,7 +175,7 @@ double *rho0, double *lam, double *bet, double *dia, double *mag)
* retarded for light time in second pass;
* alternative option: vsop allows calculating rates.
*/
planpos(mj - dt, p, 0.0, ret);
planpos(mj - dt, p, ret);
lp = ret[0];
bp = ret[1];

View File

@ -27,7 +27,7 @@ sunpos (double mj, double *lsn, double *rsn, double *bsn)
return;
}
vsop87(mj, SUN, 0.0, ret); /* full precision earth pos */
vsop87(mj, SUN, ret); /* full precision earth pos */
*lsn = ret[0] - PI; /* revert to sun pos */
range (lsn, 2*PI); /* normalise */

View File

@ -94,79 +94,67 @@
* return: error index (int)
* 0: no error.
* 2: object out of range [MERCURY .. NEPTUNE, SUN]
* 3: precision out of range [0.0 .. 1e-3]
******************************************************************/
int
vsop87 (double mj, int obj, double prec, double *ret)
{
static double (*vx_map[])[3] = { /* data tables */
vx_mercury, vx_venus, vx_mars, vx_jupiter,
vx_saturn, vx_uranus, vx_neptune, 0, vx_earth,
};
static int (*vn_map[])[3] = { /* indexes */
vn_mercury, vn_venus, vn_mars, vn_jupiter,
vn_saturn, vn_uranus, vn_neptune, 0, vn_earth,
};
static double a0[] = { /* semimajor axes; for precision ctrl only */
0.39, 0.72, 1.5, 5.2, 9.6, 19.2, 30.1, 39.5, 1.0,
};
double (*vx_obj)[3] = vx_map[obj]; /* VSOP87 data and indexes */
int (*vn_obj)[3] = vn_map[obj];
/******************************************************************
* added entire vsop87 data set (31577 terms)
* change use of indexes for pointers
* delete VSOP_SCALE macro
* delete precision control as always called with 0 (full precision)
* Gustavo A. Corradi - Dec - 2022 (gcorrad@gmail.com)
******************************************************************/
extern t_vsop87v
*mercury_vs[], *venus_vs[], *mars_vs[], *jupiter_vs[],
*saturn_vs[], *uranus_vs[], *neptune_vs[], *earth_vs[];
int
vsop87 (double mj, int obj, double *ret)
{
static t_vsop87v **map_obj[] = {
mercury_vs, venus_vs, mars_vs, jupiter_vs,
saturn_vs, uranus_vs, neptune_vs, 0, earth_vs,
};
double t[VSOP_MAXALPHA+1]; /* powers of time */
double t_abs[VSOP_MAXALPHA+1]; /* powers of abs(time) */
double q; /* aux for precision control */
int i, cooidx, alpha; /* misc indexes */
double term, arg, mj0;
#if VSOP_GETRATE
double termdot;
#endif
t_vsop87 *p; /* VSOP87 term pointer */
t_vsop87v *pp, **vsp; /* VSOP87 variable and planet pointer */
int i, cooidx, alpha, maxt; /* misc indexes */
if (obj == PLUTO || obj > SUN)
return (2);
if (prec < 0.0 || prec > 1e-3)
return(3);
return (2);
vsp = map_obj[obj];
/* zero result array */
for (i = 0; i < 6; ++i) ret[i] = 0.0;
/* time and its powers */
mj0 = (mj - J2000)/VSOP_A1000;
t[0] = 1.0;
t[1] = (mj - J2000)/VSOP_A1000;
for (i = 2; i <= VSOP_MAXALPHA; ++i) t[i] = t[i-1] * t[1];
t_abs[0] = 1.0;
for (i = 1; i <= VSOP_MAXALPHA; ++i) t_abs[i] = fabs(t[i]);
/* precision control */
q = -log10(prec + 1e-35) - 2; /* decades below 1e-2 */
q = VSOP_ASCALE * prec / 10.0 / q; /* reduce threshold progressively
* for higher precision */
t[1] = mj0;
for (i = 2; i <= VSOP_MAXALPHA; ++i) t[i] = t[i-1] * mj0;
/* do the term summation; first the spatial dimensions */
for (cooidx = 0; cooidx < 3; ++cooidx) {
/* then the powers of time */
for (alpha = 0; vn_obj[alpha+1][cooidx] ; ++alpha) {
double p, term, termdot;
/* then the powers of time */
pp = vsp[cooidx];
for (alpha = 0; pp->vars; ++alpha, ++pp) {
/* precision threshold */
p= alpha ? q/(t_abs[alpha] + alpha*t_abs[alpha-1]*1e-4 + 1e-35) : q;
#if VSOP_SPHERICAL
if (cooidx == 2) /* scale by semimajor axis for radius */
#endif
p *= a0[obj];
term = termdot = 0.0;
for (i = vn_obj[alpha][cooidx]; i < vn_obj[alpha+1][cooidx]; ++i) {
double a, b, c, arg;
a = vx_obj[i][0];
if (a < p) continue; /* ignore small terms */
b = vx_obj[i][1];
c = vx_obj[i][2];
arg = b + c * t[1];
term += a * cos(arg);
maxt = pp->maxt;
p = pp->vars;
term = 0.0;
#if VSOP_GETRATE
termdot += -c * a * sin(arg);
termdot = 0.0;
#endif
for (i = 0; i < maxt; ++i, ++p) {
arg = p->B + p->r * mj0;
term += p->L * cos(arg);
#if VSOP_GETRATE
termdot += -p->r * p->L * sin(arg);
#endif
}
@ -178,8 +166,6 @@ vsop87 (double mj, int obj, double prec, double *ret)
} /* alpha */
} /* cooidx */
for (i = 0; i < 6; ++i) ret[i] /= VSOP_ASCALE;
#if VSOP_SPHERICAL
/* reduce longitude to 0..2pi */
ret[0] -= floor(ret[0]/(2.*PI)) * (2.*PI);
@ -193,7 +179,7 @@ vsop87 (double mj, int obj, double prec, double *ret)
#if VSOP_SPHERICAL
/* reduction from dynamical equinox of VSOP87 to FK5;
*/
if (prec < 5e-7) { /* 5e-7 rad = 0.1 arc seconds */
{
double L1, c1, s1;
L1 = ret[0] - degrad(13.97 * t[1] - 0.031 * t[2]);
c1 = cos(L1); s1 = sin(L1);

View File

@ -1,5 +1,5 @@
/* Position of planets mercury to neptune; from:
ftp://ftp.bdl.fr/pub/ephem/planets/vsop87/
ftp://ftp.imcce.fr/pub/ephem/planets/vsop87/
from README:
========================== ===========================
@ -60,31 +60,33 @@ reports to: E-mail : comments@bdl.fr
==============================================================================
implemented for C: stern
*/
/******************************************************************
* added entire vsop87 data set (31577 terms)
* change use of indexes for pointers
* delete VSOP_SCALE macro
* delete precision control as always called with 0 (full precision)
* Gustavo A. Corradi - Dec - 2022 (gcorrad@gmail.com)
******************************************************************/
#define VSOP_ASCALE 1e8 /* amplitude factor as stored */
#ifndef _VSOP87_H_
#define _VSOP87_H_
/* coding flags */
#define VSOP_SPHERICAL 1 /* version in data.c uses spherical coords */
#define VSOP_GETRATE 0 /* calculate time derivatives of coordinates */
/* data tables */
extern double vx_mercury[][3];
extern int vn_mercury[][3];
extern double vx_venus[][3];
extern int vn_venus[][3];
extern double vx_earth[][3];
extern int vn_earth[][3];
extern double vx_mars[][3];
extern int vn_mars[][3];
extern double vx_jupiter[][3];
extern int vn_jupiter[][3];
extern double vx_saturn[][3];
extern int vn_saturn[][3];
extern double vx_uranus[][3];
extern int vn_uranus[][3];
extern double vx_neptune[][3];
extern int vn_neptune[][3];
extern int vsop87 (double mj, int obj, double prec, double *ret);
typedef struct s_vsop87 {
double L;
double B;
double r;
} t_vsop87;
typedef struct s_vsop87v {
t_vsop87 *vars;
int maxt;
} t_vsop87v;
extern int vsop87 (double mj, int obj, double *ret);
#endif /* _VSOP87_H_ */

2482
libastro/vsop87_ear.c Normal file

File diff suppressed because it is too large Load Diff

3543
libastro/vsop87_jup.c Normal file

File diff suppressed because it is too large Load Diff

5543
libastro/vsop87_mar.c Normal file

File diff suppressed because it is too large Load Diff

6887
libastro/vsop87_mer.c Normal file

File diff suppressed because it is too large Load Diff

1986
libastro/vsop87_nep.c Normal file

File diff suppressed because it is too large Load Diff

5819
libastro/vsop87_sat.c Normal file

File diff suppressed because it is too large Load Diff

4043
libastro/vsop87_ura.c Normal file

File diff suppressed because it is too large Load Diff

1742
libastro/vsop87_ven.c Normal file

File diff suppressed because it is too large Load Diff