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.apache.commons.math3.analysis.UnivariateVectorFunction;
20 import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
21 import org.apache.commons.math3.util.FastMath;
22 import org.orekit.errors.OrekitException;
23 import org.orekit.errors.OrekitExceptionWrapper;
24 import org.orekit.propagation.SpacecraftState;
25 import org.orekit.propagation.semianalytical.dsst.utilities.AuxiliaryElements;
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public abstract class AbstractGaussianContribution implements DSSTForceModel {
49
50
51 private static final int[] GAUSS_ORDER = {12, 16, 20, 24, 32, 40, 48};
52
53
54 private static final int MAX_ORDER_RANK = GAUSS_ORDER.length - 1;
55
56
57
58
59 protected double I;
60
61
62 protected double a;
63
64 protected double k;
65
66 protected double h;
67
68 protected double q;
69
70 protected double p;
71
72
73 protected double ecc;
74
75
76 protected double n;
77
78
79 protected Vector3D f;
80
81 protected Vector3D g;
82
83 protected Vector3D w;
84
85
86 protected double A;
87
88 protected double B;
89
90 protected double C;
91
92
93 protected double ton2a;
94
95 protected double ooA;
96
97 protected double ooAB;
98
99 protected double co2AB;
100
101 protected double ooBpo;
102
103 protected double ooMu;
104
105
106
107
108 private final double threshold;
109
110
111 private GaussQuadrature integrator;
112
113
114 private boolean isDirty;
115
116
117
118
119
120 protected AbstractGaussianContribution(final double threshold) {
121 this.threshold = threshold;
122 this.integrator = new GaussQuadrature(GAUSS_ORDER[MAX_ORDER_RANK]);
123 this.isDirty = true;
124 }
125
126
127 public void initialize(final AuxiliaryElements aux)
128 throws OrekitException {
129
130 }
131
132
133 public void initializeStep(final AuxiliaryElements aux)
134 throws OrekitException {
135
136
137 a = aux.getSma();
138 k = aux.getK();
139 h = aux.getH();
140 q = aux.getQ();
141 p = aux.getP();
142
143
144 I = aux.getRetrogradeFactor();
145
146
147 ecc = aux.getEcc();
148
149
150 A = aux.getA();
151 B = aux.getB();
152 C = aux.getC();
153
154
155 f = aux.getVectorF();
156 g = aux.getVectorG();
157 w = aux.getVectorW();
158
159
160 n = A / (a * a);
161
162
163 ooA = 1. / A;
164
165 ooAB = ooA / B;
166
167 co2AB = C * ooAB / 2.;
168
169 ooBpo = 1. / (1. + B);
170
171 ton2a = 2. / (n * n * a);
172
173 ooMu = 1. / aux.getMu();
174 }
175
176
177 public double[] getMeanElementRate(final SpacecraftState state) throws OrekitException {
178
179 double[] meanElementRate = new double[6];
180
181 final double[] ll = getLLimits(state);
182
183 if (ll[0] < ll[1]) {
184 meanElementRate = getMeanElementRate(state, integrator, ll[0], ll[1]);
185 if (isDirty) {
186 boolean next = true;
187 for (int i = 0; i < MAX_ORDER_RANK && next; i++) {
188 final double[] meanRates = getMeanElementRate(state, new GaussQuadrature(GAUSS_ORDER[i]), ll[0], ll[1]);
189 if (getRatesDiff(meanElementRate, meanRates) < threshold) {
190 integrator = new GaussQuadrature(GAUSS_ORDER[i]);
191 next = false;
192 }
193 }
194 isDirty = false;
195 }
196 }
197 return meanElementRate;
198 }
199
200
201
202
203
204
205
206
207
208 protected abstract Vector3D getAcceleration(final SpacecraftState state,
209 final Vector3D position,
210 final Vector3D velocity) throws OrekitException;
211
212
213
214
215
216
217
218 protected abstract double[] getLLimits(final SpacecraftState state) throws OrekitException;
219
220
221
222
223
224
225
226
227
228
229 private double[] getMeanElementRate(final SpacecraftState state,
230 final GaussQuadrature gauss,
231 final double low,
232 final double high) throws OrekitException {
233 final double[] meanElementRate = gauss.integrate(new IntegrableFunction(state), low, high);
234
235 final double coef = 1. / (2. * FastMath.PI * B);
236
237 for (int i = 0; i < 6; i++) {
238 meanElementRate[i] *= coef;
239 }
240 return meanElementRate;
241 }
242
243
244
245
246
247
248
249 private double getRatesDiff(final double[] meanRef, final double[] meanCur) {
250 double maxDiff = FastMath.abs(meanRef[0] - meanCur[0]) / a;
251
252 for (int i = 1; i < meanRef.length; i++) {
253 final double diff = FastMath.abs(meanRef[i] - meanCur[i]);
254 if (maxDiff < diff) maxDiff = diff;
255 }
256 return maxDiff;
257 }
258
259
260 private class IntegrableFunction implements UnivariateVectorFunction {
261
262
263 private final SpacecraftState state;
264
265
266
267
268 public IntegrableFunction(final SpacecraftState state) {
269 this.state = state;
270 }
271
272
273 public double[] value(final double x) {
274 final double cosL = FastMath.cos(x);
275 final double sinL = FastMath.sin(x);
276 final double roa = B * B / (1. + h * sinL + k * cosL);
277 final double roa2 = roa * roa;
278 final double r = a * roa;
279 final double X = r * cosL;
280 final double Y = r * sinL;
281 final double naob = n * a / B;
282 final double Xdot = -naob * (h + sinL);
283 final double Ydot = naob * (k + cosL);
284 final Vector3D pos = new Vector3D(X, f, Y, g);
285 final Vector3D vel = new Vector3D(Xdot, f, Ydot, g);
286
287 Vector3D acc = Vector3D.ZERO;
288 try {
289 acc = getAcceleration(state, pos, vel);
290 } catch (OrekitException oe) {
291 throw new OrekitExceptionWrapper(oe);
292 }
293
294 final double[] val = new double[6];
295
296 val[0] = roa2 * getAoV(vel).dotProduct(acc);
297
298 val[1] = roa2 * getKoV(X, Y, Xdot, Ydot).dotProduct(acc);
299
300 val[2] = roa2 * getHoV(X, Y, Xdot, Ydot).dotProduct(acc);
301
302 val[3] = roa2 * getQoV(X).dotProduct(acc);
303
304 val[4] = roa2 * getPoV(Y).dotProduct(acc);
305
306 val[5] = roa2 * getLoV(X, Y, Xdot, Ydot).dotProduct(acc);
307
308 return val;
309 }
310
311
312
313
314
315 private Vector3D getAoV(final Vector3D vel) {
316 return new Vector3D(ton2a, vel);
317 }
318
319
320
321
322
323
324
325
326 private Vector3D getHoV(final double X, final double Y, final double Xdot, final double Ydot) {
327 final double kf = (2. * Xdot * Y - X * Ydot) * ooMu;
328 final double kg = X * Xdot * ooMu;
329 final double kw = k * (I * q * Y - p * X) * ooAB;
330 return new Vector3D(kf, f, -kg, g, kw, w);
331 }
332
333
334
335
336
337
338
339
340 private Vector3D getKoV(final double X, final double Y, final double Xdot, final double Ydot) {
341 final double kf = Y * Ydot * ooMu;
342 final double kg = (2. * X * Ydot - Xdot * Y) * ooMu;
343 final double kw = h * (I * q * Y - p * X) * ooAB;
344 return new Vector3D(-kf, f, kg, g, -kw, w);
345 }
346
347
348
349
350
351 private Vector3D getPoV(final double Y) {
352 return new Vector3D(co2AB * Y, w);
353 }
354
355
356
357
358
359 private Vector3D getQoV(final double X) {
360 return new Vector3D(I * co2AB * X, w);
361 }
362
363
364
365
366
367
368
369
370 private Vector3D getLoV(final double X, final double Y, final double Xdot, final double Ydot) {
371 final Vector3D pos = new Vector3D(X, f, Y, g);
372 final Vector3D v2 = new Vector3D(k, getHoV(X, Y, Xdot, Ydot), -h, getKoV(X, Y, Xdot, Ydot));
373 return new Vector3D(-2. * ooA, pos, ooBpo, v2, (I * q * Y - p * X) * ooA, w);
374 }
375
376 }
377
378
379
380
381
382 private static class GaussQuadrature {
383
384
385
386
387
388
389 private static final double[] P_12 = {
390 -0.98156063424671910000,
391 -0.90411725637047490000,
392 -0.76990267419430470000,
393 -0.58731795428661740000,
394 -0.36783149899818024000,
395 -0.12523340851146890000,
396 0.12523340851146890000,
397 0.36783149899818024000,
398 0.58731795428661740000,
399 0.76990267419430470000,
400 0.90411725637047490000,
401 0.98156063424671910000
402 };
403
404
405 private static final double[] W_12 = {
406 0.04717533638651220000,
407 0.10693932599531830000,
408 0.16007832854334633000,
409 0.20316742672306584000,
410 0.23349253653835478000,
411 0.24914704581340286000,
412 0.24914704581340286000,
413 0.23349253653835478000,
414 0.20316742672306584000,
415 0.16007832854334633000,
416 0.10693932599531830000,
417 0.04717533638651220000
418 };
419
420
421 private static final double[] P_16 = {
422 -0.98940093499164990000,
423 -0.94457502307323260000,
424 -0.86563120238783160000,
425 -0.75540440835500310000,
426 -0.61787624440264380000,
427 -0.45801677765722737000,
428 -0.28160355077925890000,
429 -0.09501250983763745000,
430 0.09501250983763745000,
431 0.28160355077925890000,
432 0.45801677765722737000,
433 0.61787624440264380000,
434 0.75540440835500310000,
435 0.86563120238783160000,
436 0.94457502307323260000,
437 0.98940093499164990000
438 };
439
440
441 private static final double[] W_16 = {
442 0.02715245941175405800,
443 0.06225352393864777000,
444 0.09515851168249283000,
445 0.12462897125553388000,
446 0.14959598881657685000,
447 0.16915651939500256000,
448 0.18260341504492360000,
449 0.18945061045506847000,
450 0.18945061045506847000,
451 0.18260341504492360000,
452 0.16915651939500256000,
453 0.14959598881657685000,
454 0.12462897125553388000,
455 0.09515851168249283000,
456 0.06225352393864777000,
457 0.02715245941175405800
458 };
459
460
461 private static final double[] P_20 = {
462 -0.99312859918509490000,
463 -0.96397192727791390000,
464 -0.91223442825132600000,
465 -0.83911697182221890000,
466 -0.74633190646015080000,
467 -0.63605368072651510000,
468 -0.51086700195082700000,
469 -0.37370608871541955000,
470 -0.22778585114164507000,
471 -0.07652652113349734000,
472 0.07652652113349734000,
473 0.22778585114164507000,
474 0.37370608871541955000,
475 0.51086700195082700000,
476 0.63605368072651510000,
477 0.74633190646015080000,
478 0.83911697182221890000,
479 0.91223442825132600000,
480 0.96397192727791390000,
481 0.99312859918509490000
482 };
483
484
485 private static final double[] W_20 = {
486 0.01761400713915226400,
487 0.04060142980038684000,
488 0.06267204833410904000,
489 0.08327674157670477000,
490 0.10193011981724048000,
491 0.11819453196151844000,
492 0.13168863844917678000,
493 0.14209610931838212000,
494 0.14917298647260380000,
495 0.15275338713072600000,
496 0.15275338713072600000,
497 0.14917298647260380000,
498 0.14209610931838212000,
499 0.13168863844917678000,
500 0.11819453196151844000,
501 0.10193011981724048000,
502 0.08327674157670477000,
503 0.06267204833410904000,
504 0.04060142980038684000,
505 0.01761400713915226400
506 };
507
508
509 private static final double[] P_24 = {
510 -0.99518721999702130000,
511 -0.97472855597130950000,
512 -0.93827455200273270000,
513 -0.88641552700440100000,
514 -0.82000198597390300000,
515 -0.74012419157855440000,
516 -0.64809365193697550000,
517 -0.54542147138883950000,
518 -0.43379350762604520000,
519 -0.31504267969616340000,
520 -0.19111886747361634000,
521 -0.06405689286260563000,
522 0.06405689286260563000,
523 0.19111886747361634000,
524 0.31504267969616340000,
525 0.43379350762604520000,
526 0.54542147138883950000,
527 0.64809365193697550000,
528 0.74012419157855440000,
529 0.82000198597390300000,
530 0.88641552700440100000,
531 0.93827455200273270000,
532 0.97472855597130950000,
533 0.99518721999702130000
534 };
535
536
537 private static final double[] W_24 = {
538 0.01234122979998733500,
539 0.02853138862893380600,
540 0.04427743881741981000,
541 0.05929858491543691500,
542 0.07334648141108027000,
543 0.08619016153195320000,
544 0.09761865210411391000,
545 0.10744427011596558000,
546 0.11550566805372553000,
547 0.12167047292780335000,
548 0.12583745634682825000,
549 0.12793819534675221000,
550 0.12793819534675221000,
551 0.12583745634682825000,
552 0.12167047292780335000,
553 0.11550566805372553000,
554 0.10744427011596558000,
555 0.09761865210411391000,
556 0.08619016153195320000,
557 0.07334648141108027000,
558 0.05929858491543691500,
559 0.04427743881741981000,
560 0.02853138862893380600,
561 0.01234122979998733500
562 };
563
564
565 private static final double[] P_32 = {
566 -0.99726386184948160000,
567 -0.98561151154526840000,
568 -0.96476225558750640000,
569 -0.93490607593773970000,
570 -0.89632115576605220000,
571 -0.84936761373256990000,
572 -0.79448379596794250000,
573 -0.73218211874028970000,
574 -0.66304426693021520000,
575 -0.58771575724076230000,
576 -0.50689990893222950000,
577 -0.42135127613063540000,
578 -0.33186860228212767000,
579 -0.23928736225213710000,
580 -0.14447196158279646000,
581 -0.04830766568773831000,
582 0.04830766568773831000,
583 0.14447196158279646000,
584 0.23928736225213710000,
585 0.33186860228212767000,
586 0.42135127613063540000,
587 0.50689990893222950000,
588 0.58771575724076230000,
589 0.66304426693021520000,
590 0.73218211874028970000,
591 0.79448379596794250000,
592 0.84936761373256990000,
593 0.89632115576605220000,
594 0.93490607593773970000,
595 0.96476225558750640000,
596 0.98561151154526840000,
597 0.99726386184948160000
598 };
599
600
601 private static final double[] W_32 = {
602 0.00701861000947013600,
603 0.01627439473090571200,
604 0.02539206530926214200,
605 0.03427386291302141000,
606 0.04283589802222658600,
607 0.05099805926237621600,
608 0.05868409347853559000,
609 0.06582222277636193000,
610 0.07234579410884862000,
611 0.07819389578707042000,
612 0.08331192422694673000,
613 0.08765209300440380000,
614 0.09117387869576390000,
615 0.09384439908080441000,
616 0.09563872007927487000,
617 0.09654008851472784000,
618 0.09654008851472784000,
619 0.09563872007927487000,
620 0.09384439908080441000,
621 0.09117387869576390000,
622 0.08765209300440380000,
623 0.08331192422694673000,
624 0.07819389578707042000,
625 0.07234579410884862000,
626 0.06582222277636193000,
627 0.05868409347853559000,
628 0.05099805926237621600,
629 0.04283589802222658600,
630 0.03427386291302141000,
631 0.02539206530926214200,
632 0.01627439473090571200,
633 0.00701861000947013600
634 };
635
636
637 private static final double[] P_40 = {
638 -0.99823770971055930000,
639 -0.99072623869945710000,
640 -0.97725994998377420000,
641 -0.95791681921379170000,
642 -0.93281280827867660000,
643 -0.90209880696887420000,
644 -0.86595950321225960000,
645 -0.82461223083331170000,
646 -0.77830565142651940000,
647 -0.72731825518992710000,
648 -0.67195668461417960000,
649 -0.61255388966798030000,
650 -0.54946712509512820000,
651 -0.48307580168617870000,
652 -0.41377920437160500000,
653 -0.34199409082575850000,
654 -0.26815218500725370000,
655 -0.19269758070137110000,
656 -0.11608407067525522000,
657 -0.03877241750605081600,
658 0.03877241750605081600,
659 0.11608407067525522000,
660 0.19269758070137110000,
661 0.26815218500725370000,
662 0.34199409082575850000,
663 0.41377920437160500000,
664 0.48307580168617870000,
665 0.54946712509512820000,
666 0.61255388966798030000,
667 0.67195668461417960000,
668 0.72731825518992710000,
669 0.77830565142651940000,
670 0.82461223083331170000,
671 0.86595950321225960000,
672 0.90209880696887420000,
673 0.93281280827867660000,
674 0.95791681921379170000,
675 0.97725994998377420000,
676 0.99072623869945710000,
677 0.99823770971055930000
678 };
679
680
681 private static final double[] W_40 = {
682 0.00452127709853309800,
683 0.01049828453115270400,
684 0.01642105838190797300,
685 0.02224584919416689000,
686 0.02793700698002338000,
687 0.03346019528254786500,
688 0.03878216797447199000,
689 0.04387090818567333000,
690 0.04869580763507221000,
691 0.05322784698393679000,
692 0.05743976909939157000,
693 0.06130624249292891000,
694 0.06480401345660108000,
695 0.06791204581523394000,
696 0.07061164739128681000,
697 0.07288658239580408000,
698 0.07472316905796833000,
699 0.07611036190062619000,
700 0.07703981816424793000,
701 0.07750594797842482000,
702 0.07750594797842482000,
703 0.07703981816424793000,
704 0.07611036190062619000,
705 0.07472316905796833000,
706 0.07288658239580408000,
707 0.07061164739128681000,
708 0.06791204581523394000,
709 0.06480401345660108000,
710 0.06130624249292891000,
711 0.05743976909939157000,
712 0.05322784698393679000,
713 0.04869580763507221000,
714 0.04387090818567333000,
715 0.03878216797447199000,
716 0.03346019528254786500,
717 0.02793700698002338000,
718 0.02224584919416689000,
719 0.01642105838190797300,
720 0.01049828453115270400,
721 0.00452127709853309800
722 };
723
724
725 private static final double[] P_48 = {
726 -0.99877100725242610000,
727 -0.99353017226635080000,
728 -0.98412458372282700000,
729 -0.97059159254624720000,
730 -0.95298770316043080000,
731 -0.93138669070655440000,
732 -0.90587913671556960000,
733 -0.87657202027424800000,
734 -0.84358826162439350000,
735 -0.80706620402944250000,
736 -0.76715903251574020000,
737 -0.72403413092381470000,
738 -0.67787237963266400000,
739 -0.62886739677651370000,
740 -0.57722472608397270000,
741 -0.52316097472223300000,
742 -0.46690290475095840000,
743 -0.40868648199071680000,
744 -0.34875588629216070000,
745 -0.28736248735545555000,
746 -0.22476379039468908000,
747 -0.16122235606889174000,
748 -0.09700469920946270000,
749 -0.03238017096286937000,
750 0.03238017096286937000,
751 0.09700469920946270000,
752 0.16122235606889174000,
753 0.22476379039468908000,
754 0.28736248735545555000,
755 0.34875588629216070000,
756 0.40868648199071680000,
757 0.46690290475095840000,
758 0.52316097472223300000,
759 0.57722472608397270000,
760 0.62886739677651370000,
761 0.67787237963266400000,
762 0.72403413092381470000,
763 0.76715903251574020000,
764 0.80706620402944250000,
765 0.84358826162439350000,
766 0.87657202027424800000,
767 0.90587913671556960000,
768 0.93138669070655440000,
769 0.95298770316043080000,
770 0.97059159254624720000,
771 0.98412458372282700000,
772 0.99353017226635080000,
773 0.99877100725242610000
774 };
775
776
777 private static final double[] W_48 = {
778 0.00315334605230596250,
779 0.00732755390127620800,
780 0.01147723457923446900,
781 0.01557931572294386600,
782 0.01961616045735556700,
783 0.02357076083932435600,
784 0.02742650970835688000,
785 0.03116722783279807000,
786 0.03477722256477045000,
787 0.03824135106583080600,
788 0.04154508294346483000,
789 0.04467456085669424000,
790 0.04761665849249054000,
791 0.05035903555385448000,
792 0.05289018948519365000,
793 0.05519950369998416500,
794 0.05727729210040315000,
795 0.05911483969839566000,
796 0.06070443916589384000,
797 0.06203942315989268000,
798 0.06311419228625403000,
799 0.06392423858464817000,
800 0.06446616443595010000,
801 0.06473769681268386000,
802 0.06473769681268386000,
803 0.06446616443595010000,
804 0.06392423858464817000,
805 0.06311419228625403000,
806 0.06203942315989268000,
807 0.06070443916589384000,
808 0.05911483969839566000,
809 0.05727729210040315000,
810 0.05519950369998416500,
811 0.05289018948519365000,
812 0.05035903555385448000,
813 0.04761665849249054000,
814 0.04467456085669424000,
815 0.04154508294346483000,
816 0.03824135106583080600,
817 0.03477722256477045000,
818 0.03116722783279807000,
819 0.02742650970835688000,
820 0.02357076083932435600,
821 0.01961616045735556700,
822 0.01557931572294386600,
823 0.01147723457923446900,
824 0.00732755390127620800,
825 0.00315334605230596250
826 };
827
828
829
830 private final double[] nodePoints;
831
832
833 private final double[] nodeWeights;
834
835
836
837
838
839 public GaussQuadrature(final int numberOfPoints) {
840
841 switch(numberOfPoints) {
842 case 12 :
843 this.nodePoints = P_12.clone();
844 this.nodeWeights = W_12.clone();
845 break;
846 case 16 :
847 this.nodePoints = P_16.clone();
848 this.nodeWeights = W_16.clone();
849 break;
850 case 20 :
851 this.nodePoints = P_20.clone();
852 this.nodeWeights = W_20.clone();
853 break;
854 case 24 :
855 this.nodePoints = P_24.clone();
856 this.nodeWeights = W_24.clone();
857 break;
858 case 32 :
859 this.nodePoints = P_32.clone();
860 this.nodeWeights = W_32.clone();
861 break;
862 case 40 :
863 this.nodePoints = P_40.clone();
864 this.nodeWeights = W_40.clone();
865 break;
866 case 48 :
867 default :
868 this.nodePoints = P_48.clone();
869 this.nodeWeights = W_48.clone();
870 break;
871 }
872
873 }
874
875
876
877
878
879
880
881
882 public double[] integrate(final UnivariateVectorFunction f,
883 final double lowerBound, final double upperBound) {
884
885 final double[] adaptedPoints = nodePoints.clone();
886 final double[] adaptedWeights = nodeWeights.clone();
887 transform(adaptedPoints, adaptedWeights, lowerBound, upperBound);
888 return basicIntegrate(f, adaptedPoints, adaptedWeights);
889 }
890
891
892
893
894
895
896
897
898
899
900
901
902 private void transform(final double[] points, final double[] weights,
903 final double a, final double b) {
904
905 final double scale = (b - a) / 2;
906 final double shift = a + scale;
907 for (int i = 0; i < points.length; i++) {
908 points[i] = points[i] * scale + shift;
909 weights[i] *= scale;
910 }
911 }
912
913
914
915
916
917
918
919
920
921
922 private double[] basicIntegrate(final UnivariateVectorFunction f,
923 final double[] points,
924 final double[] weights) {
925 double x = points[0];
926 double w = weights[0];
927 double[] v = f.value(x);
928 final double[] y = new double[v.length];
929 for (int j = 0; j < v.length; j++) {
930 y[j] = w * v[j];
931 }
932 final double[] t = y.clone();
933 final double[] c = new double[v.length];
934 final double[] s = t.clone();
935 for (int i = 1; i < points.length; i++) {
936 x = points[i];
937 w = weights[i];
938 v = f.value(x);
939 for (int j = 0; j < v.length; j++) {
940 y[j] = w * v[j] - c[j];
941 t[j] = s[j] + y[j];
942 c[j] = (t[j] - s[j]) - y[j];
943 s[j] = t[j];
944 }
945 }
946 return s;
947 }
948
949 }
950 }