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