1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.models.earth.displacement;
18
19 import java.util.HashMap;
20 import java.util.Map;
21 import java.util.function.Function;
22
23 import org.hipparchus.analysis.UnivariateFunction;
24 import org.hipparchus.analysis.interpolation.SplineInterpolator;
25 import org.hipparchus.analysis.polynomials.PolynomialSplineFunction;
26 import org.hipparchus.geometry.euclidean.threed.Vector3D;
27 import org.hipparchus.util.FastMath;
28 import org.hipparchus.util.SinCos;
29 import org.orekit.bodies.GeodeticPoint;
30 import org.orekit.bodies.OneAxisEllipsoid;
31 import org.orekit.data.BodiesElements;
32 import org.orekit.frames.Frame;
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 public class OceanLoading implements StationDisplacement {
144
145
146
147 private static final double[] CARTWRIGHT_EDDEN_AMPLITUDE = {
148 0.632208, 0.294107, 0.121046, 0.079915, 0.023818, -0.023589, 0.022994,
149 0.019333, -0.017871, 0.017192, 0.016018, 0.004671, -0.004662, -0.004519,
150 0.004470, 0.004467, 0.002589, -0.002455, -0.002172, 0.001972, 0.001947,
151 0.001914, -0.001898, 0.001802, 0.001304, 0.001170, 0.001130, 0.001061,
152 -0.001022, -0.001017, 0.001014, 0.000901, -0.000857, 0.000855, 0.000855,
153 0.000772, 0.000741, 0.000741, -0.000721, 0.000698, 0.000658, 0.000654,
154 -0.000653, 0.000633, 0.000626, -0.000598, 0.000590, 0.000544, 0.000479,
155 -0.000464, 0.000413, -0.000390, 0.000373, 0.000366, 0.000366, -0.000360,
156 -0.000355, 0.000354, 0.000329, 0.000328, 0.000319, 0.000302, 0.000279,
157 -0.000274, -0.000272, 0.000248, -0.000225, 0.000224, -0.000223, -0.000216,
158 0.000211, 0.000209, 0.000194, 0.000185, -0.000174, -0.000171, 0.000159,
159 0.000131, 0.000127, 0.000120, 0.000118, 0.000117, 0.000108, 0.000107,
160 0.000105, -0.000102, 0.000102, 0.000099, -0.000096, 0.000095, -0.000089,
161 -0.000085, -0.000084, -0.000081, -0.000077, -0.000072, -0.000067, 0.000066,
162 0.000064, 0.000063, 0.000063, 0.000063, 0.000062, 0.000062, -0.000060,
163 0.000056, 0.000053, 0.000051, 0.000050, 0.368645, -0.262232, -0.121995,
164 -0.050208, 0.050031, -0.049470, 0.020620, 0.020613, 0.011279, -0.009530,
165 -0.009469, -0.008012, 0.007414, -0.007300, 0.007227, -0.007131, -0.006644,
166 0.005249, 0.004137, 0.004087, 0.003944, 0.003943, 0.003420, 0.003418,
167 0.002885, 0.002884, 0.002160, -0.001936, 0.001934, -0.001798, 0.001690,
168 0.001689, 0.001516, 0.001514, -0.001511, 0.001383, 0.001372, 0.001371,
169 -0.001253, -0.001075, 0.001020, 0.000901, 0.000865, -0.000794, 0.000788,
170 0.000782, -0.000747, -0.000745, 0.000670, -0.000603, -0.000597, 0.000542,
171 0.000542, -0.000541, -0.000469, -0.000440, 0.000438, 0.000422, 0.000410,
172 -0.000374, -0.000365, 0.000345, 0.000335, -0.000321, -0.000319, 0.000307,
173 0.000291, 0.000290, -0.000289, 0.000286, 0.000275, 0.000271, 0.000263,
174 -0.000245, 0.000225, 0.000225, 0.000221, -0.000202, -0.000200, -0.000199,
175 0.000192, 0.000183, 0.000183, 0.000183, -0.000170, 0.000169, 0.000168,
176 0.000162, 0.000149, -0.000147, -0.000141, 0.000138, 0.000136, 0.000136,
177 0.000127, 0.000127, -0.000126, -0.000121, -0.000121, 0.000117, -0.000116,
178 -0.000114, -0.000114, -0.000114, 0.000114, 0.000113, 0.000109, 0.000108,
179 0.000106, -0.000106, -0.000106, 0.000105, 0.000104, -0.000103, -0.000100,
180 -0.000100, -0.000100, 0.000099, -0.000098, 0.000093, 0.000093, 0.000090,
181 -0.000088, 0.000083, -0.000083, -0.000082, -0.000081, -0.000079, -0.000077,
182 -0.000075, -0.000075, -0.000075, 0.000071, 0.000071, -0.000071, 0.000068,
183 0.000068, 0.000065, 0.000065, 0.000064, 0.000064, 0.000064, -0.000064,
184 -0.000060, 0.000056, 0.000056, 0.000053, 0.000053, 0.000053, -0.000053,
185 0.000053, 0.000053, 0.000052, 0.000050, -0.066607, -0.035184, -0.030988,
186 0.027929, -0.027616, -0.012753, -0.006728, -0.005837, -0.005286, -0.004921,
187 -0.002884, -0.002583, -0.002422, 0.002310, 0.002283, -0.002037, 0.001883,
188 -0.001811, -0.001687, -0.001004, -0.000925, -0.000844, 0.000766, 0.000766,
189 -0.000700, -0.000495, -0.000492, 0.000491, 0.000483, 0.000437, -0.000416,
190 -0.000384, 0.000374, -0.000312, -0.000288, -0.000273, 0.000259, 0.000245,
191 -0.000232, 0.000229, -0.000216, 0.000206, -0.000204, -0.000202, 0.000200,
192 0.000195, -0.000190, 0.000187, 0.000180, -0.000179, 0.000170, 0.000153,
193 -0.000137, -0.000119, -0.000119, -0.000112, -0.000110, -0.000110, 0.000107,
194 -0.000095, -0.000095, -0.000091, -0.000090, -0.000081, -0.000079, -0.000079,
195 0.000077, -0.000073, 0.000069, -0.000067, -0.000066, 0.000065, 0.000064,
196 -0.000062, 0.000060, 0.000059, -0.000056, 0.000055, -0.000051
197 };
198
199
200
201
202 private static final int[][] DOODSON_ARGUMENTS = {
203 { 2, 0, 0, 0, 0, 0 }, { 2, 2, -2, 0, 0, 0 }, { 2, -1, 0, 1, 0, 0 },
204 { 2, 2, 0, 0, 0, 0 }, { 2, 2, 0, 0, 1, 0 }, { 2, 0, 0, 0, -1, 0 },
205 { 2, -1, 2, -1, 0, 0 }, { 2, -2, 2, 0, 0, 0 }, { 2, 1, 0, -1, 0, 0 },
206 { 2, 2, -3, 0, 0, 1 }, { 2, -2, 0, 2, 0, 0 }, { 2, -3, 2, 1, 0, 0 },
207 { 2, 1, -2, 1, 0, 0 }, { 2, -1, 0, 1, -1, 0 }, { 2, 3, 0, -1, 0, 0 },
208 { 2, 1, 0, 1, 0, 0 }, { 2, 2, 0, 0, 2, 0 }, { 2, 2, -1, 0, 0, -1 },
209 { 2, 0, -1, 0, 0, 1 }, { 2, 1, 0, 1, 1, 0 }, { 2, 3, 0, -1, 1, 0 },
210 { 2, 0, 1, 0, 0, -1 }, { 2, 0, -2, 2, 0, 0 }, { 2, -3, 0, 3, 0, 0 },
211 { 2, -2, 3, 0, 0, -1 }, { 2, 4, 0, 0, 0, 0 }, { 2, -1, 1, 1, 0, -1 },
212 { 2, -1, 3, -1, 0, -1 }, { 2, 2, 0, 0, -1, 0 }, { 2, -1, -1, 1, 0, 1 },
213 { 2, 4, 0, 0, 1, 0 }, { 2, -3, 4, -1, 0, 0 }, { 2, -1, 2, -1, -1, 0 },
214 { 2, 3, -2, 1, 0, 0 }, { 2, 1, 2, -1, 0, 0 }, { 2, -4, 2, 2, 0, 0 },
215 { 2, 4, -2, 0, 0, 0 }, { 2, 0, 2, 0, 0, 0 }, { 2, -2, 2, 0, -1, 0 },
216 { 2, 2, -4, 0, 0, 2 }, { 2, 2, -2, 0, -1, 0 }, { 2, 1, 0, -1, -1, 0 },
217 { 2, -1, 1, 0, 0, 0 }, { 2, 2, -1, 0, 0, 1 }, { 2, 2, 1, 0, 0, -1 },
218 { 2, -2, 0, 2, -1, 0 }, { 2, -2, 4, -2, 0, 0 }, { 2, 2, 2, 0, 0, 0 },
219 { 2, -4, 4, 0, 0, 0 }, { 2, -1, 0, -1, -2, 0 }, { 2, 1, 2, -1, 1, 0 },
220 { 2, -1, -2, 3, 0, 0 }, { 2, 3, -2, 1, 1, 0 }, { 2, 4, 0, -2, 0, 0 },
221 { 2, 0, 0, 2, 0, 0 }, { 2, 0, 2, -2, 0, 0 }, { 2, 0, 2, 0, 1, 0 },
222 { 2, -3, 3, 1, 0, -1 }, { 2, 0, 0, 0, -2, 0 }, { 2, 4, 0, 0, 2, 0 },
223 { 2, 4, -2, 0, 1, 0 }, { 2, 0, 0, 0, 0, 2 }, { 2, 1, 0, 1, 2, 0 },
224 { 2, 0, -2, 0, -2, 0 }, { 2, -2, 1, 0, 0, 1 }, { 2, -2, 1, 2, 0, -1 },
225 { 2, -1, 1, -1, 0, 1 }, { 2, 5, 0, -1, 0, 0 }, { 2, 1, -3, 1, 0, 1 },
226 { 2, -2, -1, 2, 0, 1 }, { 2, 3, 0, -1, 2, 0 }, { 2, 1, -2, 1, -1, 0 },
227 { 2, 5, 0, -1, 1, 0 }, { 2, -4, 0, 4, 0, 0 }, { 2, -3, 2, 1, -1, 0 },
228 { 2, -2, 1, 1, 0, 0 }, { 2, 4, 0, -2, 1, 0 }, { 2, 0, 0, 2, 1, 0 },
229 { 2, -5, 4, 1, 0, 0 }, { 2, 0, 2, 0, 2, 0 }, { 2, -1, 2, 1, 0, 0 },
230 { 2, 5, -2, -1, 0, 0 }, { 2, 1, -1, 0, 0, 0 }, { 2, 2, -2, 0, 0, 2 },
231 { 2, -5, 2, 3, 0, 0 }, { 2, -1, -2, 1, -2, 0 }, { 2, -3, 5, -1, 0, -1 },
232 { 2, -1, 0, 0, 0, 1 }, { 2, -2, 0, 0, -2, 0 }, { 2, 0, -1, 1, 0, 0 },
233 { 2, -3, 1, 1, 0, 1 }, { 2, 3, 0, -1, -1, 0 }, { 2, 1, 0, 1, -1, 0 },
234 { 2, -1, 2, 1, 1, 0 }, { 2, 0, -3, 2, 0, 1 }, { 2, 1, -1, -1, 0, 1 },
235 { 2, -3, 0, 3, -1, 0 }, { 2, 0, -2, 2, -1, 0 }, { 2, -4, 3, 2, 0, -1 },
236 { 2, -1, 0, 1, -2, 0 }, { 2, 5, 0, -1, 2, 0 }, { 2, -4, 5, 0, 0, -1 },
237 { 2, -2, 4, 0, 0, -2 }, { 2, -1, 0, 1, 0, 2 }, { 2, -2, -2, 4, 0, 0 },
238 { 2, 3, -2, -1, -1, 0 }, { 2, -2, 5, -2, 0, -1 }, { 2, 0, -1, 0, -1, 1 },
239 { 2, 5, -2, -1, 1, 0 }, { 1, 1, 0, 0, 0, 0 }, { 1, -1, 0, 0, 0, 0 },
240 { 1, 1, -2, 0, 0, 0 }, { 1, -2, 0, 1, 0, 0 }, { 1, 1, 0, 0, 1, 0 },
241 { 1, -1, 0, 0, -1, 0 }, { 1, 2, 0, -1, 0, 0 }, { 1, 0, 0, 1, 0, 0 },
242 { 1, 3, 0, 0, 0, 0 }, { 1, -2, 2, -1, 0, 0 }, { 1, -2, 0, 1, -1, 0 },
243 { 1, -3, 2, 0, 0, 0 }, { 1, 0, 0, -1, 0, 0 }, { 1, 1, 0, 0, -1, 0 },
244 { 1, 3, 0, 0, 1, 0 }, { 1, 1, -3, 0, 0, 1 }, { 1, -3, 0, 2, 0, 0 },
245 { 1, 1, 2, 0, 0, 0 }, { 1, 0, 0, 1, 1, 0 }, { 1, 2, 0, -1, 1, 0 },
246 { 1, 0, 2, -1, 0, 0 }, { 1, 2, -2, 1, 0, 0 }, { 1, 3, -2, 0, 0, 0 },
247 { 1, -1, 2, 0, 0, 0 }, { 1, 1, 1, 0, 0, -1 }, { 1, 1, -1, 0, 0, 1 },
248 { 1, 4, 0, -1, 0, 0 }, { 1, -4, 2, 1, 0, 0 }, { 1, 0, -2, 1, 0, 0 },
249 { 1, -2, 2, -1, -1, 0 }, { 1, 3, 0, -2, 0, 0 }, { 1, -1, 0, 2, 0, 0 },
250 { 1, -1, 0, 0, -2, 0 }, { 1, 3, 0, 0, 2, 0 }, { 1, -3, 2, 0, -1, 0 },
251 { 1, 4, 0, -1, 1, 0 }, { 1, 0, 0, -1, -1, 0 }, { 1, 1, -2, 0, -1, 0 },
252 { 1, -3, 0, 2, -1, 0 }, { 1, 1, 0, 0, 2, 0 }, { 1, 1, -1, 0, 0, -1 },
253 { 1, -1, -1, 0, 0, 1 }, { 1, 0, 2, -1, 1, 0 }, { 1, -1, 1, 0, 0, -1 },
254 { 1, -1, -2, 2, 0, 0 }, { 1, 2, -2, 1, 1, 0 }, { 1, -4, 0, 3, 0, 0 },
255 { 1, -1, 2, 0, 1, 0 }, { 1, 3, -2, 0, 1, 0 }, { 1, 2, 0, -1, -1, 0 },
256 { 1, 0, 0, 1, -1, 0 }, { 1, -2, 2, 1, 0, 0 }, { 1, 4, -2, -1, 0, 0 },
257 { 1, -3, 3, 0, 0, -1 }, { 1, -2, 1, 1, 0, -1 }, { 1, -2, 3, -1, 0, -1 },
258 { 1, 0, -2, 1, -1, 0 }, { 1, -2, -1, 1, 0, 1 }, { 1, 4, -2, 1, 0, 0 },
259 { 1, -4, 4, -1, 0, 0 }, { 1, -4, 2, 1, -1, 0 }, { 1, 5, -2, 0, 0, 0 },
260 { 1, 3, 0, -2, 1, 0 }, { 1, -5, 2, 2, 0, 0 }, { 1, 2, 0, 1, 0, 0 },
261 { 1, 1, 3, 0, 0, -1 }, { 1, -2, 0, 1, -2, 0 }, { 1, 4, 0, -1, 2, 0 },
262 { 1, 1, -4, 0, 0, 2 }, { 1, 5, 0, -2, 0, 0 }, { 1, -1, 0, 2, 1, 0 },
263 { 1, -2, 1, 0, 0, 0 }, { 1, 4, -2, 1, 1, 0 }, { 1, -3, 4, -2, 0, 0 },
264 { 1, -1, 3, 0, 0, -1 }, { 1, 3, -3, 0, 0, 1 }, { 1, 5, -2, 0, 1, 0 },
265 { 1, 1, 2, 0, 1, 0 }, { 1, 2, 0, 1, 1, 0 }, { 1, -5, 4, 0, 0, 0 },
266 { 1, -2, 0, -1, -2, 0 }, { 1, 5, 0, -2, 1, 0 }, { 1, 1, 2, -2, 0, 0 },
267 { 1, 1, -2, 2, 0, 0 }, { 1, -2, 2, 1, 1, 0 }, { 1, 0, 3, -1, 0, -1 },
268 { 1, 2, -3, 1, 0, 1 }, { 1, -2, -2, 3, 0, 0 }, { 1, -1, 2, -2, 0, 0 },
269 { 1, -4, 3, 1, 0, -1 }, { 1, -4, 0, 3, -1, 0 }, { 1, -1, -2, 2, -1, 0 },
270 { 1, -2, 0, 3, 0, 0 }, { 1, 4, 0, -3, 0, 0 }, { 1, 0, 1, 1, 0, -1 },
271 { 1, 2, -1, -1, 0, 1 }, { 1, 2, -2, 1, -1, 0 }, { 1, 0, 0, -1, -2, 0 },
272 { 1, 2, 0, 1, 2, 0 }, { 1, 2, -2, -1, -1, 0 }, { 1, 0, 0, 1, 2, 0 },
273 { 1, 0, 1, 0, 0, 0 }, { 1, 2, -1, 0, 0, 0 }, { 1, 0, 2, -1, -1, 0 },
274 { 1, -1, -2, 0, -2, 0 }, { 1, -3, 1, 0, 0, 1 }, { 1, 3, -2, 0, -1, 0 },
275 { 1, -1, -1, 0, -1, 1 }, { 1, 4, -2, -1, 1, 0 }, { 1, 2, 1, -1, 0, -1 },
276 { 1, 0, -1, 1, 0, 1 }, { 1, -2, 4, -1, 0, 0 }, { 1, 4, -4, 1, 0, 0 },
277 { 1, -3, 1, 2, 0, -1 }, { 1, -3, 3, 0, -1, -1 }, { 1, 1, 2, 0, 2, 0 },
278 { 1, 1, -2, 0, -2, 0 }, { 1, 3, 0, 0, 3, 0 }, { 1, -1, 2, 0, -1, 0 },
279 { 1, -2, 1, -1, 0, 1 }, { 1, 0, -3, 1, 0, 1 }, { 1, -3, -1, 2, 0, 1 },
280 { 1, 2, 0, -1, 2, 0 }, { 1, 6, -2, -1, 0, 0 }, { 1, 2, 2, -1, 0, 0 },
281 { 1, -1, 1, 0, -1, -1 }, { 1, -2, 3, -1, -1, -1 }, { 1, -1, 0, 0, 0, 2 },
282 { 1, -5, 0, 4, 0, 0 }, { 1, 1, 0, 0, 0, -2 }, { 1, -2, 1, 1, -1, -1 },
283 { 1, 1, -1, 0, 1, 1 }, { 1, 1, 2, 0, 0, -2 }, { 1, -3, 1, 1, 0, 0 },
284 { 1, -4, 4, -1, -1, 0 }, { 1, 1, 0, -2, -1, 0 }, { 1, -2, -1, 1, -1, 1 },
285 { 1, -3, 2, 2, 0, 0 }, { 1, 5, -2, -2, 0, 0 }, { 1, 3, -4, 2, 0, 0 },
286 { 1, 1, -2, 0, 0, 2 }, { 1, -1, 4, -2, 0, 0 }, { 1, 2, 2, -1, 1, 0 },
287 { 1, -5, 2, 2, -1, 0 }, { 1, 1, -3, 0, -1, 1 }, { 1, 1, 1, 0, 1, -1 },
288 { 1, 6, -2, -1, 1, 0 }, { 1, -2, 2, -1, -2, 0 }, { 1, 4, -2, 1, 2, 0 },
289 { 1, -6, 4, 1, 0, 0 }, { 1, 5, -4, 0, 0, 0 }, { 1, -3, 4, 0, 0, 0 },
290 { 1, 1, 2, -2, 1, 0 }, { 1, -2, 1, 0, -1, 0 }, { 0, 2, 0, 0, 0, 0 },
291 { 0, 1, 0, -1, 0, 0 }, { 0, 0, 2, 0, 0, 0 }, { 0, 0, 0, 0, 1, 0 },
292 { 0, 2, 0, 0, 1, 0 }, { 0, 3, 0, -1, 0, 0 }, { 0, 1, -2, 1, 0, 0 },
293 { 0, 2, -2, 0, 0, 0 }, { 0, 3, 0, -1, 1, 0 }, { 0, 0, 1, 0, 0, -1 },
294 { 0, 2, 0, -2, 0, 0 }, { 0, 2, 0, 0, 2, 0 }, { 0, 3, -2, 1, 0, 0 },
295 { 0, 1, 0, -1, -1, 0 }, { 0, 1, 0, -1, 1, 0 }, { 0, 4, -2, 0, 0, 0 },
296 { 0, 1, 0, 1, 0, 0 }, { 0, 0, 3, 0, 0, -1 }, { 0, 4, 0, -2, 0, 0 },
297 { 0, 3, -2, 1, 1, 0 }, { 0, 3, -2, -1, 0, 0 }, { 0, 4, -2, 0, 1, 0 },
298 { 0, 0, 2, 0, 1, 0 }, { 0, 1, 0, 1, 1, 0 }, { 0, 4, 0, -2, 1, 0 },
299 { 0, 3, 0, -1, 2, 0 }, { 0, 5, -2, -1, 0, 0 }, { 0, 1, 2, -1, 0, 0 },
300 { 0, 1, -2, 1, -1, 0 }, { 0, 1, -2, 1, 1, 0 }, { 0, 2, -2, 0, -1, 0 },
301 { 0, 2, -3, 0, 0, 1 }, { 0, 2, -2, 0, 1, 0 }, { 0, 0, 2, -2, 0, 0 },
302 { 0, 1, -3, 1, 0, 1 }, { 0, 0, 0, 0, 2, 0 }, { 0, 0, 1, 0, 0, 1 },
303 { 0, 1, 2, -1, 1, 0 }, { 0, 3, 0, -3, 0, 0 }, { 0, 2, 1, 0, 0, -1 },
304 { 0, 1, -1, -1, 0, 1 }, { 0, 1, 0, 1, 2, 0 }, { 0, 5, -2, -1, 1, 0 },
305 { 0, 2, -1, 0, 0, 1 }, { 0, 2, 2, -2, 0, 0 }, { 0, 1, -1, 0, 0, 0 },
306 { 0, 5, 0, -3, 0, 0 }, { 0, 2, 0, -2, 1, 0 }, { 0, 1, 1, -1, 0, -1 },
307 { 0, 3, -4, 1, 0, 0 }, { 0, 0, 2, 0, 2, 0 }, { 0, 2, 0, -2, -1, 0 },
308 { 0, 4, -3, 0, 0, 1 }, { 0, 3, -1, -1, 0, 1 }, { 0, 0, 2, 0, 0, -2 },
309 { 0, 3, -3, 1, 0, 1 }, { 0, 2, -4, 2, 0, 0 }, { 0, 4, -2, -2, 0, 0 },
310 { 0, 3, 1, -1, 0, -1 }, { 0, 5, -4, 1, 0, 0 }, { 0, 3, -2, -1, -1, 0 },
311 { 0, 3, -2, 1, 2, 0 }, { 0, 4, -4, 0, 0, 0 }, { 0, 6, -2, -2, 0, 0 },
312 { 0, 5, 0, -3, 1, 0 }, { 0, 4, -2, 0, 2, 0 }, { 0, 2, 2, -2, 1, 0 },
313 { 0, 0, 4, 0, 0, -2 }, { 0, 3, -1, 0, 0, 0 }, { 0, 3, -3, -1, 0, 1 },
314 { 0, 4, 0, -2, 2, 0 }, { 0, 1, -2, -1, -1, 0 }, { 0, 2, -1, 0, 0, -1 },
315 { 0, 4, -4, 2, 0, 0 }, { 0, 2, 1, 0, 1, -1 }, { 0, 3, -2, -1, 1, 0 },
316 { 0, 4, -3, 0, 1, 1 }, { 0, 2, 0, 0, 3, 0 }, { 0, 6, -4, 0, 0, 0 }
317 };
318
319
320
321 private static final Map<Tide, Double> CARTWRIGHT_EDDEN_AMPLITUDE_MAP;
322
323 static {
324 CARTWRIGHT_EDDEN_AMPLITUDE_MAP = new HashMap<>(CARTWRIGHT_EDDEN_AMPLITUDE.length);
325 for (int i = 0; i < CARTWRIGHT_EDDEN_AMPLITUDE.length; ++i) {
326 CARTWRIGHT_EDDEN_AMPLITUDE_MAP.put(new Tide(DOODSON_ARGUMENTS[i][0], DOODSON_ARGUMENTS[i][1], DOODSON_ARGUMENTS[i][2],
327 DOODSON_ARGUMENTS[i][3], DOODSON_ARGUMENTS[i][4], DOODSON_ARGUMENTS[i][5]),
328 CARTWRIGHT_EDDEN_AMPLITUDE[i]);
329 }
330 }
331
332
333 private final OneAxisEllipsoid earth;
334
335
336 private final MainTideData[][] mainTides;
337
338
339
340
341
342
343 public OceanLoading(final OneAxisEllipsoid earth, final OceanLoadingCoefficients coefficients) {
344
345 this.earth = earth;
346
347
348
349 mainTides = new MainTideData[coefficients.getNbSpecies()][];
350 for (int i = 0; i < mainTides.length; ++i) {
351 mainTides[i] = new MainTideData[coefficients.getNbTides(i)];
352 for (int j = 0; j < mainTides[i].length; ++j) {
353 final double amplitude = CARTWRIGHT_EDDEN_AMPLITUDE_MAP.get(coefficients.getTide(i, j));
354 mainTides[i][j] = new MainTideData(coefficients, i, j, FastMath.abs(amplitude));
355 }
356 }
357
358 }
359
360
361 @Override
362 public Vector3D displacement(final BodiesElements elements, final Frame earthFrame,
363 final Vector3D referencePoint) {
364
365
366 final UnivariateFunction[] realZSpline = new UnivariateFunction[mainTides.length];
367 final UnivariateFunction[] imaginaryZSpline = new UnivariateFunction[mainTides.length];
368 final UnivariateFunction[] realWSpline = new UnivariateFunction[mainTides.length];
369 final UnivariateFunction[] imaginaryWSpline = new UnivariateFunction[mainTides.length];
370 final UnivariateFunction[] realSSpline = new UnivariateFunction[mainTides.length];
371 final UnivariateFunction[] imaginarySSpline = new UnivariateFunction[mainTides.length];
372
373
374 for (int i = 0; i < mainTides.length; ++i) {
375
376
377 final double[] rates = new double[mainTides[i].length];
378 for (int j = 0; j < rates.length; ++j) {
379 rates[j] = mainTides[i][j].tide.getRate(elements);
380 }
381
382
383 realZSpline[i] = spline(rates, mainTides[i], d -> d.realZ);
384 imaginaryZSpline[i] = spline(rates, mainTides[i], d -> d.imaginaryZ);
385 realWSpline[i] = spline(rates, mainTides[i], d -> d.realW);
386 imaginaryWSpline[i] = spline(rates, mainTides[i], d -> d.imaginaryW);
387 realSSpline[i] = spline(rates, mainTides[i], d -> d.realS);
388 imaginarySSpline[i] = spline(rates, mainTides[i], d -> d.imaginaryS);
389
390 }
391
392
393 double dz = 0;
394 double dw = 0;
395 double ds = 0;
396 for (final Map.Entry<Tide, Double> entry : CARTWRIGHT_EDDEN_AMPLITUDE_MAP.entrySet()) {
397
398 final Tide tide = entry.getKey();
399 final double amplitude = entry.getValue();
400 final int i = tide.getTauMultiplier();
401 final double rate = tide.getRate(elements);
402
403
404 final double rZ = realZSpline[i].value(rate);
405 final double iZ = imaginaryZSpline[i].value(rate);
406 final double rW = realWSpline[i].value(rate);
407 final double iW = imaginaryWSpline[i].value(rate);
408 final double rS = realSSpline[i].value(rate);
409 final double iS = imaginarySSpline[i].value(rate);
410
411
412 final double correction;
413 if (tide.getTauMultiplier() == 0) {
414 correction = FastMath.PI;
415 } else if (tide.getTauMultiplier() == 1) {
416 correction = 0.5 * FastMath.PI;
417 } else {
418 correction = 0.0;
419 }
420 final double phase = tide.getPhase(elements) + correction;
421
422 dz += amplitude * FastMath.hypot(rZ, iZ) * FastMath.cos(phase + FastMath.atan2(iZ, rZ));
423 dw += amplitude * FastMath.hypot(rW, iW) * FastMath.cos(phase + FastMath.atan2(iW, rW));
424 ds += amplitude * FastMath.hypot(rS, iS) * FastMath.cos(phase + FastMath.atan2(iS, rS));
425
426 }
427
428
429 final GeodeticPoint gp = earth.transform(referencePoint, earthFrame, elements.getDate());
430 return new Vector3D(dz, gp.getZenith(),
431 dw, gp.getWest(),
432 ds, gp.getSouth());
433
434 }
435
436
437
438
439
440
441
442 private UnivariateFunction spline(final double[] rates, final MainTideData[] data,
443 final Function<MainTideData, Double> selector) {
444 final double[] y = new double[data.length];
445 for (int i = 0; i < y.length; ++i) {
446 y[i] = selector.apply(data[i]);
447 }
448 final PolynomialSplineFunction psf = new SplineInterpolator().interpolate(rates, y);
449
450
451
452
453
454
455 final double[] knots = psf.getKnots();
456 final double minRate = knots[0];
457 final double valueAtMinRate = psf.value(minRate);
458 final double maxRate = knots[knots.length - 1];
459 final double valueAtMaxRate = psf.value(maxRate);
460 return t -> (t < minRate) ? valueAtMinRate : (t > maxRate) ? valueAtMaxRate : psf.value(t);
461
462 }
463
464
465 private static class MainTideData {
466
467
468 private final Tide tide;
469
470
471 private final double realZ;
472
473
474 private final double imaginaryZ;
475
476
477 private final double realW;
478
479
480 private final double imaginaryW;
481
482
483 private final double realS;
484
485
486 private final double imaginaryS;
487
488
489
490
491
492
493
494 MainTideData(final OceanLoadingCoefficients coefficients, final int i, final int j, final double absAmplitude) {
495
496 final SinCos scZenith = FastMath.sinCos(coefficients.getZenithPhase(i, j));
497 final SinCos scWest = FastMath.sinCos(coefficients.getWestPhase(i, j));
498 final SinCos scSouth = FastMath.sinCos(coefficients.getSouthPhase(i, j));
499
500 tide = coefficients.getTide(i, j);
501 realZ = coefficients.getZenithAmplitude(i, j) * scZenith.cos() / absAmplitude;
502 imaginaryZ = coefficients.getZenithAmplitude(i, j) * scZenith.sin() / absAmplitude;
503 realW = coefficients.getWestAmplitude(i, j) * scWest.cos() / absAmplitude;
504 imaginaryW = coefficients.getWestAmplitude(i, j) * scWest.sin() / absAmplitude;
505 realS = coefficients.getSouthAmplitude(i, j) * scSouth.cos() / absAmplitude;
506 imaginaryS = coefficients.getSouthAmplitude(i, j) * scSouth.sin() / absAmplitude;
507 }
508
509 }
510
511 }
512