1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.semianalytical.dsst.forces;
18
19 import org.hipparchus.geometry.euclidean.threed.Vector3D;
20 import org.hipparchus.util.CombinatoricsUtils;
21 import org.hipparchus.util.FastMath;
22 import org.orekit.bodies.CelestialBody;
23 import org.orekit.propagation.semianalytical.dsst.utilities.AuxiliaryElements;
24 import org.orekit.propagation.semianalytical.dsst.utilities.CoefficientsFactory;
25 import org.orekit.propagation.semianalytical.dsst.utilities.UpperBounds;
26
27
28
29
30
31
32
33
34
35
36 public class DSSTThirdBodyContext extends ForceModelContext {
37
38
39 private static final int MAX_POWER = 22;
40
41
42 private static final double BIG_TRUNCATION_TOLERANCE = 1.e-1;
43
44
45 private static final double SMALL_TRUNCATION_TOLERANCE = 1.9e-6;
46
47
48 private static final int MAX_ECCPOWER_SP = 4;
49
50
51 private int maxAR3Pow;
52
53
54 private int maxEccPow;
55
56
57 private double[] aoR3Pow;
58
59
60 private int maxEccPowShort;
61
62
63 private int maxFreqF;
64
65
66 private double[][] Qns;
67
68
69 private final double gm;
70
71
72 private double R3;
73
74
75 private final double A;
76
77
78
79 private double alpha;
80
81 private double beta;
82
83 private double gamma;
84
85
86 private double BB;
87
88 private double BBB;
89
90
91 private double X;
92
93 private double XX;
94
95 private double XXX;
96
97 private double m2aoA;
98
99 private double BoA;
100
101 private double ooAB;
102
103 private double mCo2AB;
104
105 private double BoABpo;
106
107
108 private double muoR3;
109
110
111 private double b;
112
113
114 private double hXXX;
115
116 private double kXXX;
117
118
119 private final double motion;
120
121
122
123
124
125
126
127
128 DSSTThirdBodyContext(final AuxiliaryElements auxiliaryElements, final CelestialBody thirdBody, final double[] parameters) {
129
130 super(auxiliaryElements);
131
132 final double mu = parameters[1];
133 A = FastMath.sqrt(mu * auxiliaryElements.getSma());
134 this.gm = parameters[0];
135
136
137 final double absA = FastMath.abs(auxiliaryElements.getSma());
138 motion = FastMath.sqrt(mu / absA) / absA;
139
140
141 final Vector3D bodyPos = thirdBody.getPVCoordinates(auxiliaryElements.getDate(), auxiliaryElements.getFrame()).getPosition();
142 R3 = bodyPos.getNorm();
143
144
145 final Vector3D bodyDir = bodyPos.normalize();
146 alpha = bodyDir.dotProduct(auxiliaryElements.getVectorF());
147 beta = bodyDir.dotProduct(auxiliaryElements.getVectorG());
148 gamma = bodyDir.dotProduct(auxiliaryElements.getVectorW());
149
150
151 BB = auxiliaryElements.getB() * auxiliaryElements.getB();
152
153 BBB = BB * auxiliaryElements.getB();
154
155
156 b = 1. / (1. + auxiliaryElements.getB());
157
158
159 X = 1. / auxiliaryElements.getB();
160 XX = X * X;
161 XXX = X * XX;
162
163 m2aoA = -2. * auxiliaryElements.getSma() / A;
164
165 BoA = auxiliaryElements.getB() / A;
166
167 ooAB = 1. / (A * auxiliaryElements.getB());
168
169 mCo2AB = -auxiliaryElements.getC() * ooAB / 2.;
170
171 BoABpo = BoA / (1. + auxiliaryElements.getB());
172
173
174 muoR3 = gm / R3;
175
176
177 hXXX = auxiliaryElements.getH() * XXX;
178
179 kXXX = auxiliaryElements.getK() * XXX;
180
181
182 final double aoR3 = auxiliaryElements.getSma() / R3;
183 final double tol = ( aoR3 > .3 || aoR3 > .15 && auxiliaryElements.getEcc() > .25 ) ? BIG_TRUNCATION_TOLERANCE : SMALL_TRUNCATION_TOLERANCE;
184
185
186
187 final double eo2 = FastMath.max(0.0025, auxiliaryElements.getEcc() / 2.);
188 final double x2o2 = XX / 2.;
189 final double[] eccPwr = new double[MAX_POWER];
190 final double[] chiPwr = new double[MAX_POWER];
191 eccPwr[0] = 1.;
192 chiPwr[0] = X;
193 for (int i = 1; i < MAX_POWER; i++) {
194 eccPwr[i] = eccPwr[i - 1] * eo2;
195 chiPwr[i] = chiPwr[i - 1] * x2o2;
196 }
197
198
199 final double ao2rxx = aoR3 / (2. * XX);
200 double xmuarn = ao2rxx * ao2rxx * gm / (X * R3);
201 double term = 0.;
202
203
204 maxAR3Pow = 2;
205 maxEccPow = 0;
206 int n = 2;
207 int m = 2;
208 int nsmd2 = 0;
209
210 do {
211
212 term = xmuarn *
213 (CombinatoricsUtils.factorialDouble(n + m) / (CombinatoricsUtils.factorialDouble(nsmd2) * CombinatoricsUtils.factorialDouble(nsmd2 + m))) *
214 (CombinatoricsUtils.factorialDouble(n + m + 1) / (CombinatoricsUtils.factorialDouble(m) * CombinatoricsUtils.factorialDouble(n + 1))) *
215 (CombinatoricsUtils.factorialDouble(n - m + 1) / CombinatoricsUtils.factorialDouble(n + 1)) *
216 eccPwr[m] * UpperBounds.getDnl(XX, chiPwr[m], n + 2, m);
217
218 if (term < tol) {
219 if (m == 0) {
220 break;
221 } else if (m < 2) {
222 xmuarn *= ao2rxx;
223 m = 0;
224 n++;
225 nsmd2++;
226 } else {
227 m -= 2;
228 nsmd2++;
229 }
230 } else {
231 maxAR3Pow = n;
232 maxEccPow = FastMath.max(m, maxEccPow);
233 xmuarn *= ao2rxx;
234 m++;
235 n++;
236 }
237 } while (n < MAX_POWER);
238
239 maxEccPow = FastMath.min(maxAR3Pow, maxEccPow);
240
241
242 aoR3Pow = new double[maxAR3Pow + 1];
243
244 aoR3Pow[0] = 1.;
245 for (int i = 1; i <= maxAR3Pow; i++) {
246 aoR3Pow[i] = aoR3 * aoR3Pow[i - 1];
247 }
248
249 maxFreqF = maxAR3Pow + 1;
250 maxEccPowShort = MAX_ECCPOWER_SP;
251
252 Qns = CoefficientsFactory.computeQns(gamma, maxAR3Pow, FastMath.max(maxEccPow, maxEccPowShort));
253
254 }
255
256
257
258
259 public double getA() {
260 return A;
261 }
262
263
264
265
266 public double getAlpha() {
267 return alpha;
268 }
269
270
271
272
273 public double getBeta() {
274 return beta;
275 }
276
277
278
279
280 public double getGamma() {
281 return gamma;
282 }
283
284
285
286
287 public double getBB() {
288 return BB;
289 }
290
291
292
293
294 public double getBBB() {
295 return BBB;
296 }
297
298
299
300
301 public double getb() {
302 return b;
303 }
304
305
306
307
308 public double getX() {
309 return X;
310 }
311
312
313
314
315 public double getM2aoA() {
316 return m2aoA;
317 }
318
319
320
321
322 public double getBoA() {
323 return BoA;
324 }
325
326
327
328
329 public double getOoAB() {
330 return ooAB;
331 }
332
333
334
335
336 public double getMCo2AB() {
337 return mCo2AB;
338 }
339
340
341
342
343 public double getBoABpo() {
344 return BoABpo;
345 }
346
347
348
349
350 public double getMuoR3() {
351 return muoR3;
352 }
353
354
355
356
357 public double getHXXX() {
358 return hXXX;
359 }
360
361
362
363
364 public double getKXXX() {
365 return kXXX;
366 }
367
368
369
370
371 public int getMaxAR3Pow() {
372 return maxAR3Pow;
373 }
374
375
376
377
378 public int getMaxEccPow() {
379 return maxEccPow;
380 }
381
382
383
384
385 public double[] getAoR3Pow() {
386 return aoR3Pow.clone();
387 }
388
389
390
391
392 public int getMaxFreqF() {
393 return maxFreqF;
394 }
395
396
397
398
399
400
401 public double getMeanMotion() {
402 return motion;
403 }
404
405
406
407
408 public double[][] getQns() {
409 return Qns.clone();
410 }
411
412 }