libTheSky
Routines to compute sky positions of Sun, Moon, planets and more
All Namespaces Files Functions Variables Pages
asteroids.f90
Go to the documentation of this file.
1!> \file asteroids.f90 Procedures to compute asteroid positions and more for libTheSky
2
3
4! Copyright (c) 2002-2025 Marc van der Sluys - Nikhef/Utrecht University - marc.vandersluys.nl
5!
6! This file is part of the libTheSky package,
7! see: https://libthesky.sf.net/
8!
9! This is free software: you can redistribute it and/or modify it under the terms of the
10! European Union Public Licence 1.2 (EUPL 1.2).
11!
12! This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13! without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14! See the EU Public Licence for more details.
15!
16! You should have received a copy of the European Union Public Licence along with this code.
17! If not, see <https://www.eupl.eu/1.2/en/>.
18
19
20!***********************************************************************************************************************************
21!> \brief Procedures for asteroids
22
24 implicit none
25 save
26
27contains
28
29
30 !*********************************************************************************************************************************
31 !> \brief Calculate orbital elements for asteroids
32 !!
33 !! \param tjm Dynamical time in Julian Millennia after 2000.0
34 !! \param as Asteroid ID
35 !!
36 !! \param hcr Heliocentric distance (AU) (output)
37 !! \param om1 Argument of perihelion (rad) (output)
38 !! \param nu True anomaly (rad) (output)
39 !!
40 !! \param cosi cos(i): cosine of inclination (output)
41 !! \param sini sin(i): sine of inclination (output)
42 !! \param coso cos(Om): cosine of longitude of ascending node (output)
43 !! \param sino sin(Om): sine of longitude of ascending node (output)
44 !!
45 !! \see Meeus, Astronomical Algorithms, 1998, Ch.33
46 !!
47 !! \note Used by asteroid_lbr() and asteroid_eq()
48
49
50 subroutine asteroid_elements(tjm,as, hcr, om1,nu, cosi,sini,coso,sino)
51 use sufr_kinds, only: double
52 use sufr_constants, only: jd2000
53
56
57 real(double), intent(in) :: tjm
58 integer, intent(in) :: as
59 real(double), intent(out) :: hcr, om1,nu, sini,cosi,sino,coso
60 real(double) :: jd,jd0,djd, sma,ecc,in,om2, m0,mea,mem,ea
61
62
63 ! Elements are: 1-Epoch (JD), 2-a, 3-e, 4-i, 5-omega, 6-Omega, 7-M, 8-H, 9-G, for J2000.0:
64 jd0 = asterelems(as,1) ! JD of epoch
65 sma = asterelems(as,2) ! Semi-major axis
66 ecc = asterelems(as,3) ! Eccentricity
67 in = asterelems(as,4) ! Inlination
68 om1 = asterelems(as,5) ! omega - argument of perihelion
69 om2 = asterelems(as,6) ! Omega - longitude of ascending node
70 m0 = asterelems(as,7) ! Mean anomaly at epoch
71
72 ! Test Meeus p.232:
73 !jd0 = 2448193.04502000d0
74 !sma = 2.2091404d0
75 !ecc = 0.8502196d0
76 !in = 11.94524d0*d2r
77 !om1 = 186.23352d0*d2r
78 !om2 = 334.75006d0*d2r
79 !m0 = 0.d0
80
81 mem = 0.01720209895d0 * sma**(-1.5d0) ! Mean motion (rad/day)
82 jd = jd2000 + 365250.d0 * tjm
83 djd = jd - jd0 ! Time since epoch in days
84 mea = m0 + mem*djd ! Mean anomaly at time t
85
86 call precess_orb(jd2000,jd,in,om1,om2) ! Precess elements to equinox of date (for compatibility with planet_position)
87
88 call kepler(ecc,mea, ea) ! Solve Kepler's equation for eccentricic anomaly ea
89
90 nu = 2*atan(sqrt((1.d0+ecc)/(1.d0-ecc)) * tan(0.5d0*ea)) ! True anomaly, Meeus Eq. 30.1
91 hcr = sma*(1.d0 - ecc*cos(ea)) ! Radius vector, Meeus Eq. 30.2
92
93 sini = sin(in)
94 cosi = cos(in)
95 sino = sin(om2)
96 coso = cos(om2)
97
98 end subroutine asteroid_elements
99 !*********************************************************************************************************************************
100
101
102
103 !*********************************************************************************************************************************
104 !> \brief Calculate heliocentric ecliptical coordinates l,b,r for asteroid as at time t (Julian Millennia after 2000.0 in DT)
105 !!
106 !! \param t Dynamical time in Julian Millennia after 2000.0
107 !! \param as Asteroid ID
108 !!
109 !! \param l Heliocentric ecliptical longitude (rad) (output)
110 !! \param b Heliocentric ecliptical latitude (rad) (output)
111 !! \param r Heliocentric distance (AU) (output)
112 !!
113 !! \see Meeus, Astronomical Algorithms, 1998, Ch.33
114
115 subroutine asteroid_lbr(t,as, l,b,r)
116 use sufr_kinds, only: double
117 use sufr_angles, only: rev
118
119 implicit none
120 real(double), intent(in) :: t
121 integer, intent(in) :: as
122 real(double), intent(out) :: l,b,r
123
124 real(double) :: om1,nu, sini,cosi,sino,coso,u,sinu,cosu,x,y,z
125
126
127 ! Compute orbital elements:
128 call asteroid_elements(t,as, r, om1, nu, cosi,sini, coso,sino)
129
130 ! To calculate *ecliptical* coordinates:
131 ! Meeus, p.233:
132 u = om1 + nu
133 cosu = cos(u)
134 sinu = sin(u)
135
136 ! Heliocentric rectangular position:
137 x = r * (coso * cosu - sino * sinu * cosi)
138 y = r * (sino * cosu + coso * sinu * cosi)
139 z = r * sini * sinu
140
141 l = rev(atan2(y,x)) ! Heliocentric ecliptic longitude
142 b = asin(z/r) ! Heliocentric ecliptic latitude
143
144 end subroutine asteroid_lbr
145 !*********************************************************************************************************************************
146
147
148
149 !*********************************************************************************************************************************
150 !> \brief Calculate geocentric(?) equatorial coordinates ra, dec, delta for asteroid as at time t (Jul. Millennia DT after 2000)
151 !!
152 !! \param t Dynamical time in Julian Millennia after 2000.0
153 !! \param as Asteroid ID
154 !! \param l0 Heliocentric longitude of Earth
155 !! \param b0 Heliocentric latitude of Earth
156 !! \param r0 Heliocentric distance of Earth
157 !!
158 !! \param ra Geocentric right ascension (rad) (output)
159 !! \param dec Geocentric declination (rad) (output)
160 !! \param delta Geocentric distance (AU) (output)
161 !!
162 !! \see Meeus, Astronomical Algorithms, 1998, Ch.33
163
164 subroutine asteroid_eq(t,as, l0,b0,r0, ra,dec,delta)
165 use sufr_kinds, only: double
166 use sufr_angles, only: rev
167 use sufr_constants, only: eps2000
168
170
171 implicit none
172 real(double), intent(in) :: t, l0,b0,r0
173 integer, intent(in) :: as
174 real(double), intent(out) :: ra,dec,delta
175
176 real(double) :: om1,nu, eps,sine,cose, ff,gg,hh,pp,qq,rr, a1,a2,b1,b2,c1,c2 ! jd, dpsi,eps0,deps
177 real(double) :: sini,cosi,sino,coso, x,y,z, r, sx,sy,sz
178
179
180 ! Compute orbital elements:
181 call asteroid_elements(t,as, r, om1, nu, cosi,sini, coso,sino)
182
183 ! To calculate *equatorial* coordinates:
184 !jd = jd2000 + 365250.d0 * t
185 !call nutation(t, dpsi,eps0,deps)
186 !call nutation2000(jd,dpsi,deps) ! IAU 2000 Nutation model - doesn't provide eps0
187 !eps = eps0 + deps
188
189 eps = eps2000 ! For J2000.0 - this is used by JPL - CHECK
190 sine = sin(eps)
191 cose = cos(eps)
192
193 ! Meeus, Eq. 33.7:
194 ff = coso
195 gg = sino*cose
196 hh = sino*sine
197 pp = -sino*cosi
198 qq = coso*cosi*cose - sini*sine
199 rr = coso*cosi*sine + sini*cose
200
201 ! Meeus, Eq. 33.8:
202 a1 = rev( atan2(ff,pp) )
203 b1 = rev( atan2(gg,qq) )
204 c1 = rev( atan2(hh,rr) )
205 a2 = sqrt( ff**2 + pp**2 )
206 b2 = sqrt( gg**2 + qq**2 )
207 c2 = sqrt( hh**2 + rr**2 )
208
209 ! Meeus, Eq. 33.9:
210 x = r * a2 * sin(a1 + om1 + nu) ! Heliocentric *EQUATORIAL* rectangular coordinates: x,y,z
211 y = r * b2 * sin(b1 + om1 + nu)
212 z = r * c2 * sin(c1 + om1 + nu)
213
214 ! Heliocentric -> geocentric:
215 call calcsunxyz(t, l0,b0,r0, sx,sy,sz) ! Geocentric *equatorial* rectangular solar coordinates
216
217 ! Meeus, Eq. 33.10:
218 x = x + sx ! heliocentric -> geocentric
219 y = y + sy ! heliocentric -> geocentric
220 z = z + sz ! heliocentric -> geocentric
221
222 delta = sqrt(x**2 + y**2 + z**2) ! Geocentric distance (AU)
223 ra = atan2(y,x) ! Geocentric right ascenson
224 dec = asin(z/delta) ! Geocentric declination
225
226 end subroutine asteroid_eq
227 !*********************************************************************************************************************************
228
229
230
231 !*********************************************************************************************************************************
232 !> \brief Calculate asteroid magnitude for asteroid AS.
233 !!
234 !! \param as Asteroid number
235 !! \param delta Distance to the Earth
236 !! \param r Distance to the Sun
237 !! \param pa Phase angle
238 !!
239 !! \retval asteroid_magn Magnitude of the asteroid
240 !!
241 !! \see Meeus, Astronomical Algorithms, 1998, Ch.33
242
243 function asteroid_magn(as, delta,r, pa)
244 use sufr_kinds, only: double
246
247 implicit none
248 integer, intent(in) :: as
249 real(double), intent(in) :: delta,r,pa
250 real(double) :: asteroid_magn,h,g,phi1,phi2
251
252 h = asterelems(as,8) ! Mean absolute visual magnitude
253 g = asterelems(as,9) ! 'Slope parameter'
254
255 ! Meeus, p.231:
256 phi1 = exp(-3.33d0 * tan(0.5d0*pa)**(0.63d0))
257 phi2 = exp(-1.87d0 * tan(0.5d0*pa)**(1.22d0))
258
259 asteroid_magn = h + 5.d0*log10(r*delta) - 2.5d0*log10((1.d0-g)*phi1 + g*phi2) ! Meeus, Eq. 33.14
260
261 end function asteroid_magn
262 !*********************************************************************************************************************************
263
264
265
266 !*********************************************************************************************************************************
267 !> \brief Solve Kepler's equation
268 !!
269 !! \param ecc Eccentricity
270 !! \param mea Mean anomaly
271 !! \param eca Eccentric anomaly (output)
272 !!
273 !! Solve Kepler's equation for given eccentricity ecc, mean anomaly mea and eccentric anomaly eca
274 !! \see Meeus, Astronomical Algorithms, 1998, p.206
275
276 subroutine kepler(ecc,mea, eca)
277 use sufr_kinds, only: double, dbl
278 use sufr_constants, only: pi,pi2, pio2,pio4
279 use sufr_system, only: warn
280 use sufr_angles, only: rev
281
282 implicit none
283 real(double), intent(in) :: ecc,mea
284 real(double), intent(out) :: eca
285
286 real(double), parameter :: accur = 1.0e-15_dbl ! Accur: 1e-10: 34 iterations, 1e-15: 51 iter, 1e-50: 167, 0.d0: 1076
287 integer :: sig
288 real(double) :: ma,d,de,m1
289
290 if(ecc.lt.0.d0 .or. ecc.gt.1.d0) call warn('kepler() can only be used for orbits with eccentricities between 0 and 1', 0)
291
292 ma = mea
293 !sig = nint(abs(m)/ma) ! Sign of ma
294 sig = nint(sign(1.d0,ma)) ! Sign of ma
295 ma = abs(ma)/pi2
296 ma = rev( sig * pi2 * (ma-floor(ma)) ) ! Is INT() in basic really floor() ?
297
298 sig = 1
299 if(ma.gt.pi) then
300 sig = -1
301 ma = pi2 - ma
302 end if
303
304 ! Starting values:
305 eca = pio2 ! pi/2
306 d = pio4 ! pi/4
307 de = huge(de)
308
309 do while(abs(de).gt.accur) ! Takes 51 iterations
310 m1 = eca - ecc*sin(eca)
311 de = d * sign(1.d0,ma-m1)
312 eca = eca + de
313 d = 0.5d0*d
314 end do
315
316 eca = sig * eca ! Apply the correct sign
317
318 end subroutine kepler
319 !*********************************************************************************************************************************
320
321
322
323
324end module thesky_asteroids
325!***********************************************************************************************************************************
Procedures for asteroids.
Definition asteroids.f90:23
subroutine asteroid_lbr(t, as, l, b, r)
Calculate heliocentric ecliptical coordinates l,b,r for asteroid as at time t (Julian Millennia after...
subroutine asteroid_elements(tjm, as, hcr, om1, nu, cosi, sini, coso, sino)
Calculate orbital elements for asteroids.
Definition asteroids.f90:51
real(double) function asteroid_magn(as, delta, r, pa)
Calculate asteroid magnitude for asteroid AS.
subroutine asteroid_eq(t, as, l0, b0, r0, ra, dec, delta)
Calculate geocentric(?) equatorial coordinates ra, dec, delta for asteroid as at time t (Jul....
subroutine kepler(ecc, mea, eca)
Solve Kepler's equation.
Procedures for coordinates.
subroutine precess_orb(jd1, jd2, i, o1, o2)
Compute the precession of the equinoxes in orbital elements.
subroutine calcsunxyz(t1, l0, b0, r0, x, y, z)
Compute the geocentric equatorial rectangular coordinates of the Sun, from Earth's heliocentric,...
Planet data, needed to compute planet positions.
Definition modules.f90:85
real(double), dimension(nasteroids, 9) asterelems
Asteroid orbital elements.
Definition modules.f90:113