Fortran - グリニッジ恒星時の計算(IAU2006 理論)!
Updated:
グリニッジ視恒星時(GAST; Greenwich Apparent Sidereal Time)、グリニッジ平均恒星時(GMST; Greenwich Mean Sidereal Time)、分点均差(EE; Equation of Equinoxes )の計算を Fortran 95 で行いました。(使用するのは IAU2006 理論)
過去には Ruby や Python でも行いましたが。
0. 前提条件
- LMDE 3 (Linux Mint Debian Edition 3; 64bit) での作業を想定。
- GCC 6.3.0 (GFortran 6.3.0) でのコンパイルを想定。
1. 章動の計算について
当ブログ過去記事を参照のこと。
2. ソースコードの作成
- 以下は実行部分。
File: greenwich_time.f95
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
!*******************************************************************************
! グリニジ視恒星時 GAST(= Greenwich Apparent Sidereal Time)等の計算
! : IAU2006 による計算
!
! * IAU SOFA(International Astronomical Union, Standards of Fundamental Astronomy)
! の提供する C ソースコード "gst06.c" 等で実装されているアルゴリズムを使用する。
! * 参考サイト
! - [SOFA Library Issue 2016-05-03 for ANSI C: Complete List]
! (http://www.iausofa.org/2016_0503_C/CompleteList.html)
! - [USNO Circular 179]
! (http://aa.usno.navy.mil/publications/docs/Circular_179.php)
! - [IERS Conventions Center]
! (http://62.161.69.131/iers/conv2003/conv2003_c5.html)
! * うるう秒の判定は UTC でなく TT で行っている
!
! Date Author Version
! 2018.10.18 mk-mode.com 1.00 新規作成
! 2018.11.09 mk-mode.com 1.01 時刻の取扱変更(マイクロ秒 => ミリ秒)
! 2018.11.11 mk-mode.com 1.02 ΔT計算に DUT1 を加味
!
! Copyright(C) 2018 mk-mode.com All Rights Reserved.
! ---
! 引数 : 日時(TT(地球時))
! * 書式:YYYYMMDD[HHMMSS[MMM]]
! * 無指定なら現在(システム日時)を地球時とみなす。
!*******************************************************************************
!
program greenwich_time
use const
use delta_t
use time
use precession
use nutation
use rotation_fw
use cip_cio
use greenwich
implicit none
type(t_time) :: tt, ut1
integer(SP) :: utc_tai, i
real(DP) :: jd, jc, dut1, dt, jd_ut1
real(DP) :: gam_b, phi_b, psi_b, eps_a, fj2
real(DP) :: d_psi_ls, d_eps_ls, d_psi_pl, d_eps_pl, d_psi, d_eps
real(DP) :: mtx(3, 3), xy(2), s
real(DP) :: era, eo, gast, gast_deg, gmst, gmst_deg, ee, ee_deg
! コマンドライン引数(TT)取得
call get_arg(tt)
if (tt%year == 0) stop
! === Time calculation
call gc2jd(tt, jd)
call jd2jc(jd, jc)
call utc2utc_tai(tt, utc_tai)
call utc2dut1(tt, dut1)
call utc2dt(tt, utc_tai, dut1, dt)
call tt2ut1(tt, dt, ut1)
call gc2jd(ut1, jd_ut1)
! === Fukushima-Williams angles for frame bias and precession.
! Ref: iauPfw06(date1, date2, &gamb, &phib, &psib, &epsa)
call pfw_06(jc, gam_b, phi_b, psi_b)
call obl_06(jc, eps_a)
! === Nutation components.
! Ref: iauNut06a(date1, date2, &dp, &de)
! * Factor correcting for secular variation of J2.
fj2 = -2.7774e-6_DP * jc
! Calculation
call calc_lunisolar(jc, d_psi_ls, d_eps_ls)
call calc_planetary(jc, d_psi_pl, d_eps_pl)
d_psi = d_psi_ls + d_psi_pl
d_eps = d_eps_ls + d_eps_pl
! * Apply P03 adjustments (Wallace & Capitaine, 2006, Eqs.5).
d_psi = d_psi + d_psi * (0.4697e-6_DP + fj2)
d_eps = d_eps + d_eps * fj2
! === Equinox based nutation x precession x bias matrix.
! Ref: iauFw2m(gamb, phib, psib + dp, epsa + de, rnpb)
call fw2m(gam_b, phi_b, psi_b + d_psi, eps_a + d_eps, mtx)
! === Extract CIP coordinates.
! Ref: iauBpn2xy(rnpb, &x, &y)
call bpn2xy(mtx, xy)
! === The CIO locator, s.
! Ref: iauS06(tta, ttb, x, y)
call s_06(jc, xy, s)
!# Greenwich time
! === Greenwich apparent sidereal time.
! Ref: iauEra00(uta, utb), iauEors(rnpb, s)
call gw_era(jd_ut1, era)
call gw_eors(mtx, s, eo)
call gw_gast(era, eo, gast)
gast_deg = gast / PI_180
! === Greenwich mean sidereal time, IAU 2006.
! Ref: iauGmst06(uta, utb, tta, ttb)
call gw_gmst(era, jc, gmst)
gmst_deg = gmst / PI_180
! === Equation of Equinoxes
call gw_ee(gast, gmst, ee)
ee_deg = ee / PI_180
! 結果出力
print '(" TT = ", A)', date_fmt(tt)
print '(" UT1 = ", A)', date_fmt(ut1)
print '(" JD(TT) = ", F18.10, " (days)")', jd
print '("JD(UT1) = ", F18.10, " (days)")', jd_ut1
print '(" JC = ", F18.16, " (centuries)")', jc
print '(" DT = ", F6.3, " (seconds)")', dt
print '(" GAMMA_ = ", F21.18)', gam_b
print '(" PHI_ = ", F21.18)', phi_b
print '(" PSI_ = ", F21.18)', psi_b
print '(" EPS_A = ", F21.18)', eps_a
print '(" D_PSI = ", F21.18)', d_psi
print '(" D_EPS = ", F21.18)', d_eps
print '(" r_mtx = ")'
do i = 1, 3
print '(2X3(XF21.18))', mtx(i, :)
end do
print '(" x, y = ", (F21.18, X, F21.18))', xy
print '(" s = ", F21.18)', s
print '(" ERA = ", F23.18, " (rad)")', era
print '(" EO = ", F23.18, " (rad)")', eo
print '(" GAST = ", F23.18, " (rad)")', gast
print '(" = ", F23.18, " (°)")' , gast_deg
print '(" = ", A)' , deg2hms(gast_deg)
print '(" GMST = ", F23.18, " (rad)")', gmst
print '(" = ", F23.18, " (°)")', gmst_deg
print '(" = ", A)' , deg2hms(gmst_deg)
print '(" EE = ", F23.18, " (rad)")', ee
print '(" = ", F23.18, " (°)")', ee_deg
print '(" = ", A)' , deg2hms(ee_deg)
stop
contains
! コマンドライン引数取得
! * YYYYMMDD[HHMMSS[MMM]] 形式
! * 17桁超入力された場合は、18桁目以降の部分は切り捨てる
! * コマンドライン引数がなければ、システム日付を TT とする
! * 日時の整合性チェックは行わない
!
! :param(inout) type(t_time) tt
subroutine get_arg(tt)
implicit none
type(t_time), intent(inout) :: tt
character(17) :: gc
integer(SP) :: dt(8), len_gc
if (iargc() == 0) then
call date_and_time(values=dt)
tt = t_time(dt(1), dt(2), dt(3), dt(5), dt(6), dt(7), dt(8))
else
call getarg(1, gc)
len_gc = len(trim(gc))
if (len_gc /= 8 .and. len_gc /= 14 .and. len_gc /= 17) then
print *, "Format: YYYYMMDD[HHMMSS[MMM]]"
return
end if
read (gc, FMT_DT_0) tt
end if
end subroutine get_arg
end program greenwich_time
モジュールや定数ファイルを含めた全てのファイルは GitHub にアップしている。(当然ながら、モジュール部分の方が計算の本質となっている)
3. ソースコードのビルド
$ make
- やり直す場合は、
make clean
してから。
4. 準備
- うるう年ファイル
LEAP_SEC.txt
, DUT1 ファイルDUT1.txt
は適宜最新のものに更新すること。
5. 実行方法
$ ./greenwich_time [YYYYMMDD[HHMMSS[MMM]]]
- TT(地球時)は「年・月・日・時・分・秒・ミリ秒」を最大17桁で指定する。
- TT(地球時)を指定しない場合は、システム日時を TT とみなす。
以下、実行例。
$ ./greenwich_time 20190106123456123
TT = 2019-01-06 12:34:56.123
UT1 = 2019-01-06 12:33:45.042
JD(TT) = 2458490.0242606830 (days)
JD(UT1) = 2458490.0234379862 (days)
JC = 0.1901444013876245 (centuries)
DT = 71.081 (seconds)
GAMMA_ = 0.000009561193753159
PHI_ = 0.409049490088273016
PSI_ = 0.004644774992010763
EPS_A = 0.409049424343738532
D_PSI = -0.000070858824994223
D_EPS = -0.000022910476246079
r_mtx =
0.999989579742006973 -0.004186989111982383 -0.001819211252307724
0.004187030893655816 0.999991234164195109 0.000019158957116627
0.001819115087055748 -0.000026775851190874 0.999998345050307602
x, y = 0.001819115087055748 -0.000026775851190874
s = 0.000000014817885464
ERA = 5.131245921135885624 (rad)
EO = -0.004187010883491056 (rad)
GAST = 5.135432932019377006 (rad)
= 294.238632977204076724 (°)
= 19 h 36 m 57.271914 s
GMST = 5.135497933767932288 (rad)
= 294.242357303057303852 (°)
= 19 h 36 m 58.165752 s
EE = -0.000065001748555282 (rad)
= -0.003724325853188271 (°)
= - 0 h 00 m 00.893838 s
以上、
Comments