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.complex.Complex;
20 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
21 import org.hipparchus.geometry.euclidean.threed.Vector3D;
22 import org.hipparchus.util.Binary64;
23 import org.hipparchus.util.Binary64Field;
24 import org.hipparchus.util.MathArrays;
25 import org.junit.jupiter.api.Assertions;
26 import org.junit.jupiter.api.Test;
27 import org.junit.jupiter.params.ParameterizedTest;
28 import org.junit.jupiter.params.provider.ValueSource;
29 import org.mockito.Mockito;
30 import org.orekit.frames.FramesFactory;
31 import org.orekit.orbits.CartesianOrbit;
32 import org.orekit.orbits.Orbit;
33 import org.orekit.propagation.FieldSpacecraftState;
34 import org.orekit.propagation.SpacecraftState;
35 import org.orekit.propagation.events.EventDetectionSettings;
36 import org.orekit.propagation.events.EventDetector;
37 import org.orekit.propagation.events.FieldEventDetectionSettings;
38 import org.orekit.propagation.events.FieldEventDetector;
39 import org.orekit.propagation.events.handlers.FieldResetDerivativesOnEvent;
40 import org.orekit.time.AbsoluteDate;
41 import org.orekit.utils.TimeStampedPVCoordinates;
42
43 import java.util.List;
44 import java.util.stream.Collectors;
45 import java.util.stream.Stream;
46
47 class FieldCartesianFuelCostTest {
48
49 @Test
50 void testConstructor() {
51
52 final EventDetectionSettings expectedDetectionSettings = EventDetectionSettings.getDefaultEventDetectionSettings();
53
54 final FieldCartesianFuelCost<Binary64> cartesianFuel = new FieldCartesianFuelCost<>("", new Binary64(1),
55 new Binary64(2));
56
57 final FieldEventDetectionSettings<Binary64> actualDetectionSettings = cartesianFuel.getEventDetectionSettings();
58 Assertions.assertEquals(expectedDetectionSettings.getMaxIterationCount(),
59 actualDetectionSettings.getMaxIterationCount());
60 Assertions.assertEquals(expectedDetectionSettings.getThreshold(), actualDetectionSettings.getThreshold().getReal());
61 }
62
63 @ParameterizedTest
64 @ValueSource(doubles = {-1e1, 1, 1e1})
65 void testUpdateFieldAdjointDerivatives(final double adjointMass) {
66
67 final Binary64 rateFactor = Binary64.ONE;
68 final Binary64 maximumThrust = new Binary64(2);
69 final FieldCartesianFuelCost<Binary64> cartesianFuel = new FieldCartesianFuelCost<>("", rateFactor, maximumThrust);
70 final double[] adjoint = new double[] {0, 0, 0, 0, 1, 0, adjointMass};
71 final Binary64[] fieldAdjoint = MathArrays.buildArray(Binary64Field.getInstance(), adjoint.length);
72 for (int i = 0; i < adjoint.length; i++) {
73 fieldAdjoint[i] = new Binary64(adjoint[i]);
74 }
75 final Binary64 mass = new Binary64(100);
76 final Binary64[] fieldDerivatives = MathArrays.buildArray(Binary64Field.getInstance(), adjoint.length);
77 final double[] derivatives = new double[adjoint.length];
78
79 cartesianFuel.updateFieldAdjointDerivatives(fieldAdjoint, mass, fieldDerivatives);
80
81 cartesianFuel.toCartesianCost().updateAdjointDerivatives(adjoint, mass.getReal(), derivatives);
82 Assertions.assertEquals(derivatives[6], fieldDerivatives[6].getReal());
83 }
84
85 @ParameterizedTest
86 @ValueSource(doubles = {-1e1, 1, 1e1})
87 void testGetFieldThrustAccelerationVector(final double adjointMass) {
88
89 final Binary64 rateFactor = Binary64.ONE;
90 final Binary64 maximumThrust = new Binary64(2);
91 final FieldCartesianFuelCost<Binary64> cartesianFuel = new FieldCartesianFuelCost<>("", rateFactor, maximumThrust);
92 final double[] adjoint = new double[] {0, 0, 0, 0, 1, 0, adjointMass};
93 final Binary64[] fieldAdjoint = MathArrays.buildArray(Binary64Field.getInstance(), adjoint.length);
94 for (int i = 0; i < adjoint.length; i++) {
95 fieldAdjoint[i] = new Binary64(adjoint[i]);
96 }
97 final Binary64 mass = new Binary64(100);
98
99 final FieldVector3D<Binary64> actual = cartesianFuel.getFieldThrustAccelerationVector(fieldAdjoint, mass);
100
101 Assertions.assertEquals(cartesianFuel.toCartesianCost().getThrustAccelerationVector(adjoint, mass.getReal()), actual.toVector3D());
102 }
103
104 @Test
105 @SuppressWarnings("unchecked")
106 void testGetFieldHamiltonianContribution() {
107
108 final FieldCartesianFuelCost<Binary64> cartesianFuel = Mockito.mock(FieldCartesianFuelCost.class);
109 final Binary64Field field = Binary64Field.getInstance();
110 final Binary64[] adjoint = MathArrays.buildArray(field, 0);
111 final Binary64 mass = Binary64.ONE;
112 final FieldVector3D<Binary64> accelerationVector = new FieldVector3D<>(field, new Vector3D(1, 2, 3));
113 Mockito.when(cartesianFuel.getFieldThrustAccelerationVector(adjoint, mass)).thenReturn(accelerationVector);
114 Mockito.when(cartesianFuel.getFieldHamiltonianContribution(adjoint, mass)).thenCallRealMethod();
115
116 final Binary64 actual = cartesianFuel.getFieldHamiltonianContribution(adjoint, mass);
117
118 Assertions.assertEquals(accelerationVector.scalarMultiply(mass).getNorm(), actual.negate());
119 }
120
121 @ParameterizedTest
122 @ValueSource(doubles = {0., 1.})
123 void testGetFieldEventDetectors(final double massFlowRateFactor) {
124
125 final String adjointName = "1";
126 final FieldCartesianFuelCost<Binary64> cartesianFuel = new FieldCartesianFuelCost<>(adjointName,
127 new Binary64(massFlowRateFactor), new Binary64(2));
128 final Binary64Field field = Binary64Field.getInstance();
129 final double mass = 3;
130
131 final Stream<FieldEventDetector<Binary64>> detectorStream = cartesianFuel.getFieldEventDetectors(field);
132
133 final List<FieldEventDetector<Binary64>> fieldDetectorList = detectorStream.collect(Collectors.toList());
134 final List<EventDetector> detectorList = cartesianFuel.toCartesianCost().getEventDetectors().collect(Collectors.toList());
135 Assertions.assertEquals(detectorList.size(), fieldDetectorList.size());
136 final EventDetector detector = detectorList.get(0);
137 final FieldEventDetector<Binary64> fieldEventDetector = fieldDetectorList.get(0);
138 Assertions.assertInstanceOf(FieldResetDerivativesOnEvent.class, fieldEventDetector.getHandler());
139 final FieldSpacecraftState<Binary64> fieldState = buildFieldState(mass, adjointName);
140 Assertions.assertEquals(detector.g(fieldState.toSpacecraftState()), fieldEventDetector.g(fieldState).getReal());
141 Assertions.assertEquals(detector.getDetectionSettings().getThreshold(),
142 fieldEventDetector.getDetectionSettings().getThreshold().getReal());
143 Assertions.assertEquals(detector.getDetectionSettings().getMaxIterationCount(),
144 fieldEventDetector.getDetectionSettings().getMaxIterationCount());
145 }
146
147 private static FieldSpacecraftState<Binary64> buildFieldState(final double mass, final String adjointName) {
148 final Orbit orbit = new CartesianOrbit(new TimeStampedPVCoordinates(AbsoluteDate.ARBITRARY_EPOCH,
149 new Vector3D(4, 5, 6), Vector3D.MINUS_K), FramesFactory.getEME2000(), 1);
150 final Binary64Field field = Binary64Field.getInstance();
151 final Binary64[] adjoint = MathArrays.buildArray(field, 7);
152 for (int i = 0; i < adjoint.length; i++) {
153 adjoint[i] = new Binary64(i + 1);
154 }
155 return new FieldSpacecraftState<>(field, new SpacecraftState(orbit).withMass(mass))
156 .addAdditionalData(adjointName, adjoint);
157 }
158
159 @Test
160 void testToCartesianCost() {
161
162 final Complex massRateFactor = Complex.ONE;
163 final FieldCartesianFuelCost<Complex> fieldCartesianEnergy = new FieldCartesianFuelCost<>("",
164 massRateFactor, new Complex(2));
165
166 final CartesianFuelCost cartesianEnergy = fieldCartesianEnergy.toCartesianCost();
167
168 Assertions.assertEquals(cartesianEnergy.getAdjointName(), fieldCartesianEnergy.getAdjointName());
169 Assertions.assertEquals(cartesianEnergy.getMaximumThrustMagnitude(),
170 fieldCartesianEnergy.getMaximumThrustMagnitude().getReal());
171 }
172 }
173