libTheSky
Routines to compute sky positions of Sun, Moon, planets and more
All Namespaces Files Functions Variables Pages
functions.f90
Go to the documentation of this file.
1!> \file functions.f90 Contains general functions 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! const_id: Identify the constellation a,d lies in
21
22! plsep: Calculates angular separation between two planets
23! plpa: Calculates position angle between two planets
24
25! conabr2conid: Convert a three-letter constellation abbreviation to a constellation ID number
26
27! fillfloat Print a floating-point number with leading zeros in format (0...0)Ftot.dgt to a string
28
29! ds: Returns distance as a nice string in AU
30! ds1: Returns distance as a nice, smaller string in AU
31
32
33
34!***********************************************************************************************************************************
35!> \brief Assorted procedures
36
38 implicit none
39 save
40
41contains
42
43 !*********************************************************************************************************************************
44 !> \brief Set a location, using the variables in TheSky_local
45 !!
46 !! \param lat0 Latitude (radians, >0 is northern hemisphere)
47 !! \param lon0 Longitude (radians, >0 is east of Greenwich)
48 !! \param height Altitude/elevation above sealevel, in metres
49 !!
50 !! \param tz0 Default timezone (standard time, no DST, >0 is east of Greenwich)
51 !! \param dsttp DST type: 0-none, 1-EU, 2-USA
52
53 subroutine set_thesky_location(lat0,lon0,height, tz0,dsttp)
54 use sufr_kinds, only: double
55 use thesky_local, only: llon0=>lon0,llat0=>lat0,lheight=>height,ltz=>tz,ltz0=>tz0,ldsttp=>dsttp
56
57 implicit none
58 real(double), intent(in) :: lat0,lon0,height, tz0
59 integer, intent(in) :: dsttp
60
61 llat0 = lat0
62 llon0 = lon0
63 lheight = height
64
65 ltz = tz0 ! Current timezone (standard time or DST)
66 ltz0 = tz0 ! Default timezone (standard time, no DST)
67 ldsttp = dsttp
68
69 end subroutine set_thesky_location
70 !*********************************************************************************************************************************
71
72
73
74 !*********************************************************************************************************************************
75 !> \brief Identify the constellation a,d lies in
76 !!
77 !! \param jd Equinox in JD
78 !! \param ra RA in radians
79 !! \param dec Dec in radians
80 !!
81 !! \retval const_id The constellation ID
82
83 function const_id(jd, ra,dec)
84 use sufr_kinds, only: double
85 use sufr_constants, only: jd1875, r2d,r2h
86 use sufr_angles, only: rev
87 use sufr_system, only: warn
88
91
92 implicit none
93 real(double), intent(in) :: jd,ra,dec
94 integer :: line,const_id
95 real(double) :: lra,ldec
96
97 lra = ra
98 ldec = dec
99
100 ! Precess position to 1875.0 equinox:
101 call precess_eq(jd,jd1875,lra,ldec)
102 lra = rev(lra)*r2h
103 ldec = ldec*r2d
104
105 ! Find constellation such that the declination entered is higher than the lower boundary of the constellation
106 ! when the upper and lower right ascensions for the constellation bound the entered right ascension:
107 line = 1
108
109 do while(coniddecl(line).gt.ldec)
110 line = line + 1
111 end do
112
113
114 do
115 do while(conidrau(line).le.lra)
116 line = line + 1
117 end do
118
119 do while(conidral(line).gt.lra)
120 line = line + 1
121 end do
122
123 ! If constellation has been found, write result and exit/return. Otherwise, continue the search by returning to rau.
124 if(lra.ge.conidral(line).and.lra.lt.conidrau(line).and.coniddecl(line).le.ldec) then
125 const_id = conid(line)
126 exit
127 else if(conidrau(line).gt.lra) then ! Nothing found
128 const_id = 0
129 call warn('const_id(): constellation ID was not found', 0)
130 exit
131 end if ! else cycle
132 end do
133
134 end function const_id
135 !*********************************************************************************************************************************
136
137
138
139
140
141 !*********************************************************************************************************************************
142 !> \brief Calculates the angular separation between two planets
143 !!
144 !! \param jd0 Julian day for calculation
145 !! \param p1 ID of planet 1
146 !! \param p2 ID of planet 2
147 !!
148 !! \retval plsep The angular separation between the two planets (rad)
149 !!
150 !! \note Uses asep()
151
152 function plsep(jd0, p1,p2)
153 use sufr_kinds, only: double
154 use sufr_angles, only: asep
155
157 use thesky_planetdata, only: planpos
158
159 implicit none
160 real(double), intent(in) :: jd0
161 integer, intent(in) :: p1,p2
162 real(double) :: plsep,jd,l1,l2,b1,b2
163
164 jd = jd0
165 call planet_position(jd,p1)
166 l1 = planpos(25)
167 b1 = planpos(26)
168
169 call planet_position(jd,p2)
170 l2 = planpos(25)
171 b2 = planpos(26)
172
173 plsep = asep(l1,l2, b1,b2)
174
175 end function plsep
176 !*********************************************************************************************************************************
177
178
179
180
181 !*********************************************************************************************************************************
182 !> \brief Calculates the position angle of planet 2 with respect to planet 1, COUNTERCLOCKWISE from the north
183 !!
184 !! \param jd0 Julian day for calculation
185 !! \param p1 ID of planet 1
186 !! \param p2 ID of planet 2
187 !! \retval plpa The position angle of planet 2 with respect to planet 1, COUNTERCLOCKWISE from the north (rad)
188 !!
189 !! \note
190 !! Uses calpa()
191
192 function plpa(jd0,p1,p2)
193 use sufr_kinds, only: double
194 use sufr_angles, only: calpa
195
197 use thesky_planetdata, only: planpos
198
199 implicit none
200 real(double), intent(in) :: jd0
201 integer, intent(in) :: p1,p2
202 real(double) :: plpa,jd,l1,l2,b1,b2
203
204 jd = jd0
205 call planet_position(jd,p1)
206 l1 = planpos(5) ! RA and Dec
207 b1 = planpos(6)
208
209 call planet_position(jd,p2)
210 l2 = planpos(5)
211 b2 = planpos(6)
212
213 plpa = calpa(l1,l2, b1,b2)
214
215 end function plpa
216 !*********************************************************************************************************************************
217
218
219
220
221 !*********************************************************************************************************************************
222 !> \brief Convert a three-letter constellation abbreviation to a constellation ID number
223 !!
224 !! \param myconabr Constellation abbreviation (e.g. And)
225 !! \param myconid Constellation ID number (output)
226
227 subroutine conabr2conid(myconabr, myconid)
229
230 implicit none
231 character, intent(in) :: myconabr*(*)
232 integer, intent(out) :: myconid
233 integer :: con
234
235 myconid = 0
236 do con=1,nconstel
237 if(trim(conabr(con)).eq.trim(myconabr)) then
238 myconid = con
239 exit
240 end if
241 end do
242
243 end subroutine conabr2conid
244 !*********************************************************************************************************************************
245
246
247
248 !*********************************************************************************************************************************
249 !> \brief Print a floating-point number with leading zeros in format (0...0)Ftot.dgt to a string
250 !!
251 !! \param x Number to be printed
252 !! \param tot Total length of printed number - Ftot.dgt
253 !! \param dgt Number of decimal digits - Ftot.dgt
254 !!
255 !! \retval fillfloat String containing the float with leading zeros.
256
257 function fillfloat(x,tot,dgt)
258 use sufr_kinds, only: double
259 implicit none
260 real(double), intent(in) :: x
261 integer, intent(in) :: tot,dgt
262 character :: fillfloat*(99), fmt*(99)
263 integer :: dec
264
265 dec = tot-dgt-1 ! Number of decimal places before decimal sign
266 if(x.lt.0.d0) then
267 dec = dec-1 ! Need extra room for minus sign
268 write(fmt,'(A,2(I3.3,A,I3.3,A))') '(A1,I',dec,'.',dec,',F',dgt+1,'.',dgt,')'
269 write(fillfloat,trim(fmt)) '-', floor(abs(x)), abs(x)-floor(abs(x))
270 else
271 write(fmt,'(A,2(I3.3,A,I3.3,A))') '(I',dec,'.',dec,',F',dgt+1,'.',dgt,')'
272 write(fillfloat,trim(fmt)) floor(x), abs(x)-floor(abs(x))
273 end if
274
275 end function fillfloat
276 !*********************************************************************************************************************************
277
278
279 !*********************************************************************************************************************************
280 !> \brief Print planet distance in AU as a nice string, but use km for the Moon
281 !!
282 !! \param d Distance (AU)
283 !! \retval ds String containing the formatted distance in AU
284
285 function ds(d)
286 use sufr_kinds, only: double
287 use sufr_constants, only: au
288
289 implicit none
290 real(double), intent(in) :: d
291 character :: ds*(11)
292
293 write(ds,'(F11.8)') d
294 if(d.lt.0.01d0) write(ds,'(F11.4)') d*au/1.d5 ! For the Moon
295
296 end function ds
297 !*********************************************************************************************************************************
298
299
300 !*********************************************************************************************************************************
301 !> \brief Print planet distance in AU as a nice string, but use km for the Moon - smaller string
302 !!
303 !! \param d Distance (AU)
304 !! \retval ds1 String containing the formatted distance in AU
305
306 function ds1(d)
307 use sufr_kinds, only: double
308 use sufr_constants, only: au
309
310 implicit none
311 real(double), intent(in) :: d
312 character :: ds1*(9)
313
314 write(ds1,'(F9.6)') d
315 if(d.lt.0.01d0) write(ds1,'(F9.2)') d*au/1.d5 ! For the Moon
316
317 end function ds1
318 !*********************************************************************************************************************************
319
320end module thesky_functions
321!***********************************************************************************************************************************
Procedures for coordinates.
subroutine precess_eq(jd1, jd2, a1, d1)
Compute the precession of the equinoxes in equatorial coordinates, from jd1 to jd2.
Assorted procedures.
Definition functions.f90:37
real(double) function plsep(jd0, p1, p2)
Calculates the angular separation between two planets.
subroutine conabr2conid(myconabr, myconid)
Convert a three-letter constellation abbreviation to a constellation ID number.
subroutine set_thesky_location(lat0, lon0, height, tz0, dsttp)
Set a location, using the variables in TheSky_local.
Definition functions.f90:54
character function, dimension(99) fillfloat(x, tot, dgt)
Print a floating-point number with leading zeros in format (0...0)Ftot.dgt to a string.
real(double) function plpa(jd0, p1, p2)
Calculates the position angle of planet 2 with respect to planet 1, COUNTERCLOCKWISE from the north.
character function, dimension(11) ds(d)
Print planet distance in AU as a nice string, but use km for the Moon.
character function, dimension(9) ds1(d)
Print planet distance in AU as a nice string, but use km for the Moon - smaller string.
integer function const_id(jd, ra, dec)
Identify the constellation a,d lies in.
Definition functions.f90:84
Local parameters for libTheSky: location, date, time.
Definition modules.f90:56
real(double) tz
Current value of time zone, taking into account DST (hours; >0 is east of Greenwich)
Definition modules.f90:67
real(double) height
Altitude of the observer above sea level (m)
Definition modules.f90:65
real(double) tz0
Standard value of time zone, without DST ("winter time"; hours; >0 is east of Greenwich)
Definition modules.f90:68
real(double) lon0
Longitude of the observer (rad)
Definition modules.f90:64
real(double) lat0
Latitude of the observer (rad)
Definition modules.f90:63
integer dsttp
DST type for current location (0: none, 1: EU, 2: USA+Canada (after 2007)
Definition modules.f90:76
Planet data, needed to compute planet positions.
Definition modules.f90:85
real(double), dimension(nplanpos) planpos
Planpos[] is an array with many different types of coordinates and related variables:
Definition modules.f90:192
Procedures for planets.
Definition planets.f90:23
subroutine planet_position(jd, pl, lat, lon, hgt, lbaccur, raccur, ltime, aber, to_fk5, assume_jde, lunar_theory, nutat, magmdl, verbosity)
Compute the position, distance, etc of a planet.
Definition planets.f90:63
Star and basic constellation data.
Definition modules.f90:343
integer, parameter nconstel
Number of constellations.
Definition modules.f90:367
real(double), dimension(nconid) coniddecl
Constellation lower declination boundary for ID.
Definition modules.f90:373
real(double), dimension(nconid) conidrau
Constellation uppwer RA boundary for ID.
Definition modules.f90:372
integer, dimension(nconid) conid
Constellation ID.
Definition modules.f90:369
character, dimension(3) conabr
Abbreviations of the constellations.
Definition modules.f90:375
real(double), dimension(nconid) conidral
Constellation lower RA boundary for ID.
Definition modules.f90:371