/rust/registry/src/index.crates.io-1949cf8c6b5b557f/sofars-0.6.1/src/pnp/s00.rs
Line | Count | Source |
1 | | #![allow(non_upper_case_globals)] |
2 | | use crate::consts::{DAS2R, DJ00, DJC}; |
3 | | use crate::fundargs::{fad03, fae03, faf03, fal03, falp03, faom03, fapa03, fave03}; |
4 | | |
5 | | struct TERM( |
6 | | [i32; 8], // nfa |
7 | | f64, |
8 | | f64, // s, c |
9 | | ); |
10 | | |
11 | | const sp: [f64; 6] = [ |
12 | | 94.00e-6, |
13 | | 3808.35e-6, |
14 | | -119.94e-6, |
15 | | -72574.09e-6, |
16 | | 27.70e-6, |
17 | | 15.61e-6, |
18 | | ]; |
19 | | |
20 | | /* Terms of order t^0 */ |
21 | | const s0: [TERM; 33] = [ |
22 | | TERM([0, 0, 0, 0, 1, 0, 0, 0], -2640.73e-6, 0.39e-6), |
23 | | TERM([0, 0, 0, 0, 2, 0, 0, 0], -63.53e-6, 0.02e-6), |
24 | | TERM([0, 0, 2, -2, 3, 0, 0, 0], -11.75e-6, -0.01e-6), |
25 | | TERM([0, 0, 2, -2, 1, 0, 0, 0], -11.21e-6, -0.01e-6), |
26 | | TERM([0, 0, 2, -2, 2, 0, 0, 0], 4.57e-6, 0.00e-6), |
27 | | TERM([0, 0, 2, 0, 3, 0, 0, 0], -2.02e-6, 0.00e-6), |
28 | | TERM([0, 0, 2, 0, 1, 0, 0, 0], -1.98e-6, 0.00e-6), |
29 | | TERM([0, 0, 0, 0, 3, 0, 0, 0], 1.72e-6, 0.00e-6), |
30 | | TERM([0, 1, 0, 0, 1, 0, 0, 0], 1.41e-6, 0.01e-6), |
31 | | TERM([0, 1, 0, 0, -1, 0, 0, 0], 1.26e-6, 0.01e-6), |
32 | | TERM([1, 0, 0, 0, -1, 0, 0, 0], 0.63e-6, 0.00e-6), |
33 | | TERM([1, 0, 0, 0, 1, 0, 0, 0], 0.63e-6, 0.00e-6), |
34 | | TERM([0, 1, 2, -2, 3, 0, 0, 0], -0.46e-6, 0.00e-6), |
35 | | TERM([0, 1, 2, -2, 1, 0, 0, 0], -0.45e-6, 0.00e-6), |
36 | | TERM([0, 0, 4, -4, 4, 0, 0, 0], -0.36e-6, 0.00e-6), |
37 | | TERM([0, 0, 1, -1, 1, -8, 12, 0], 0.24e-6, 0.12e-6), |
38 | | TERM([0, 0, 2, 0, 0, 0, 0, 0], -0.32e-6, 0.00e-6), |
39 | | TERM([0, 0, 2, 0, 2, 0, 0, 0], -0.28e-6, 0.00e-6), |
40 | | TERM([1, 0, 2, 0, 3, 0, 0, 0], -0.27e-6, 0.00e-6), |
41 | | TERM([1, 0, 2, 0, 1, 0, 0, 0], -0.26e-6, 0.00e-6), |
42 | | TERM([0, 0, 2, -2, 0, 0, 0, 0], 0.21e-6, 0.00e-6), |
43 | | TERM([0, 1, -2, 2, -3, 0, 0, 0], -0.19e-6, 0.00e-6), |
44 | | TERM([0, 1, -2, 2, -1, 0, 0, 0], -0.18e-6, 0.00e-6), |
45 | | TERM([0, 0, 0, 0, 0, 8, -13, -1], 0.10e-6, -0.05e-6), |
46 | | TERM([0, 0, 0, 2, 0, 0, 0, 0], -0.15e-6, 0.00e-6), |
47 | | TERM([2, 0, -2, 0, -1, 0, 0, 0], 0.14e-6, 0.00e-6), |
48 | | TERM([0, 1, 2, -2, 2, 0, 0, 0], 0.14e-6, 0.00e-6), |
49 | | TERM([1, 0, 0, -2, 1, 0, 0, 0], -0.14e-6, 0.00e-6), |
50 | | TERM([1, 0, 0, -2, -1, 0, 0, 0], -0.14e-6, 0.00e-6), |
51 | | TERM([0, 0, 4, -2, 4, 0, 0, 0], -0.13e-6, 0.00e-6), |
52 | | TERM([0, 0, 2, -2, 4, 0, 0, 0], 0.11e-6, 0.00e-6), |
53 | | TERM([1, 0, -2, 0, -3, 0, 0, 0], -0.11e-6, 0.00e-6), |
54 | | TERM([1, 0, -2, 0, -1, 0, 0, 0], -0.11e-6, 0.00e-6), |
55 | | ]; |
56 | | |
57 | | /* Terms of order t^1 */ |
58 | | const s1: [TERM; 3] = [ |
59 | | TERM([0, 0, 0, 0, 2, 0, 0, 0], -0.07e-6, 3.57e-6), |
60 | | TERM([0, 0, 0, 0, 1, 0, 0, 0], 1.71e-6, -0.03e-6), |
61 | | TERM([0, 0, 2, -2, 3, 0, 0, 0], 0.00e-6, 0.48e-6), |
62 | | ]; |
63 | | |
64 | | /* Terms of order t^2 */ |
65 | | const s2: [TERM; 25] = [ |
66 | | TERM([0, 0, 0, 0, 1, 0, 0, 0], 743.53e-6, -0.17e-6), |
67 | | TERM([0, 0, 2, -2, 2, 0, 0, 0], 56.91e-6, 0.06e-6), |
68 | | TERM([0, 0, 2, 0, 2, 0, 0, 0], 9.84e-6, -0.01e-6), |
69 | | TERM([0, 0, 0, 0, 2, 0, 0, 0], -8.85e-6, 0.01e-6), |
70 | | TERM([0, 1, 0, 0, 0, 0, 0, 0], -6.38e-6, -0.05e-6), |
71 | | TERM([1, 0, 0, 0, 0, 0, 0, 0], -3.07e-6, 0.00e-6), |
72 | | TERM([0, 1, 2, -2, 2, 0, 0, 0], 2.23e-6, 0.00e-6), |
73 | | TERM([0, 0, 2, 0, 1, 0, 0, 0], 1.67e-6, 0.00e-6), |
74 | | TERM([1, 0, 2, 0, 2, 0, 0, 0], 1.30e-6, 0.00e-6), |
75 | | TERM([0, 1, -2, 2, -2, 0, 0, 0], 0.93e-6, 0.00e-6), |
76 | | TERM([1, 0, 0, -2, 0, 0, 0, 0], 0.68e-6, 0.00e-6), |
77 | | TERM([0, 0, 2, -2, 1, 0, 0, 0], -0.55e-6, 0.00e-6), |
78 | | TERM([1, 0, -2, 0, -2, 0, 0, 0], 0.53e-6, 0.00e-6), |
79 | | TERM([0, 0, 0, 2, 0, 0, 0, 0], -0.27e-6, 0.00e-6), |
80 | | TERM([1, 0, 0, 0, 1, 0, 0, 0], -0.27e-6, 0.00e-6), |
81 | | TERM([1, 0, -2, -2, -2, 0, 0, 0], -0.26e-6, 0.00e-6), |
82 | | TERM([1, 0, 0, 0, -1, 0, 0, 0], -0.25e-6, 0.00e-6), |
83 | | TERM([1, 0, 2, 0, 1, 0, 0, 0], 0.22e-6, 0.00e-6), |
84 | | TERM([2, 0, 0, -2, 0, 0, 0, 0], -0.21e-6, 0.00e-6), |
85 | | TERM([2, 0, -2, 0, -1, 0, 0, 0], 0.20e-6, 0.00e-6), |
86 | | TERM([0, 0, 2, 2, 2, 0, 0, 0], 0.17e-6, 0.00e-6), |
87 | | TERM([2, 0, 2, 0, 2, 0, 0, 0], 0.13e-6, 0.00e-6), |
88 | | TERM([2, 0, 0, 0, 0, 0, 0, 0], -0.13e-6, 0.00e-6), |
89 | | TERM([1, 0, 2, -2, 2, 0, 0, 0], -0.12e-6, 0.00e-6), |
90 | | TERM([0, 0, 2, 0, 0, 0, 0, 0], -0.11e-6, 0.00e-6), |
91 | | ]; |
92 | | |
93 | | /* Terms of order t^3 */ |
94 | | const s3: [TERM; 4] = [ |
95 | | TERM([0, 0, 0, 0, 1, 0, 0, 0], 0.30e-6, -23.51e-6), |
96 | | TERM([0, 0, 2, -2, 2, 0, 0, 0], -0.03e-6, -1.39e-6), |
97 | | TERM([0, 0, 2, 0, 2, 0, 0, 0], -0.01e-6, -0.24e-6), |
98 | | TERM([0, 0, 0, 0, 2, 0, 0, 0], 0.00e-6, 0.22e-6), |
99 | | ]; |
100 | | |
101 | | /* Terms of order t^4 */ |
102 | | const s4: [TERM; 1] = [ |
103 | | /* 1-1 */ |
104 | | TERM([0, 0, 0, 0, 1, 0, 0, 0], -0.26e-6, -0.01e-6), |
105 | | ]; |
106 | | |
107 | | /// The CIO locator s, positioning the Celestial Intermediate Origin on |
108 | | /// the equator of the Celestial Intermediate Pole, given the CIP's X,Y |
109 | | /// coordinates. Compatible with IAU 2000A precession-nutation. |
110 | | /// |
111 | | /// Given: |
112 | | /// date1,date2 f64 TT as a 2-part Julian Date (Note 1) |
113 | | /// x,y f64 CIP coordinates (Note 3) |
114 | | /// |
115 | | /// Returned (function value): |
116 | | /// f64 the CIO locator s in radians (Note 2) |
117 | | /// |
118 | | /// Notes: |
119 | | /// |
120 | | /// 1) The TT date date1+date2 is a Julian Date, apportioned in any |
121 | | /// convenient way between the two arguments. For example, |
122 | | /// JD(TT)=2450123.7 could be expressed in any of these ways, |
123 | | /// among others: |
124 | | /// |
125 | | /// date1 date2 |
126 | | /// |
127 | | /// 2450123.7 0.0 (JD method) |
128 | | /// 2451545.0 -1421.3 (J2000 method) |
129 | | /// 2400000.5 50123.2 (MJD method) |
130 | | /// 2450123.5 0.2 (date & time method) |
131 | | /// |
132 | | /// The JD method is the most natural and convenient to use in |
133 | | /// cases where the loss of several decimal digits of resolution |
134 | | /// is acceptable. The J2000 method is best matched to the way |
135 | | /// the argument is handled internally and will deliver the |
136 | | /// optimum resolution. The MJD method and the date & time methods |
137 | | /// are both good compromises between resolution and convenience. |
138 | | /// |
139 | | /// 2) The CIO locator s is the difference between the right ascensions |
140 | | /// of the same point in two systems: the two systems are the GCRS |
141 | | /// and the CIP,CIO, and the point is the ascending node of the |
142 | | /// CIP equator. The quantity s remains below 0.1 arcsecond |
143 | | /// throughout 1900-2100. |
144 | | /// |
145 | | /// 3) The series used to compute s is in fact for s+XY/2, where X and Y |
146 | | /// are the x and y components of the CIP unit vector; this series |
147 | | /// is more compact than a direct series for s would be. This |
148 | | /// function requires X,Y to be supplied by the caller, who is |
149 | | /// responsible for providing values that are consistent with the |
150 | | /// supplied date. |
151 | | /// |
152 | | /// 4) The model is consistent with the IAU 2000A precession-nutation. |
153 | | /// |
154 | | /// References: |
155 | | /// |
156 | | /// Capitaine, N., Chapront, J., Lambert, S. and Wallace, P., |
157 | | /// "Expressions for the Celestial Intermediate Pole and Celestial |
158 | | /// Ephemeris Origin consistent with the IAU 2000A precession- |
159 | | /// nutation model", Astron.Astrophys. 400, 1145-1154 (2003) |
160 | | /// |
161 | | /// n.b. The celestial ephemeris origin (CEO) was renamed "celestial |
162 | | /// intermediate origin" (CIO) by IAU 2006 Resolution 2. |
163 | | /// |
164 | | /// McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), |
165 | | /// IERS Technical Note No. 32, BKG (2004) |
166 | 0 | pub fn s00(date1: f64, date2: f64, x: f64, y: f64) -> f64 { |
167 | | /* Interval between fundamental epoch J2000.0 and current date (JC). */ |
168 | 0 | let t = ((date1 - DJ00) + date2) / DJC; |
169 | | |
170 | | /* Fundamental Arguments (from IERS Conventions 2003) */ |
171 | | |
172 | 0 | let mut fa: [f64; 8] = [0.0; 8]; |
173 | | /* Mean anomaly of the Moon. */ |
174 | 0 | fa[0] = fal03(t); |
175 | | |
176 | | /* Mean anomaly of the Sun. */ |
177 | 0 | fa[1] = falp03(t); |
178 | | |
179 | | /* Mean longitude of the Moon minus that of the ascending node. */ |
180 | 0 | fa[2] = faf03(t); |
181 | | |
182 | | /* Mean elongation of the Moon from the Sun. */ |
183 | 0 | fa[3] = fad03(t); |
184 | | |
185 | | /* Mean longitude of the ascending node of the Moon. */ |
186 | 0 | fa[4] = faom03(t); |
187 | | |
188 | | /* Mean longitude of Venus. */ |
189 | 0 | fa[5] = fave03(t); |
190 | | |
191 | | /* Mean longitude of Earth. */ |
192 | 0 | fa[6] = fae03(t); |
193 | | |
194 | | /* General precession in longitude. */ |
195 | 0 | fa[7] = fapa03(t); |
196 | | |
197 | 0 | let [mut w0, mut w1, mut w2, mut w3, mut w4, w5] = sp; |
198 | 0 | for i in (0..s0.len()).rev() { |
199 | 0 | let nfa = s0[i].0; |
200 | 0 | let [s, c] = [s0[i].1, s0[i].2]; |
201 | 0 | let a = fa |
202 | 0 | .iter() |
203 | 0 | .zip(nfa.iter()) |
204 | 0 | .fold(0.0, |acc, (&fa, &nfa)| acc + fa * nfa as f64); |
205 | 0 | w0 += s * a.sin() + c * a.cos(); |
206 | | } |
207 | | |
208 | 0 | for i in (0..s1.len()).rev() { |
209 | 0 | let nfa = s1[i].0; |
210 | 0 | let [s, c] = [s1[i].1, s1[i].2]; |
211 | 0 | let a = fa |
212 | 0 | .iter() |
213 | 0 | .zip(nfa.iter()) |
214 | 0 | .fold(0.0, |acc, (&fa, &nfa)| acc + fa * nfa as f64); |
215 | 0 | w1 += s * a.sin() + c * a.cos(); |
216 | | } |
217 | | |
218 | 0 | for i in (0..s2.len()).rev() { |
219 | 0 | let nfa = s2[i].0; |
220 | 0 | let [s, c] = [s2[i].1, s2[i].2]; |
221 | 0 | let a = fa |
222 | 0 | .iter() |
223 | 0 | .zip(nfa.iter()) |
224 | 0 | .fold(0.0, |acc, (&fa, &nfa)| acc + fa * nfa as f64); |
225 | 0 | w2 += s * a.sin() + c * a.cos(); |
226 | | } |
227 | | |
228 | 0 | for i in (0..s3.len()).rev() { |
229 | 0 | let nfa = s3[i].0; |
230 | 0 | let [s, c] = [s3[i].1, s3[i].2]; |
231 | 0 | let a = fa |
232 | 0 | .iter() |
233 | 0 | .zip(nfa.iter()) |
234 | 0 | .fold(0.0, |acc, (&fa, &nfa)| acc + fa * nfa as f64); |
235 | 0 | w3 += s * a.sin() + c * a.cos(); |
236 | | } |
237 | | |
238 | 0 | for i in (0..s4.len()).rev() { |
239 | 0 | let nfa = s4[i].0; |
240 | 0 | let [s, c] = [s4[i].1, s4[i].2]; |
241 | 0 | let a = fa |
242 | 0 | .iter() |
243 | 0 | .zip(nfa.iter()) |
244 | 0 | .fold(0.0, |acc, (&fa, &nfa)| acc + fa * nfa as f64); |
245 | 0 | w4 += s * a.sin() + c * a.cos(); |
246 | | } |
247 | | |
248 | 0 | let s = (w0 + (w1 + (w2 + (w3 + (w4 + w5 * t) * t) * t) * t) * t) * DAS2R - x * y / 2.0; |
249 | | |
250 | 0 | s |
251 | 0 | } |