libTheSky
Routines to compute sky positions of Sun, Moon, planets and more
All Namespaces Files Functions Variables Pages
vsop.f90
Go to the documentation of this file.
1!> \file vsop.f90 Core VSOP routines 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 VSOP
22!!
23!! \note
24!! VSOP87 accuracies 1900-2100 in milliarcseconds (VSOP87 paper):
25!! - Me: 1, Ve: 6, Ea: 5, Ma: 23, Ju: 20, Sa: 100, Ur: 16, Ne: 30
26!!
27!! \note
28!! Accuracy < 1" in JD2000 +- range in kyr (Wikipedia):
29!! - Me-Ma: 4, Ju,Sa: 2, Ur,Ne: 6 (i.e., Earth position more accurate than 1" between -2000 and +6000)
30!!
31!! \see Bretagnon, P.; Francou, G. Planetary theories in rectangular and spherical variables - VSOP 87 solutions
32!! http://esoads.eso.org/abs/1988A%26A...202..309B
33
35 implicit none
36 save
37
38
39contains
40
41
42 !*********************************************************************************************************************************
43 !> \brief Calculate true heliocentric ecliptic coordinates l,b,r for planet pl and the mean ecliptic and
44 !! equinox of date using VSOP87D
45 !!
46 !! \param tm Dynamical time in Julian Millennia after J2000.0, (tau in Meeus)
47 !! \param pl Planet to compute position for
48 !!
49 !! \param lon Heliocentric longitude (rad) (output)
50 !! \param lat Heliocentric latitude (rad) (output)
51 !! \param rad Heliocentric distance (AU) (output)
52 !!
53 !! \param LBaccur Desired accuracy of L,B (rad, optional)
54 !! \param Raccur Desired accuracy of R (AU, optional)
55 !!
56 !! \see http://esoads.eso.org/abs/1988A%26A...202..309B
57
58 subroutine vsop87d_lbr(tm,pl, lon,lat,rad, LBaccur,Raccur)
59 use sufr_kinds, only: double
60 use sufr_angles, only: rev
62
63 implicit none
64 real(double), intent(in) :: tm
65 integer, intent(in) :: pl
66 real(double), intent(out) :: lon,lat,rad
67 real(double), intent(in), optional :: LBaccur,Raccur
68
69 integer :: li, pow, Nli,Nle, var, nTerm, skip
70 real(double) :: fac, lbr(3), accur, desired_accuracy(3)
71
72 ! desired_accuracy = 1.d-9 ! 5e-9 rad = 1 mas = VSOP87 accuracy for Mercury in 1900-2100
73 desired_accuracy = 0.d0 ! Use all available terms - setting LBR accuracy equal to VSOP87 truncation still skips some terms!
74 if(present(lbaccur)) desired_accuracy(1:2) = [lbaccur,lbaccur]
75 if(present(raccur)) desired_accuracy(3) = raccur
76
77 lbr = 0.d0
78 !$omp parallel do private(Nli,Nle,skip,li,pow,fac,nTerm) ! Loop body seems to small for any benefit
79 do var=1,3 ! L,B,R
80 nli = 0
81 if(var.ge.2) nli = vsopnls(1,pl)
82 if(var.eq.3) nli = nli + vsopnls(2,pl)
83 nle = nli + vsopnls(var,pl)
84
85 skip = -1 ! Switch to skip terms if sufficient accuracy is reached
86 do li=nli+1,nle
87 pow = nint(vsopdat(1,li,pl))
88
89 if(pow.ne.skip) then
90 fac = tm**pow * vsopdat(2,li,pl)
91 lbr(var) = lbr(var) + fac * cos( vsopdat(3,li,pl) + vsopdat(4,li,pl)*tm )
92
93 ! Determine current accuracy (A*T^n):
94 if((desired_accuracy(var).gt.1.d-15) .and. (mod(li,3).eq.0)) then ! Reduce overhead, experimentally optimised to 3
95 nterm = li - vsopnblk(pow,1,pl)+1
96 accur = 2*sqrt(dble(nterm)) * abs(fac)
97 if(accur.lt.desired_accuracy(var)) skip = pow ! Skip the remaining terms for this power
98 end if
99 end if
100
101 end do ! li
102 end do ! var
103 !$omp end parallel do
104
105 lon = lbr(1)
106 lat = lbr(2)
107 rad = lbr(3)
108
109 end subroutine vsop87d_lbr
110 !*********************************************************************************************************************************
111
112
113
114end module thesky_vsop
115!***********************************************************************************************************************************
Planet data, needed to compute planet positions.
Definition modules.f90:85
real(double), dimension(4, 6827, 10) vsopdat
Periodic terms for VSOP87.
Definition modules.f90:106
integer, dimension(3, 8) vsopnls
Numbers of lines in the VSOP input files (l,b,r x 8 pl)
Definition modules.f90:103
integer, dimension(0:5, 3, 8) vsopnblk
Line number in the VSOP data where the next block of (Planet, Variable (LBR), Power) starts.
Definition modules.f90:104
Procedures for VSOP.
Definition vsop.f90:34
subroutine vsop87d_lbr(tm, pl, lon, lat, rad, lbaccur, raccur)
Calculate true heliocentric ecliptic coordinates l,b,r for planet pl and the mean ecliptic and equino...
Definition vsop.f90:59