00001
00002
00003
00004
00005 #ifndef LOCAL_SOLEPHEM_INCL
00006 #define LOCAL_SOLEPHEM_INCL
00007 #endif
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #define EPS 3.e-17
00022 static double ecanom (double e, double manom) {
00023 int i;
00024 double ecm_new, ecm_old;
00025
00026 ecm_old = manom + e*sin(manom);
00027 i = 0;
00028 for (;;) {
00029 ++i;
00030 ecm_new = ecm_old - (ecm_old - manom - e * sin( ecm_old)) /
00031 (1 - e * cos( ecm_old));
00032 if (fabs((ecm_new - ecm_old)/(ecm_new + ecm_old)) < EPS ||
00033 fabs((ecm_new - ecm_old)) < EPS ) break;
00034 ecm_old = ecm_new;
00035 if (i > 16) {
00036 fprintf (stderr, "ecanom: excessive iterations: %d\nold,new", i);
00037 fprintf (stderr, " %g %g %g\n", ecm_old, ecm_new, ecm_new-ecm_old);
00038 break;
00039 }
00040 }
00041 return (ecm_new);
00042 }
00043
00044 #define EPHEM_OFFSET (-11865398400.0)
00045
00046 #define EPHEM_SIZE 35
00047
00048 #define EPHEM_T 1
00049 #define EPHEM_TCENT 2
00050 #define EPHEM_JD 3
00051 #define EPHEM_ST 4
00052 #define EPHEM_RA 5
00053 #define EPHEM_DEC 6
00054 #define EPHEM_CLONG 7
00055 #define EPHEM_L0 8
00056 #define EPHEM_B0 9
00057 #define EPHEM_P 10
00058
00059 #define EPHEM_DIST 11
00060 #define EPHEM_RSUN 12
00061 #define EPHEM_VEARTH 13
00062 #define EPHEM_EOT 14
00063 #define EPHEM_B0V 15
00064 #define EPHEM_PHI 16
00065 #define EPHEM_SINP 17
00066 #define EPHEM_COSP 18
00067 #define EPHEM_PAROT 19
00068
00069 #define EPHEM_RHO 20
00070 #define EPHEM_L 21
00071 #define EPHEM_B 22
00072 #define EPHEM_R 23
00073 #define EPHEM_SECZ 24
00074 #define EPHEM_SINL 25
00075 #define EPHEM_SINB 26
00076
00077 #define EPHEM_IA 27
00078 #define EPHEM_LD 28
00079 #define EPHEM_AIRM 29
00080 #define EPHEM_DV 30
00081
00082 #define EPHEM_OBS_LON 31
00083 #define EPHEM_OBS_LAT 32
00084
00085
00086 static void solephem (double time, double *ephem) {
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 double dwork1, dwork2, dsd;
00135 long year,modsd,ly,sd,doy;
00136 double tenths,tenths_sid_mean,tt;
00137 double days_1900,t,mean_sid_time,hams,rams,ra,lo,eot,pi,two_pi,
00138 clong,omega,xx,xs,xc,cosclo,b0,l0,l00,perigee,e,rday,
00139 clong_omega,p,r,rsun,sinincl,cosincl,tanincl,
00140 sinb0,dec,g,ge,v,eps,y;
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 pi=3.14159265358979324;
00151 two_pi=6.28318530717995865;
00152 rday=two_pi/864000;
00153
00154
00155
00156 sinincl = 0.126198969135829761;
00157 cosincl = 0.992004949679714999;
00158 tanincl = 0.127216068001046929;
00159
00160
00161
00162
00163
00164 tenths = modf((double)time/86400.0, &dsd);
00165 sd = dsd;
00166 tenths *= 864000.0;
00167
00168 modf((double)sd/36524.0, &dwork1);
00169 modf((double)sd/146096.0, &dwork2);
00170 modsd = (long)(sd + dwork1 - dwork2);
00171 ly=modsd/1461;
00172 dwork1 = (modsd+1-1461*ly)/365.3;
00173 if(dwork1 < 0)
00174 {
00175 modf(fabs(dwork1), &dwork1);
00176 dwork1 = -1.0 - dwork1;
00177 }
00178 else
00179 modf(dwork1, &dwork1);
00180 year=4*ly+dwork1;
00181 modf((double)(year*365.25), &dwork1);
00182 doy= modsd + 1 - dwork1;
00183 year=1601+year;
00184
00185
00186
00187
00188
00189
00190 days_1900=dsd-109206.0-0.5;
00191
00192 t=days_1900/36525.0;
00193 tt = t + tenths/(864000.0*36525.0);
00194
00195 e = 0.01675104 - tt*(4.18e-5 + 1.26e-7*tt);
00196
00197 eps = 0.40931975520272993 - tt*(2.271109689158e-4 +
00198 tt*(2.86040072e-8 - tt*8.7751276e-9));
00199
00200 perigee=4.90822946686888692 + tt*( 3.000526416797e-2 +
00201 tt*( 7.9024630021e-6 + tt*5.81776417e-8));
00202
00203 lo = 4.8815279341118791 + tt*(628.33195094248177 + 5.2796209873e-6*tt);
00204
00205
00206 y = tan( (double)(eps/2.0) );
00207 y = y*y;
00208
00209 tenths_sid_mean=239258.36+86401845.42*t+
00210 0.929*t*t+1.0027379093*tenths;
00211
00212 mean_sid_time = two_pi*modf(tenths_sid_mean/864000.0, &dwork2);
00213
00214 hams=(tenths-432000.0)*rday; if( hams < 0 ) hams=hams+two_pi;
00215
00216 rams=mean_sid_time-hams; if( rams < 0 ) rams=rams+two_pi;
00217
00218 g = lo - perigee;
00219
00220 ge = ecanom(e, g);
00221
00222 v = 2.0*atan(sqrt((1.0+e)/(1.0-e))*tan(0.5*ge));
00223
00224 clong = v + perigee;
00225 if(clong > two_pi)clong -= two_pi;
00226 else if (clong < 0)clong += two_pi;
00227
00228 ra = atan2( (1.0-y)*sin(clong),(1+y)*cos(clong));
00229 if(ra < 0)ra += two_pi;
00230
00231 eot = rams - ra;
00232 if(eot > pi)eot -= two_pi;
00233 else if(eot < -pi)eot += two_pi;
00234
00235 dec = asin(sin(eps)*sin(clong));
00236
00237 omega=1.2857258823024895+2.436188747575e-4*(time-7857648000.0)/3.15576e7;
00238
00239 clong_omega=clong-omega;
00240 if( clong_omega < 0 )
00241 clong_omega= clong_omega+two_pi;
00242 else if( clong_omega >= two_pi)
00243 clong_omega= clong_omega-two_pi;
00244 xs=sin(clong_omega); xc= cos(clong_omega);
00245 cosclo = xc= cos(clong_omega);
00246
00247 sinb0= xs*sinincl;
00248 b0 = asin(sinb0);
00249
00250
00251
00252 l00 = atan2(-xs*cosincl,-xc)+5.1097298952004202 + 0.247564432906997103
00253 * (2430000.5 - 2415020.0 - days_1900 - (tenths/864000.0));
00254 l00 = modf(l00/two_pi, &dwork1);
00255 l00 *= two_pi;
00256 if(l00 < 0)l00 += two_pi;
00257 xx = xc * sinincl;
00258
00259
00260
00261
00262
00263
00264
00265 l0= (time - 7983921600.0)/(25.38*86400.0)
00266
00267 + 2.5 - clong_omega/two_pi - (year-1854);
00268 if( doy>90 && clong>omega ) l0=l0-1;
00269
00270 dwork1 = l0;
00271 modf(l0, &l0);
00272 l0 = l0 + (two_pi - l00)/two_pi;
00273
00274 if (dwork1 - l0 > 0.9) l0 = l0 + 1.0;
00275 else if (l0 - dwork1 > 0.9) l0 = l0 - 1.0;
00276
00277
00278
00279 p=atan(-tan(eps)*cos(clong))+atan(-tanincl*xc);
00280 xc=cos(clong-perigee);
00281 r=(1.0-e*e)/(1.0+e*xc);
00282 rsun=959.63/r;
00283
00284 ephem[EPHEM_T] = time;
00285 ephem[EPHEM_TCENT] = t;
00286 ephem[EPHEM_JD] = 2415020.0 + days_1900;
00287 ephem[EPHEM_ST] = mean_sid_time;
00288 ephem[EPHEM_RA] = ra;
00289 ephem[EPHEM_DEC] = dec;
00290 ephem[EPHEM_CLONG] = clong;
00291 ephem[EPHEM_L0] = l0*360;
00292 ephem[EPHEM_B0] = b0;
00293 ephem[EPHEM_P] = p;
00294 ephem[EPHEM_DIST] = r;
00295 ephem[EPHEM_RSUN] = rsun;
00296 ephem[EPHEM_VEARTH] = 29785.9*(1+e*xc);
00297
00298
00299 ephem[EPHEM_EOT] = eot;
00300
00301
00302
00303
00304
00305
00306
00307 ephem[EPHEM_B0V] = xx * ephem[EPHEM_VEARTH];
00308 ephem[EPHEM_PHI] = atan (0.4336*cos(clong)+p);
00309 ephem[EPHEM_SINP] = sin (p);
00310 ephem[EPHEM_COSP] = cos (p);
00311 ephem[EPHEM_PAROT] = atan (-tanincl*cosclo);
00312 return;
00313 }
00314
00315 static void calc_sun_ephemeris (TIME time, double ephem[], double obs_lon, double obs_lat) {
00316 solephem (time - EPHEM_OFFSET, ephem);
00317 ephem[EPHEM_OBS_LON] = obs_lon * M_PI / 180.0;
00318 ephem[EPHEM_OBS_LAT] = obs_lat * M_PI / 180.0;
00319 }
00320