1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.integration;
18
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25
26 import org.hipparchus.CalculusFieldElement;
27 import org.hipparchus.Field;
28 import org.hipparchus.exception.MathIllegalArgumentException;
29 import org.hipparchus.exception.MathIllegalStateException;
30 import org.hipparchus.ode.FieldDenseOutputModel;
31 import org.hipparchus.ode.FieldEquationsMapper;
32 import org.hipparchus.ode.FieldExpandableODE;
33 import org.hipparchus.ode.FieldODEIntegrator;
34 import org.hipparchus.ode.FieldODEState;
35 import org.hipparchus.ode.FieldODEStateAndDerivative;
36 import org.hipparchus.ode.FieldOrdinaryDifferentialEquation;
37 import org.hipparchus.ode.FieldSecondaryODE;
38 import org.hipparchus.ode.events.Action;
39 import org.hipparchus.ode.events.FieldEventHandlerConfiguration;
40 import org.hipparchus.ode.events.FieldODEEventHandler;
41 import org.hipparchus.ode.sampling.AbstractFieldODEStateInterpolator;
42 import org.hipparchus.ode.sampling.FieldODEStateInterpolator;
43 import org.hipparchus.ode.sampling.FieldODEStepHandler;
44 import org.hipparchus.util.MathArrays;
45 import org.hipparchus.util.Precision;
46 import org.orekit.attitudes.AttitudeProvider;
47 import org.orekit.errors.OrekitException;
48 import org.orekit.errors.OrekitInternalError;
49 import org.orekit.errors.OrekitMessages;
50 import org.orekit.frames.Frame;
51 import org.orekit.orbits.OrbitType;
52 import org.orekit.orbits.PositionAngle;
53 import org.orekit.propagation.FieldAbstractPropagator;
54 import org.orekit.propagation.FieldBoundedPropagator;
55 import org.orekit.propagation.FieldEphemerisGenerator;
56 import org.orekit.propagation.FieldSpacecraftState;
57 import org.orekit.propagation.PropagationType;
58 import org.orekit.propagation.events.FieldEventDetector;
59 import org.orekit.propagation.sampling.FieldOrekitStepHandler;
60 import org.orekit.propagation.sampling.FieldOrekitStepInterpolator;
61 import org.orekit.time.FieldAbsoluteDate;
62
63
64
65
66
67
68
69 public abstract class FieldAbstractIntegratedPropagator<T extends CalculusFieldElement<T>> extends FieldAbstractPropagator<T> {
70
71
72 private final List<FieldEventDetector<T>> detectors;
73
74
75 private final List<FieldStoringStepHandler> generators;
76
77
78 private final FieldODEIntegrator<T> integrator;
79
80
81 private List<FieldAdditionalEquations<T>> additionalEquations;
82
83
84 private int calls;
85
86
87 private FieldStateMapper<T> stateMapper;
88
89
90 private FieldEquationsMapper<T> equationsMapper;
91
92
93 private boolean resetAtEnd;
94
95
96
97
98
99
100
101 private PropagationType propagationType;
102
103
104
105
106
107
108 protected FieldAbstractIntegratedPropagator(final Field<T> field, final FieldODEIntegrator<T> integrator, final PropagationType propagationType) {
109 super(field);
110 detectors = new ArrayList<>();
111 generators = new ArrayList<>();
112 additionalEquations = new ArrayList<>();
113 this.integrator = integrator;
114 this.propagationType = propagationType;
115 this.resetAtEnd = true;
116 }
117
118
119
120
121
122
123
124
125
126
127
128
129
130 public void setResetAtEnd(final boolean resetAtEnd) {
131 this.resetAtEnd = resetAtEnd;
132 }
133
134
135
136
137 protected void initMapper(final Field<T> field) {
138 final T zero = field.getZero();
139 stateMapper = createMapper(null, zero.add(Double.NaN), null, null, null, null);
140 }
141
142
143 public void setAttitudeProvider(final AttitudeProvider attitudeProvider) {
144 super.setAttitudeProvider(attitudeProvider);
145 stateMapper = createMapper(stateMapper.getReferenceDate(), stateMapper.getMu(),
146 stateMapper.getOrbitType(), stateMapper.getPositionAngleType(),
147 attitudeProvider, stateMapper.getFrame());
148 }
149
150
151
152
153 protected void setOrbitType(final OrbitType orbitType) {
154 stateMapper = createMapper(stateMapper.getReferenceDate(), stateMapper.getMu(),
155 orbitType, stateMapper.getPositionAngleType(),
156 stateMapper.getAttitudeProvider(), stateMapper.getFrame());
157 }
158
159
160
161
162 protected OrbitType getOrbitType() {
163 return stateMapper.getOrbitType();
164 }
165
166
167
168
169
170 protected PropagationType isMeanOrbit() {
171 return propagationType;
172 }
173
174
175
176
177
178
179
180
181
182
183 protected void setPositionAngleType(final PositionAngle positionAngleType) {
184 stateMapper = createMapper(stateMapper.getReferenceDate(), stateMapper.getMu(),
185 stateMapper.getOrbitType(), positionAngleType,
186 stateMapper.getAttitudeProvider(), stateMapper.getFrame());
187 }
188
189
190
191
192 protected PositionAngle getPositionAngleType() {
193 return stateMapper.getPositionAngleType();
194 }
195
196
197
198
199 public void setMu(final T mu) {
200 stateMapper = createMapper(stateMapper.getReferenceDate(), mu,
201 stateMapper.getOrbitType(), stateMapper.getPositionAngleType(),
202 stateMapper.getAttitudeProvider(), stateMapper.getFrame());
203 }
204
205
206
207
208
209 public T getMu() {
210 return stateMapper.getMu();
211 }
212
213
214
215
216
217
218 public int getCalls() {
219 return calls;
220 }
221
222
223 @Override
224 public boolean isAdditionalStateManaged(final String name) {
225
226
227 if (super.isAdditionalStateManaged(name)) {
228 return true;
229 }
230
231
232 for (final FieldAdditionalEquations<T> equation : additionalEquations) {
233 if (equation.getName().equals(name)) {
234 return true;
235 }
236 }
237
238 return false;
239 }
240
241
242 @Override
243 public String[] getManagedAdditionalStates() {
244 final String[] alreadyIntegrated = super.getManagedAdditionalStates();
245 final String[] managed = new String[alreadyIntegrated.length + additionalEquations.size()];
246 System.arraycopy(alreadyIntegrated, 0, managed, 0, alreadyIntegrated.length);
247 for (int i = 0; i < additionalEquations.size(); ++i) {
248 managed[i + alreadyIntegrated.length] = additionalEquations.get(i).getName();
249 }
250 return managed;
251 }
252
253
254
255
256 public void addAdditionalEquations(final FieldAdditionalEquations<T> additional) {
257
258
259 if (isAdditionalStateManaged(additional.getName())) {
260
261 throw new OrekitException(OrekitMessages.ADDITIONAL_STATE_NAME_ALREADY_IN_USE,
262 additional.getName());
263 }
264
265
266 additionalEquations.add(additional);
267
268 }
269
270
271 public <D extends FieldEventDetector<T>> void addEventDetector(final D detector) {
272 detectors.add(detector);
273 }
274
275
276 public Collection<FieldEventDetector<T>> getEventsDetectors() {
277 return Collections.unmodifiableCollection(detectors);
278 }
279
280
281 public void clearEventsDetectors() {
282 detectors.clear();
283 }
284
285
286
287 protected void setUpUserEventDetectors() {
288 for (final FieldEventDetector<T> detector : detectors) {
289 setUpEventDetector(integrator, detector);
290 }
291 }
292
293
294
295
296
297 protected void setUpEventDetector(final FieldODEIntegrator<T> integ, final FieldEventDetector<T> detector) {
298 integ.addEventHandler(new FieldAdaptedEventDetector(detector),
299 detector.getMaxCheckInterval().getReal(),
300 detector.getThreshold().getReal(),
301 detector.getMaxIterationCount());
302 }
303
304
305 @Override
306 public FieldEphemerisGenerator<T> getEphemerisGenerator() {
307 final FieldStoringStepHandler storingHandler = new FieldStoringStepHandler();
308 generators.add(storingHandler);
309 return storingHandler;
310 }
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328 protected abstract FieldStateMapper<T> createMapper(FieldAbsoluteDate<T> referenceDate, T mu,
329 OrbitType orbitType, PositionAngle positionAngleType,
330 AttitudeProvider attitudeProvider, Frame frame);
331
332
333
334
335
336 protected abstract MainStateEquations<T> getMainStateEquations(FieldODEIntegrator<T> integ);
337
338
339 public FieldSpacecraftState<T> propagate(final FieldAbsoluteDate<T> target) {
340 if (getStartDate() == null) {
341 if (getInitialState() == null) {
342 throw new OrekitException(OrekitMessages.INITIAL_STATE_NOT_SPECIFIED_FOR_ORBIT_PROPAGATION);
343 }
344 setStartDate(getInitialState().getDate());
345 }
346 return propagate(getStartDate(), target);
347 }
348
349
350 public FieldSpacecraftState<T> propagate(final FieldAbsoluteDate<T> tStart, final FieldAbsoluteDate<T> tEnd) {
351
352 if (getInitialState() == null) {
353 throw new OrekitException(OrekitMessages.INITIAL_STATE_NOT_SPECIFIED_FOR_ORBIT_PROPAGATION);
354 }
355
356
357 try (IntegratorResetter<T> resetter = new IntegratorResetter<>(integrator)) {
358
359 if (!tStart.equals(getInitialState().getDate())) {
360
361
362 integrateDynamics(tStart);
363 }
364
365
366 setUpUserEventDetectors();
367
368
369 for (final FieldOrekitStepHandler<T> handler : getMultiplexer().getHandlers()) {
370 integrator.addStepHandler(new FieldAdaptedStepHandler(handler));
371 }
372 for (final FieldStoringStepHandler generator : generators) {
373 generator.setEndDate(tEnd);
374 integrator.addStepHandler(generator);
375 }
376
377
378 return integrateDynamics(tEnd);
379
380 }
381
382 }
383
384
385
386
387
388 private FieldSpacecraftState<T> integrateDynamics(final FieldAbsoluteDate<T> tEnd) {
389 try {
390
391 initializePropagation();
392
393 if (getInitialState().getDate().equals(tEnd)) {
394
395 return getInitialState();
396 }
397
398 stateMapper = createMapper(getInitialState().getDate(), stateMapper.getMu(),
399 stateMapper.getOrbitType(), stateMapper.getPositionAngleType(),
400 stateMapper.getAttitudeProvider(), getInitialState().getFrame());
401
402
403
404
405 if (Double.isNaN(getMu().getReal())) {
406 setMu(getInitialState().getMu());
407 }
408 if (getInitialState().getMass().getReal() <= 0.0) {
409 throw new OrekitException(OrekitMessages.SPACECRAFT_MASS_BECOMES_NEGATIVE,
410 getInitialState().getMass());
411 }
412
413
414 final FieldSpacecraftState<T> initialIntegrationState = getInitialIntegrationState();
415 final FieldODEState<T> mathInitialState = createInitialState(initialIntegrationState);
416 final FieldExpandableODE<T> mathODE = createODE(integrator, mathInitialState);
417 equationsMapper = mathODE.getMapper();
418
419
420 final FieldODEStateAndDerivative<T> mathFinalState;
421 beforeIntegration(initialIntegrationState, tEnd);
422 mathFinalState = integrator.integrate(mathODE, mathInitialState,
423 tEnd.durationFrom(getInitialState().getDate()));
424
425 afterIntegration();
426
427
428 FieldSpacecraftState<T> finalState =
429 stateMapper.mapArrayToState(stateMapper.mapDoubleToDate(mathFinalState.getTime(), tEnd),
430 mathFinalState.getPrimaryState(),
431 mathFinalState.getPrimaryDerivative(),
432 propagationType);
433 finalState = updateAdditionalStates(finalState);
434 for (int i = 0; i < additionalEquations.size(); ++i) {
435 final T[] secondary = mathFinalState.getSecondaryState(i + 1);
436 finalState = finalState.addAdditionalState(additionalEquations.get(i).getName(),
437 secondary);
438 }
439 if (resetAtEnd) {
440 resetInitialState(finalState);
441 setStartDate(finalState.getDate());
442 }
443
444 return finalState;
445
446 } catch (OrekitException pe) {
447 throw pe;
448 } catch (MathIllegalArgumentException miae) {
449 throw OrekitException.unwrap(miae);
450 } catch (MathIllegalStateException mise) {
451 throw OrekitException.unwrap(mise);
452 }
453 }
454
455
456
457
458 protected FieldSpacecraftState<T> getInitialIntegrationState() {
459 return getInitialState();
460 }
461
462
463
464
465
466 private FieldODEState<T> createInitialState(final FieldSpacecraftState<T> initialState) {
467
468
469 final T[] primary = MathArrays.buildArray(initialState.getA().getField(), getBasicDimension());
470 stateMapper.mapStateToArray(initialState, primary, null);
471
472
473 final T[][] secondary = MathArrays.buildArray(initialState.getA().getField(), additionalEquations.size(), -1);
474 for (int i = 0; i < additionalEquations.size(); ++i) {
475 final FieldAdditionalEquations<T> additional = additionalEquations.get(i);
476 final T[] addState = getInitialState().getAdditionalState(additional.getName());
477 secondary[i] = MathArrays.buildArray(initialState.getA().getField(), addState.length);
478 for (int j = 0; j < addState.length; j++) {
479 secondary[i][j] = addState[j];
480 }
481 }
482
483 return new FieldODEState<>(initialState.getA().getField().getZero(), primary, secondary);
484
485 }
486
487
488
489
490
491
492 private FieldExpandableODE<T> createODE(final FieldODEIntegrator<T> integ,
493 final FieldODEState<T> mathInitialState) {
494
495 final FieldExpandableODE<T> ode =
496 new FieldExpandableODE<>(new ConvertedMainStateEquations(getMainStateEquations(integ)));
497
498
499 for (int i = 0; i < additionalEquations.size(); ++i) {
500 final FieldAdditionalEquations<T> additional = additionalEquations.get(i);
501 final FieldSecondaryODE<T> secondary =
502 new ConvertedSecondaryStateEquations(additional,
503 mathInitialState.getSecondaryStateDimension(i + 1));
504 ode.addSecondaryEquations(secondary);
505 }
506
507 return ode;
508
509 }
510
511
512
513
514
515
516
517
518 protected void beforeIntegration(final FieldSpacecraftState<T> initialState,
519 final FieldAbsoluteDate<T> tEnd) {
520
521 }
522
523
524
525
526
527
528 protected void afterIntegration() {
529
530 }
531
532
533
534
535 public int getBasicDimension() {
536 return 7;
537
538 }
539
540
541
542
543 protected FieldODEIntegrator<T> getIntegrator() {
544 return integrator;
545 }
546
547
548
549
550
551
552
553 private FieldSpacecraftState<T> getCompleteState(final T t, final T[] ts, final T[] tsDot) {
554
555
556 FieldSpacecraftState<T> state = stateMapper.mapArrayToState(t, ts, tsDot, PropagationType.MEAN);
557
558 state = updateAdditionalStates(state);
559
560
561 if (!additionalEquations.isEmpty()) {
562
563 for (int i = 0; i < additionalEquations.size(); ++i) {
564 state = state.addAdditionalState(additionalEquations.get(i).getName(),
565 equationsMapper.extractEquationData(i + 1, ts));
566 }
567
568 }
569
570 return state;
571
572 }
573
574
575
576
577
578
579
580
581 private FieldSpacecraftState<T> convert(final FieldODEStateAndDerivative<T> os) {
582 try {
583
584 FieldSpacecraftState<T> s =
585 stateMapper.mapArrayToState(os.getTime(),
586 os.getPrimaryState(),
587 os.getPrimaryDerivative(),
588 propagationType);
589 s = updateAdditionalStates(s);
590 for (int i = 0; i < additionalEquations.size(); ++i) {
591 final T[] secondary = os.getSecondaryState(i + 1);
592 s = s.addAdditionalState(additionalEquations.get(i).getName(), secondary);
593 }
594
595 return s;
596
597 } catch (OrekitException oe) {
598 throw new OrekitException(oe);
599 }
600 }
601
602
603
604
605
606 private FieldODEStateAndDerivative<T> convert(final FieldSpacecraftState<T> state) {
607
608
609 final T[] primary = MathArrays.buildArray(getField(), getBasicDimension());
610 final T[] primaryDot = MathArrays.buildArray(getField(), getBasicDimension());
611 stateMapper.mapStateToArray(state, primary, primaryDot);
612
613
614 final T[][] secondary = MathArrays.buildArray(getField(), additionalEquations.size(), -1);
615 for (int i = 0; i < additionalEquations.size(); ++i) {
616 final FieldAdditionalEquations<T> additional = additionalEquations.get(i);
617 secondary[i] = state.getAdditionalState(additional.getName());
618 }
619
620 return new FieldODEStateAndDerivative<>(stateMapper.mapDateToDouble(state.getDate()),
621 primary, primaryDot,
622 secondary, null);
623
624 }
625
626
627 public interface MainStateEquations<T extends CalculusFieldElement<T>> {
628
629
630
631
632
633
634
635
636
637
638
639 void init(FieldSpacecraftState<T> initialState, FieldAbsoluteDate<T> target);
640
641
642
643
644
645 T[] computeDerivatives(FieldSpacecraftState<T> state);
646
647 }
648
649
650 private class ConvertedMainStateEquations implements FieldOrdinaryDifferentialEquation<T> {
651
652
653 private final MainStateEquations<T> main;
654
655
656
657
658 ConvertedMainStateEquations(final MainStateEquations<T> main) {
659 this.main = main;
660 calls = 0;
661 }
662
663
664 public int getDimension() {
665 return getBasicDimension();
666 }
667
668 @Override
669 public void init(final T t0, final T[] y0, final T finalTime) {
670
671 FieldSpacecraftState<T> initialState = stateMapper.mapArrayToState(t0, y0, null, PropagationType.MEAN);
672 initialState = updateAdditionalStates(initialState);
673 final FieldAbsoluteDate<T> target = stateMapper.mapDoubleToDate(finalTime);
674 main.init(initialState, target);
675 }
676
677 public T[] computeDerivatives(final T t, final T[] y) {
678
679
680 ++calls;
681
682
683 FieldSpacecraftState<T> currentState = stateMapper.mapArrayToState(t, y, null, PropagationType.MEAN);
684 currentState = updateAdditionalStates(currentState);
685
686
687 return main.computeDerivatives(currentState);
688
689 }
690
691 }
692
693
694 private class ConvertedSecondaryStateEquations implements FieldSecondaryODE<T> {
695
696
697 private final FieldAdditionalEquations<T> equations;
698
699
700 private final int dimension;
701
702
703
704
705
706 ConvertedSecondaryStateEquations(final FieldAdditionalEquations<T> equations,
707 final int dimension) {
708 this.equations = equations;
709 this.dimension = dimension;
710 }
711
712
713 @Override
714 public int getDimension() {
715 return dimension;
716 }
717
718
719 @Override
720 public void init(final T t0, final T[] primary0,
721 final T[] secondary0, final T finalTime) {
722
723 FieldSpacecraftState<T> initialState = stateMapper.mapArrayToState(t0, primary0, null, PropagationType.MEAN);
724 initialState = updateAdditionalStates(initialState);
725 initialState = initialState.addAdditionalState(equations.getName(), secondary0);
726 final FieldAbsoluteDate<T> target = stateMapper.mapDoubleToDate(finalTime);
727 equations.init(initialState, target);
728 }
729
730
731 @Override
732 public T[] computeDerivatives(final T t, final T[] primary,
733 final T[] primaryDot, final T[] secondary) {
734
735
736 FieldSpacecraftState<T> currentState = stateMapper.mapArrayToState(t, primary, primaryDot, PropagationType.MEAN);
737 currentState = updateAdditionalStates(currentState);
738 currentState = currentState.addAdditionalState(equations.getName(), secondary);
739
740
741 final T[] secondaryDot = MathArrays.buildArray(getField(), secondary.length);
742 final T[] additionalMainDot =
743 equations.computeDerivatives(currentState, secondaryDot);
744 if (additionalMainDot != null) {
745
746 for (int i = 0; i < additionalMainDot.length; ++i) {
747 primaryDot[i] = primaryDot[i].add(additionalMainDot[i]);
748 }
749 }
750
751 return secondaryDot;
752
753 }
754
755 }
756
757
758
759
760
761
762 private class FieldAdaptedEventDetector implements FieldODEEventHandler<T> {
763
764
765 private final FieldEventDetector<T> detector;
766
767
768 private T lastT;
769
770
771 private T lastG;
772
773
774
775
776 FieldAdaptedEventDetector(final FieldEventDetector<T> detector) {
777 this.detector = detector;
778 this.lastT = getField().getZero().add(Double.NaN);
779 this.lastG = getField().getZero().add(Double.NaN);
780 }
781
782
783 public void init(final FieldODEStateAndDerivative<T> s0, final T t) {
784 detector.init(getCompleteState(s0.getTime(), s0.getCompleteState(), s0.getCompleteDerivative()),
785 stateMapper.mapDoubleToDate(t));
786 this.lastT = getField().getZero().add(Double.NaN);
787 this.lastG = getField().getZero().add(Double.NaN);
788 }
789
790
791 public T g(final FieldODEStateAndDerivative<T> s) {
792 if (!Precision.equals(lastT.getReal(), s.getTime().getReal(), 0)) {
793 lastT = s.getTime();
794 lastG = detector.g(getCompleteState(s.getTime(), s.getCompleteState(), s.getCompleteDerivative()));
795 }
796 return lastG;
797 }
798
799
800 public Action eventOccurred(final FieldODEStateAndDerivative<T> s, final boolean increasing) {
801 return detector.eventOccurred(
802 getCompleteState(
803 s.getTime(),
804 s.getCompleteState(),
805 s.getCompleteDerivative()),
806 increasing);
807 }
808
809
810 public FieldODEState<T> resetState(final FieldODEStateAndDerivative<T> s) {
811
812 final FieldSpacecraftState<T> oldState = getCompleteState(s.getTime(), s.getCompleteState(), s.getCompleteDerivative());
813 final FieldSpacecraftState<T> newState = detector.resetState(oldState);
814 stateChanged(newState);
815
816
817 final T[] primary = MathArrays.buildArray(getField(), s.getPrimaryStateDimension());
818 stateMapper.mapStateToArray(newState, primary, null);
819
820
821 final T[][] secondary = MathArrays.buildArray(getField(), additionalEquations.size(), -1);
822
823 for (int i = 0; i < additionalEquations.size(); ++i) {
824 final FieldAdditionalEquations<T> additional = additionalEquations.get(i);
825 final T[] NState = newState.getAdditionalState(additional.getName());
826 secondary[i] = MathArrays.buildArray(getField(), NState.length);
827 for (int j = 0; j < NState.length; j++) {
828 secondary[i][j] = NState[j];
829 }
830 }
831
832 return new FieldODEState<>(newState.getDate().durationFrom(getStartDate()),
833 primary, secondary);
834 }
835
836 }
837
838
839
840
841
842 private class FieldAdaptedStepHandler implements FieldODEStepHandler<T> {
843
844
845 private final FieldOrekitStepHandler<T> handler;
846
847
848
849
850 FieldAdaptedStepHandler(final FieldOrekitStepHandler<T> handler) {
851 this.handler = handler;
852 }
853
854
855 public void init(final FieldODEStateAndDerivative<T> s0, final T t) {
856 handler.init(getCompleteState(s0.getTime(), s0.getCompleteState(), s0.getCompleteDerivative()),
857 stateMapper.mapDoubleToDate(t));
858 }
859
860
861 public void handleStep(final FieldODEStateInterpolator<T> interpolator) {
862 handler.handleStep(new FieldAdaptedStepInterpolator(interpolator));
863 }
864
865
866 @Override
867 public void finish(final FieldODEStateAndDerivative<T> finalState) {
868 handler.finish(convert(finalState));
869 }
870
871 }
872
873
874
875
876
877 private class FieldAdaptedStepInterpolator implements FieldOrekitStepInterpolator<T> {
878
879
880 private final FieldODEStateInterpolator<T> mathInterpolator;
881
882
883
884
885 FieldAdaptedStepInterpolator(final FieldODEStateInterpolator<T> mathInterpolator) {
886 this.mathInterpolator = mathInterpolator;
887 }
888
889
890 @Override
891 public FieldSpacecraftState<T> getPreviousState() {
892 return convert(mathInterpolator.getPreviousState());
893 }
894
895
896 @Override
897 public FieldSpacecraftState<T> getCurrentState() {
898 return convert(mathInterpolator.getCurrentState());
899 }
900
901
902 @Override
903 public FieldSpacecraftState<T> getInterpolatedState(final FieldAbsoluteDate<T> date) {
904 return convert(mathInterpolator.getInterpolatedState(date.durationFrom(getStartDate())));
905 }
906
907
908
909
910 public boolean isForward() {
911 return mathInterpolator.isForward();
912 }
913
914
915 @Override
916 public FieldAdaptedStepInterpolator restrictStep(final FieldSpacecraftState<T> newPreviousState,
917 final FieldSpacecraftState<T> newCurrentState) {
918 try {
919 final AbstractFieldODEStateInterpolator<T> aosi = (AbstractFieldODEStateInterpolator<T>) mathInterpolator;
920 return new FieldAdaptedStepInterpolator(aosi.restrictStep(convert(newPreviousState),
921 convert(newCurrentState)));
922 } catch (ClassCastException cce) {
923
924 throw new OrekitInternalError(cce);
925 }
926 }
927
928 }
929
930
931
932
933 private class FieldStoringStepHandler implements FieldODEStepHandler<T>, FieldEphemerisGenerator<T> {
934
935
936 private FieldDenseOutputModel<T> model;
937
938
939 private FieldAbsoluteDate<T> endDate;
940
941
942 private FieldBoundedPropagator<T> ephemeris;
943
944
945
946
947 public void setEndDate(final FieldAbsoluteDate<T> endDate) {
948 this.endDate = endDate;
949 }
950
951
952 @Override
953 public void init(final FieldODEStateAndDerivative<T> s0, final T t) {
954 this.model = new FieldDenseOutputModel<>();
955 model.init(s0, t);
956
957
958 this.ephemeris = null;
959
960 }
961
962
963 @Override
964 public FieldBoundedPropagator<T> getGeneratedEphemeris() {
965 return ephemeris;
966 }
967
968
969 @Override
970 public void handleStep(final FieldODEStateInterpolator<T> interpolator) {
971 model.handleStep(interpolator);
972 }
973
974
975 @Override
976 public void finish(final FieldODEStateAndDerivative<T> finalState) {
977
978
979 final T tI = model.getInitialTime();
980 final T tF = model.getFinalTime();
981
982 final FieldAbsoluteDate<T> startDate =
983 stateMapper.mapDoubleToDate(tI);
984 final FieldAbsoluteDate<T> finalDate =
985 stateMapper.mapDoubleToDate(tF, this.endDate);
986 final FieldAbsoluteDate<T> minDate;
987 final FieldAbsoluteDate<T> maxDate;
988 if (tF.getReal() < tI.getReal()) {
989 minDate = finalDate;
990 maxDate = startDate;
991 } else {
992 minDate = startDate;
993 maxDate = finalDate;
994 }
995
996
997 final Map<String, T[]> unmanaged = new HashMap<String, T[]>();
998 for (final Map.Entry<String, T[]> initial : getInitialState().getAdditionalStates().entrySet()) {
999 if (!isAdditionalStateManaged(initial.getKey())) {
1000
1001
1002 unmanaged.put(initial.getKey(), initial.getValue());
1003 }
1004 }
1005
1006
1007 final String[] names = new String[additionalEquations.size()];
1008 for (int i = 0; i < names.length; ++i) {
1009 names[i] = additionalEquations.get(i).getName();
1010 }
1011
1012
1013 ephemeris = new FieldIntegratedEphemeris<>(startDate, minDate, maxDate,
1014 stateMapper, propagationType, model, unmanaged,
1015 getAdditionalStateProviders(), names);
1016
1017 }
1018
1019 }
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032 private static class IntegratorResetter<T extends CalculusFieldElement<T>> implements AutoCloseable {
1033
1034
1035 private final FieldODEIntegrator<T> integrator;
1036
1037
1038 private final List<FieldEventHandlerConfiguration<T>> eventHandlersConfigurations;
1039
1040
1041 private final List<FieldODEStepHandler<T>> stepHandlers;
1042
1043
1044
1045
1046 IntegratorResetter(final FieldODEIntegrator<T> integrator) {
1047 this.integrator = integrator;
1048 this.eventHandlersConfigurations = new ArrayList<>(integrator.getEventHandlersConfigurations());
1049 this.stepHandlers = new ArrayList<>(integrator.getStepHandlers());
1050 }
1051
1052
1053
1054
1055
1056
1057 @Override
1058 public void close() {
1059
1060
1061 integrator.clearEventHandlers();
1062 eventHandlersConfigurations.forEach(c -> integrator.addEventHandler(c.getEventHandler(),
1063 c.getMaxCheckInterval(),
1064 c.getConvergence().getReal(),
1065 c.getMaxIterationCount(),
1066 c.getSolver()));
1067
1068
1069 integrator.clearStepHandlers();
1070 stepHandlers.forEach(stepHandler -> integrator.addStepHandler(stepHandler));
1071
1072 }
1073
1074 }
1075
1076 }