1 | #include "slalib.h"
|
---|
2 | #include "slamac.h"
|
---|
3 | void slaUe2pv ( double date, double u[], double pv[], int *jstat )
|
---|
4 | /*
|
---|
5 | ** - - - - - - - - -
|
---|
6 | ** s l a U e 2 p v
|
---|
7 | ** - - - - - - - - -
|
---|
8 | **
|
---|
9 | ** Heliocentric position and velocity of a planet, asteroid or comet,
|
---|
10 | ** starting from orbital elements in the "universal variables" form.
|
---|
11 | **
|
---|
12 | ** Given:
|
---|
13 | ** date double date, Modified Julian Date (JD-2400000.5)
|
---|
14 | **
|
---|
15 | ** Given and returned:
|
---|
16 | ** u double[13] universal orbital elements (updated; Note 1)
|
---|
17 | **
|
---|
18 | ** given [0] combined mass (M+m)
|
---|
19 | ** " [1] total energy of the orbit (alpha)
|
---|
20 | ** " [2] reference (osculating) epoch (t0)
|
---|
21 | ** " [3-5] position at reference epoch (r0)
|
---|
22 | ** " [6-8] velocity at reference epoch (v0)
|
---|
23 | ** " [9] heliocentric distance at reference epoch
|
---|
24 | ** " [10] r0.v0
|
---|
25 | ** returned [11] date (t)
|
---|
26 | ** " [12] universal eccentric anomaly (psi) of date, approx
|
---|
27 | **
|
---|
28 | ** Returned:
|
---|
29 | ** pv double[6] position (AU) and velocity (AU/s)
|
---|
30 | ** jstat int* status: 0 = OK
|
---|
31 | ** -1 = radius vector zero
|
---|
32 | ** -2 = failed to converge
|
---|
33 | **
|
---|
34 | ** Notes
|
---|
35 | **
|
---|
36 | ** 1 The "universal" elements are those which define the orbit for the
|
---|
37 | ** purposes of the method of universal variables (see reference).
|
---|
38 | ** They consist of the combined mass of the two bodies, an epoch,
|
---|
39 | ** and the position and velocity vectors (arbitrary reference frame)
|
---|
40 | ** at that epoch. The parameter set used here includes also various
|
---|
41 | ** quantities that can, in fact, be derived from the other
|
---|
42 | ** information. This approach is taken to avoiding unnecessary
|
---|
43 | ** computation and loss of accuracy. The supplementary quantities
|
---|
44 | ** are (i) alpha, which is proportional to the total energy of the
|
---|
45 | ** orbit, (ii) the heliocentric distance at epoch, (iii) the
|
---|
46 | ** outwards component of the velocity at the given epoch, (iv) an
|
---|
47 | ** estimate of psi, the "universal eccentric anomaly" at a given
|
---|
48 | ** date and (v) that date.
|
---|
49 | **
|
---|
50 | ** 2 The companion routine is slaEl2ue. This takes the conventional
|
---|
51 | ** orbital elements and transforms them into the set of numbers
|
---|
52 | ** needed by the present routine. A single prediction requires one
|
---|
53 | ** one call to slaEl2ue followed by one call to the present routine;
|
---|
54 | ** for convenience, the two calls are packaged as the routine
|
---|
55 | ** slaPlanel. Multiple predictions may be made by again calling
|
---|
56 | ** slaEl2ue once, but then calling the present routine multiple times,
|
---|
57 | ** which is faster than multiple calls to slaPlanel.
|
---|
58 | **
|
---|
59 | ** It is not obligatory to use slaEl2ue to obtain the parameters.
|
---|
60 | ** However, it should be noted that because slaEl2ue performs its
|
---|
61 | ** own validation, no checks on the contents of the array U are made
|
---|
62 | ** by the present routine.
|
---|
63 | **
|
---|
64 | ** 3 date is the instant for which the prediction is required. It is
|
---|
65 | ** in the TT timescale (formerly Ephemeris Time, ET) and is a
|
---|
66 | ** Modified Julian Date (JD-2400000.5).
|
---|
67 | **
|
---|
68 | ** 4 The universal elements supplied in the array u are in canonical
|
---|
69 | ** units (solar masses, AU and canonical days). The position and
|
---|
70 | ** velocity are not sensitive to the choice of reference frame. The
|
---|
71 | ** slaEl2ue routine in fact produces coordinates with respect to the
|
---|
72 | ** J2000 equator and equinox.
|
---|
73 | **
|
---|
74 | ** 5 The algorithm was originally adapted from the EPHSLA program of
|
---|
75 | ** D.H.P.Jones (private communication, 1996). The method is based
|
---|
76 | ** on Stumpff's Universal Variables.
|
---|
77 | **
|
---|
78 | ** Reference: Everhart, E. & Pitkin, E.T., Am.J.Phys. 51, 712, 1983.
|
---|
79 | **
|
---|
80 | ** Last revision: 19 March 1999
|
---|
81 | **
|
---|
82 | ** Copyright P.T.Wallace. All rights reserved.
|
---|
83 | */
|
---|
84 |
|
---|
85 | /* Gaussian gravitational constant (exact) */
|
---|
86 | #define GCON 0.01720209895
|
---|
87 |
|
---|
88 | /* Canonical days to seconds */
|
---|
89 | #define CD2S ( GCON / 86400.0 )
|
---|
90 |
|
---|
91 | /* Test value for solution and maximum number of iterations */
|
---|
92 | #define TEST 1e-13
|
---|
93 | #define NITMAX 20
|
---|
94 |
|
---|
95 | {
|
---|
96 | int i, nit, n;
|
---|
97 | double cm, alpha, t0, p0[3], v0[3], r0, sigma0, t, psi, dt, w,
|
---|
98 | tol, psj, psj2, beta, s0, s1, s2, s3, ff, r, f, g, fd, gd;
|
---|
99 |
|
---|
100 |
|
---|
101 |
|
---|
102 | /* Unpack the parameters. */
|
---|
103 | cm = u[0];
|
---|
104 | alpha = u[1];
|
---|
105 | t0 = u[2];
|
---|
106 | for ( i = 0; i < 3; i++ ) {
|
---|
107 | p0[i] = u[i+3];
|
---|
108 | v0[i] = u[i+6];
|
---|
109 | }
|
---|
110 | r0 = u[9];
|
---|
111 | sigma0 = u[10];
|
---|
112 | t = u[11];
|
---|
113 | psi = u[12];
|
---|
114 |
|
---|
115 | /* Approximately update the universal eccentric anomaly. */
|
---|
116 | psi = psi + ( date - t ) * GCON / r0;
|
---|
117 |
|
---|
118 | /* Time from reference epoch to date (in Canonical Days: a canonical */
|
---|
119 | /* day is 58.1324409... days, defined as 1/GCON). */
|
---|
120 | dt = ( date - t0 ) * GCON;
|
---|
121 |
|
---|
122 | /* Refine the universal eccentric anomaly. */
|
---|
123 | nit = 1;
|
---|
124 | w = 1.0;
|
---|
125 | tol = 0.0;
|
---|
126 | while ( fabs ( w ) >= tol ) {
|
---|
127 |
|
---|
128 | /* Form half angles until BETA small enough. */
|
---|
129 | n = 0;
|
---|
130 | psj = psi;
|
---|
131 | psj2 = psj * psj;
|
---|
132 | beta = alpha * psj2;
|
---|
133 | while ( fabs ( beta ) > 0.7 ) {
|
---|
134 | n++;
|
---|
135 | beta /= 4.0;
|
---|
136 | psj /= 2.0;
|
---|
137 | psj2 /= 4.0;
|
---|
138 | }
|
---|
139 |
|
---|
140 | /* Calculate Universal Variables S0,S1,S2,S3 by nested series. */
|
---|
141 | s3 = psj * psj2 * ( ( ( ( ( ( beta / 210.0 + 1.0 )
|
---|
142 | * beta / 156.0 + 1.0 )
|
---|
143 | * beta / 110.0 + 1.0 )
|
---|
144 | * beta / 72.0 + 1.0 )
|
---|
145 | * beta / 42.0 + 1.0 )
|
---|
146 | * beta / 20.0 + 1.0 ) / 6.0;
|
---|
147 | s2 = psj2 * ( ( ( ( ( ( beta / 182.0 + 1.0 )
|
---|
148 | * beta / 132.0 + 1.0 )
|
---|
149 | * beta / 90.0 + 1.0 )
|
---|
150 | * beta / 56.0 + 1.0 )
|
---|
151 | * beta / 30.0 + 1.0 )
|
---|
152 | * beta / 12.0 + 1.0 ) / 2.0;
|
---|
153 | s1 = psj + alpha * s3;
|
---|
154 | s0 = 1.0 + alpha * s2;
|
---|
155 |
|
---|
156 | /* Undo the angle-halving. */
|
---|
157 | tol = TEST;
|
---|
158 | while ( n > 0 ) {
|
---|
159 | s3 = 2.0 * ( s0 * s3 + psj * s2 );
|
---|
160 | s2 = 2.0 * s1 * s1;
|
---|
161 | s1 = 2.0 * s0 * s1;
|
---|
162 | s0 = 2.0 * s0 * s0 - 1.0;
|
---|
163 | psj += psj;
|
---|
164 | tol += tol;
|
---|
165 | n--;
|
---|
166 | }
|
---|
167 |
|
---|
168 | /* Improve the approximation to psi. */
|
---|
169 | ff = r0 * s1 + sigma0 * s2 + cm * s3 - dt;
|
---|
170 | r = r0 * s0 + sigma0 * s1 + cm * s2;
|
---|
171 | if ( r == 0.0 ) {
|
---|
172 | *jstat = -1;
|
---|
173 | return;
|
---|
174 | }
|
---|
175 | w = ff / r;
|
---|
176 | psi -= w;
|
---|
177 |
|
---|
178 | /* Next iteration, unless too many already. */
|
---|
179 | if ( nit >= NITMAX ) {
|
---|
180 | *jstat = -2;
|
---|
181 | return;
|
---|
182 | }
|
---|
183 | nit++;
|
---|
184 | }
|
---|
185 |
|
---|
186 | /* Project the position and velocity vectors (scaling velocity to AU/s). */
|
---|
187 | w = cm * s2;
|
---|
188 | f = 1.0 - w / r0;
|
---|
189 | g = dt - cm * s3;
|
---|
190 | fd = - cm * s1 / ( r0 * r );
|
---|
191 | gd = 1.0 - w / r;
|
---|
192 | for ( i = 0; i < 3; i++ ) {
|
---|
193 | pv[i] = p0[i] * f + v0[i] * g;
|
---|
194 | pv[i+3] = CD2S * ( p0[i] * fd + v0[i] * gd );
|
---|
195 | }
|
---|
196 |
|
---|
197 | /* Update the parameters to allow speedy prediction of psi next time. */
|
---|
198 | u[11] = date;
|
---|
199 | u[12] = psi;
|
---|
200 |
|
---|
201 | /* OK exit. */
|
---|
202 | *jstat = 0;
|
---|
203 |
|
---|
204 | }
|
---|