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