1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.control.indirect.adjoint.cost;
18
19 import org.hipparchus.Field;
20 import org.hipparchus.analysis.differentiation.Gradient;
21 import org.hipparchus.analysis.differentiation.GradientField;
22 import org.hipparchus.complex.Complex;
23 import org.hipparchus.complex.ComplexField;
24 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
25 import org.hipparchus.geometry.euclidean.threed.Vector3D;
26 import org.hipparchus.ode.events.Action;
27 import org.hipparchus.util.MathArrays;
28 import org.junit.jupiter.api.Assertions;
29 import org.junit.jupiter.api.Test;
30 import org.junit.jupiter.params.ParameterizedTest;
31 import org.junit.jupiter.params.provider.ValueSource;
32 import org.orekit.control.indirect.adjoint.CartesianAdjointDerivativesProvider;
33 import org.orekit.control.indirect.adjoint.FieldCartesianAdjointDerivativesProvider;
34 import org.orekit.frames.FramesFactory;
35 import org.orekit.orbits.CartesianOrbit;
36 import org.orekit.orbits.Orbit;
37 import org.orekit.propagation.FieldSpacecraftState;
38 import org.orekit.propagation.SpacecraftState;
39 import org.orekit.propagation.events.EventDetector;
40 import org.orekit.propagation.events.FieldEventDetector;
41 import org.orekit.propagation.integration.CombinedDerivatives;
42 import org.orekit.propagation.integration.FieldCombinedDerivatives;
43 import org.orekit.time.AbsoluteDate;
44 import org.orekit.utils.Constants;
45 import org.orekit.utils.PVCoordinates;
46
47 import java.util.List;
48 import java.util.stream.Collectors;
49 import java.util.stream.Stream;
50
51 class FieldUnboundedCartesianEnergyTest {
52
53 @Test
54 void testGetFieldThrustAccelerationVectorFieldFactor() {
55
56 final Complex massRateFactor = Complex.ONE;
57 final FieldUnboundedCartesianEnergy<Complex> unboundedCartesianEnergy = new FieldUnboundedCartesianEnergy<>("", massRateFactor);
58 final ComplexField field = ComplexField.getInstance();
59 final Complex[] fieldAdjoint = MathArrays.buildArray(field, 7);
60 fieldAdjoint[3] = new Complex(1.0, 0.0);
61 fieldAdjoint[4] = new Complex(2.0, 0.0);
62 final Complex mass = new Complex(3., 0.);
63
64 final FieldVector3D<Complex> fieldThrustVector = unboundedCartesianEnergy.getFieldThrustAccelerationVector(fieldAdjoint, mass);
65
66 final double[] adjoint = new double[7];
67 for (int i = 0; i < adjoint.length; i++) {
68 adjoint[i] = fieldAdjoint[i].getReal();
69 }
70 final Vector3D thrustVector = unboundedCartesianEnergy.toCartesianCost().getThrustAccelerationVector(adjoint, mass.getReal());
71 Assertions.assertEquals(thrustVector, fieldThrustVector.toVector3D());
72 }
73
74 @ParameterizedTest
75 @ValueSource(doubles = {1e-1, 1e10})
76 void testFieldDerivatives(final double mass) {
77
78 final String name = "a";
79 final FieldUnboundedCartesianEnergy<Gradient> energy = new FieldUnboundedCartesianEnergy<>(name, GradientField.getField(1).getZero());
80 final FieldCartesianAdjointDerivativesProvider<Gradient> fieldAdjointDerivativesProvider = new FieldCartesianAdjointDerivativesProvider<>(energy);
81 final Orbit orbit = new CartesianOrbit(new PVCoordinates(new Vector3D(7e6, 1e3, 0), new Vector3D(10., 7e3, -200)),
82 FramesFactory.getGCRF(), AbsoluteDate.ARBITRARY_EPOCH, Constants.EGM96_EARTH_MU);
83 final SpacecraftState state = new SpacecraftState(orbit, mass).addAdditionalData(name, new double[] {1., 2., 3., 4., 5., 6.});
84 final FieldSpacecraftState<Gradient> fieldState = new FieldSpacecraftState<>(GradientField.getField(1), state);
85
86 final FieldCombinedDerivatives<Gradient>fieldCombinedDerivatives = fieldAdjointDerivativesProvider.combinedDerivatives(fieldState);
87
88 final CartesianAdjointDerivativesProvider adjointDerivativesProvider = new CartesianAdjointDerivativesProvider(energy.toCartesianCost());
89 final CombinedDerivatives combinedDerivatives = adjointDerivativesProvider.combinedDerivatives(state);
90 for (int i = 0; i < 7; i++) {
91 Assertions.assertEquals(combinedDerivatives.getMainStateDerivativesIncrements()[i],
92 fieldCombinedDerivatives.getMainStateDerivativesIncrements()[i].getReal(), 1e-12);
93 }
94 for (int i = 0; i < 6; i++) {
95 Assertions.assertEquals(combinedDerivatives.getAdditionalDerivatives()[i],
96 fieldCombinedDerivatives.getAdditionalDerivatives()[i].getReal(), 1e-10);
97 }
98 }
99
100 @Test
101 void getFieldEventDetectorsSizeAndActionTest() {
102
103 final Complex massFlowRateFactor = new Complex(2);
104 final FieldUnboundedCartesianEnergy<Complex> unboundedCartesianEnergy = new FieldUnboundedCartesianEnergy<>("", massFlowRateFactor);
105 final Field<Complex> field = ComplexField.getInstance();
106
107 final Stream<FieldEventDetector<Complex>> eventDetectorStream = unboundedCartesianEnergy.getFieldEventDetectors(field);
108
109 final List<FieldEventDetector<Complex>> eventDetectors = eventDetectorStream.collect(Collectors.toList());
110 Assertions.assertEquals(1, eventDetectors.size());
111 Assertions.assertInstanceOf(FieldCartesianEnergyConsideringMass.FieldSingularityDetector.class, eventDetectors.get(0));
112 final FieldCartesianEnergyConsideringMass<Complex>.FieldSingularityDetector singularityDetector =
113 (FieldCartesianEnergyConsideringMass<Complex>.FieldSingularityDetector) eventDetectors.get(0);
114 Assertions.assertEquals(Action.RESET_DERIVATIVES, singularityDetector.getHandler().eventOccurred(null, null, false));
115 }
116
117 @Test
118 void getFieldEventDetectorsTest() {
119
120 final Complex massFlowRateFactor = new Complex(3);
121 final String name = "a";
122 final FieldUnboundedCartesianEnergy<Complex> unboundedCartesianEnergy = new FieldUnboundedCartesianEnergy<>(name, massFlowRateFactor);
123 final Field<Complex> field = ComplexField.getInstance();
124 final Orbit orbit = new CartesianOrbit(new PVCoordinates(new Vector3D(7e6, 1e3, 0), new Vector3D(10., 7e3, -200)),
125 FramesFactory.getGCRF(), AbsoluteDate.ARBITRARY_EPOCH, Constants.EGM96_EARTH_MU);
126 final SpacecraftState state = new SpacecraftState(orbit, 10.).addAdditionalData(name, new double[] {1., 2., 3., 4., 5., 6., 7.});
127
128 final Stream<FieldEventDetector<Complex>> fieldEventDetectorStream = unboundedCartesianEnergy.getFieldEventDetectors(field);
129
130 final List<FieldEventDetector<Complex>> fieldEventDetectors = fieldEventDetectorStream.collect(Collectors.toList());
131 Assertions.assertEquals(1, fieldEventDetectors.size());
132 Assertions.assertInstanceOf(FieldCartesianEnergyConsideringMass.FieldSingularityDetector.class, fieldEventDetectors.get(0));
133 final FieldCartesianEnergyConsideringMass<Complex>.FieldSingularityDetector fieldSingularityDetector =
134 (FieldCartesianEnergyConsideringMass<Complex>.FieldSingularityDetector) fieldEventDetectors.get(0);
135 final Complex gValue = fieldSingularityDetector.g(new FieldSpacecraftState<>(field, state));
136 final List<EventDetector> eventDetectors = unboundedCartesianEnergy.toCartesianCost().getEventDetectors().collect(Collectors.toList());
137 final CartesianEnergyConsideringMass.SingularityDetector singularityDetector =
138 (CartesianEnergyConsideringMass.SingularityDetector) eventDetectors.get(0);
139 final double expectedG = singularityDetector.g(state);
140 Assertions.assertEquals(expectedG, gValue.getReal());
141 }
142
143 @Test
144 void testToCartesianCost() {
145
146 final Complex massRateFactor = Complex.ONE;
147 final FieldUnboundedCartesianEnergy<Complex> fieldCartesianEnergy = new FieldUnboundedCartesianEnergy<>("",
148 massRateFactor);
149
150 final UnboundedCartesianEnergy cartesianEnergy = fieldCartesianEnergy.toCartesianCost();
151
152 Assertions.assertEquals(cartesianEnergy.getAdjointName(), fieldCartesianEnergy.getAdjointName());
153 }
154 }