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
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.FastMath;
25 import org.hipparchus.util.MathArrays;
26 import org.junit.jupiter.api.Assertions;
27 import org.junit.jupiter.params.ParameterizedTest;
28 import org.junit.jupiter.params.provider.ValueSource;
29 import org.orekit.control.indirect.adjoint.CartesianAdjointDerivativesProvider;
30 import org.orekit.control.indirect.adjoint.FieldCartesianAdjointDerivativesProvider;
31 import org.orekit.frames.FramesFactory;
32 import org.orekit.orbits.CartesianOrbit;
33 import org.orekit.propagation.FieldSpacecraftState;
34 import org.orekit.propagation.SpacecraftState;
35 import org.orekit.propagation.integration.CombinedDerivatives;
36 import org.orekit.propagation.integration.FieldAdditionalDerivativesProvider;
37 import org.orekit.propagation.integration.FieldCombinedDerivatives;
38 import org.orekit.time.AbsoluteDate;
39 import org.orekit.utils.PVCoordinates;
40
41 class FieldLogarithmicBarrierCartesianFuelTest {
42
43 private static final String ADJOINT_NAME = "adjoint";
44
45 @ParameterizedTest
46 @ValueSource(booleans = {false, true})
47 void testUpdateFieldAdjointDerivatives(final boolean withMass) {
48
49 final Binary64 massFlowRateFactor = withMass ? Binary64.ONE : Binary64.ZERO;
50 final FieldLogarithmicBarrierCartesianFuel<Binary64> cost = new FieldLogarithmicBarrierCartesianFuel<>("adjoint", massFlowRateFactor,
51 Binary64.PI, new Binary64(0.5));
52 final Binary64[] adjoint = MathArrays.buildArray(Binary64Field.getInstance(), withMass ? 7 : 6);
53 final Binary64[] derivatives = adjoint.clone();
54 adjoint[3] = Binary64.ONE;
55
56 cost.updateFieldAdjointDerivatives(adjoint, Binary64.ONE, derivatives);
57
58 final Binary64 zero = Binary64.ZERO;
59 for (int i = 0; i < 6; ++i) {
60 Assertions.assertEquals(zero, derivatives[i]);
61 }
62 if (withMass) {
63 Assertions.assertNotEquals(zero, derivatives[derivatives.length - 1]);
64 } else {
65 Assertions.assertEquals(zero, derivatives[derivatives.length - 1]);
66 }
67 }
68
69 @ParameterizedTest
70 @ValueSource(doubles = {0, 0.1, 0.5, 0.9})
71 void testEvaluateFieldPenaltyFunction(final double norm) {
72
73 final FieldLogarithmicBarrierCartesianFuel<Binary64> penalizedCartesianFuel = new FieldLogarithmicBarrierCartesianFuel<>(
74 ADJOINT_NAME, Binary64.ONE, Binary64.PI, Binary64.ZERO);
75
76 final Binary64 actualPenalty = penalizedCartesianFuel.evaluateFieldPenaltyFunction(Binary64.ONE.newInstance(norm));
77
78 Assertions.assertEquals(FastMath.log(norm) + FastMath.log(1 - norm), actualPenalty.getReal());
79 }
80
81 @ParameterizedTest
82 @ValueSource(doubles = {1e-3, 1e-2, 0.5, 0.999})
83 void testGetFieldHamiltonianContribution(final double epsilon) {
84
85 final FieldLogarithmicBarrierCartesianFuel<Binary64> fieldCost = new FieldLogarithmicBarrierCartesianFuel<>(
86 ADJOINT_NAME, Binary64.ONE, Binary64.PI, new Binary64(epsilon));
87 final double[] adjoint = new double[] {1, 2, 3, 4, 5, 6, 7};
88 final Binary64[] fieldAdjoint = MathArrays.buildArray(Binary64Field.getInstance(), adjoint.length);
89 for (int i = 0; i < adjoint.length; i++) {
90 fieldAdjoint[i] = fieldCost.getEpsilon().newInstance(adjoint[i]);
91 }
92 final Binary64 mass = new Binary64(100);
93
94 final Binary64 actualPenalty = fieldCost.getFieldHamiltonianContribution(fieldAdjoint, mass);
95
96 final LogarithmicBarrierCartesianFuel cost = fieldCost.toCartesianCost();
97 Assertions.assertEquals(cost.getHamiltonianContribution(adjoint, mass.getReal()), actualPenalty.getReal());
98 }
99
100 @ParameterizedTest
101 @ValueSource(doubles = {1e-3, 1e-2, 0.5, 0.999})
102 void testGetFieldThrustAccelerationVector(final double epsilon) {
103
104 final FieldLogarithmicBarrierCartesianFuel<Binary64> fieldCost = new FieldLogarithmicBarrierCartesianFuel<>(
105 ADJOINT_NAME, Binary64.ONE, Binary64.PI, new Binary64(epsilon));
106 final double[] adjoint = new double[] {1, 2, 3, 4, 5, 6, 7};
107 final Binary64[] fieldAdjoint = MathArrays.buildArray(Binary64Field.getInstance(), adjoint.length);
108 for (int i = 0; i < adjoint.length; i++) {
109 fieldAdjoint[i] = fieldCost.getEpsilon().newInstance(adjoint[i]);
110 }
111 final Binary64 mass = new Binary64(1000);
112
113 final FieldVector3D<Binary64> actualThrust = fieldCost.getFieldThrustAccelerationVector(fieldAdjoint, mass);
114
115 final LogarithmicBarrierCartesianFuel cost = fieldCost.toCartesianCost();
116 Assertions.assertEquals(cost.getThrustAccelerationVector(adjoint, mass.getReal()), actualThrust.toVector3D());
117 }
118
119 @ParameterizedTest
120 @ValueSource(doubles = {1, 1e2, 1e4})
121 void testAgainstNonField(final double mass) {
122
123 final double massFlowRateFactor = 1.e-2;
124 final double maximumThrustMagnitude = 1e-3;
125 final double epsilon = 0.5;
126 final Binary64 zero = Binary64.ZERO;
127 final FieldLogarithmicBarrierCartesianFuel<Binary64> fieldCost = new FieldLogarithmicBarrierCartesianFuel<>(ADJOINT_NAME,
128 zero.newInstance(massFlowRateFactor), zero.newInstance(maximumThrustMagnitude), zero.newInstance(epsilon));
129 final SpacecraftState state = buildState(mass);
130 final FieldSpacecraftState<Binary64> fieldState = new FieldSpacecraftState<>(Binary64Field.getInstance(), state);
131 final FieldAdditionalDerivativesProvider<Binary64> derivativesProvider = new FieldCartesianAdjointDerivativesProvider<>(fieldCost);
132
133 final FieldCombinedDerivatives<Binary64> actualDerivatives = derivativesProvider.combinedDerivatives(fieldState);
134
135 final LogarithmicBarrierCartesianFuel cost = new LogarithmicBarrierCartesianFuel(ADJOINT_NAME,
136 massFlowRateFactor, maximumThrustMagnitude, epsilon);
137 final CombinedDerivatives expectedDerivatives = new CartesianAdjointDerivativesProvider(cost)
138 .combinedDerivatives(state);
139 for (int i = 0; i < expectedDerivatives.getMainStateDerivativesIncrements().length; i++) {
140 Assertions.assertEquals(expectedDerivatives.getMainStateDerivativesIncrements()[i],
141 actualDerivatives.getMainStateDerivativesIncrements()[i].getReal(), 1e-12);
142 }
143 for (int i = 0; i < expectedDerivatives.getAdditionalDerivatives().length; i++) {
144 Assertions.assertEquals(expectedDerivatives.getAdditionalDerivatives()[i],
145 actualDerivatives.getAdditionalDerivatives()[i].getReal());
146 }
147 }
148
149 private SpacecraftState buildState(final double mass) {
150 final double[] adjoint = new double[] {1, 2, 3, 4, 5, 6, 7};
151 final CartesianOrbit orbit = new CartesianOrbit(new PVCoordinates(Vector3D.MINUS_I, Vector3D.MINUS_K),
152 FramesFactory.getEME2000(), AbsoluteDate.ARBITRARY_EPOCH, 1.);
153 return new SpacecraftState(orbit, mass).addAdditionalData(ADJOINT_NAME, adjoint);
154 }
155 }