1   /* Copyright 2022-2025 Romain Serra
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.control.indirect.adjoint;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.analysis.differentiation.FieldGradient;
21  import org.hipparchus.analysis.differentiation.Gradient;
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.util.MathArrays;
27  import org.junit.jupiter.api.Assertions;
28  import org.junit.jupiter.api.Test;
29  import org.mockito.Mockito;
30  import org.orekit.frames.Frame;
31  import org.orekit.time.AbsoluteDate;
32  import org.orekit.time.FieldAbsoluteDate;
33  
34  class AbstractCartesianAdjointEquationTermTest {
35  
36      @Test
37      void testBuildGradientCartesianVector() {
38          // GIVEN
39          final double[] variables = {1, 2, 3, 4, 5, 6};
40          // WHEN
41          final Gradient[] gradients = AbstractCartesianAdjointEquationTerm.buildGradientCartesianVector(variables);
42          // THEN
43          for (int i = 0; i < gradients.length; i++) {
44              Assertions.assertEquals(6, gradients[i].getFreeParameters());
45              Assertions.assertEquals(gradients[i].getValue(), variables[i]);
46              Assertions.assertEquals(1, gradients[i].getGradient()[i]);
47          }
48      }
49  
50      @Test
51      void testBuildFieldGradientCartesianVector() {
52          // GIVEN
53          final Complex[] variables = MathArrays.buildArray(ComplexField.getInstance(), 6);
54          for (int i = 0; i < variables.length; i++) {
55              variables[i] = Complex.ONE.multiply(i);
56          }
57          // WHEN
58          final FieldGradient<Complex>[] gradients = AbstractCartesianAdjointEquationTerm.buildFieldGradientCartesianVector(variables);
59          // THEN
60          for (int i = 0; i < gradients.length; i++) {
61              Assertions.assertEquals(6, gradients[i].getFreeParameters());
62              Assertions.assertEquals(gradients[i].getValue(), variables[i]);
63              Assertions.assertEquals(Complex.ONE, gradients[i].getGradient()[i]);
64          }
65      }
66  
67      @Test
68      void testGetFieldRatesContribution() {
69          // GIVEN
70          final Complex[] fieldState = MathArrays.buildArray(ComplexField.getInstance(), 6);
71          final Complex[] fieldAdjoint = MathArrays.buildArray(ComplexField.getInstance(), 6);
72          for (int i = 0; i < fieldAdjoint.length; i++) {
73              fieldState[i] = Complex.MINUS_ONE;
74              fieldAdjoint[i] = Complex.ONE.multiply(i);
75          }
76          final TestAdjointTerm adjointTerm = new TestAdjointTerm();
77          final FieldAbsoluteDate<Complex> fieldDate = FieldAbsoluteDate.getArbitraryEpoch(ComplexField.getInstance());
78          final Frame frame = Mockito.mock(Frame.class);
79          // WHEN
80          final Complex[] fieldRatesContribution = adjointTerm.getFieldRatesContribution(fieldDate, fieldState, fieldAdjoint, frame);
81          // THEN
82          final double[] states = new double[fieldAdjoint.length];
83          final double[] adjoint = new double[fieldAdjoint.length];
84          for (int i = 0; i < adjoint.length; i++) {
85              states[i] = fieldState[i].getReal();
86              adjoint[i] = fieldAdjoint[i].getReal();
87          }
88          final double[] ratesContribution = adjointTerm.getRatesContribution(fieldDate.toAbsoluteDate(), states, adjoint, frame);
89          for (int i = 0; i < fieldRatesContribution.length; i++) {
90              Assertions.assertEquals(fieldRatesContribution[i].getReal(), ratesContribution[i]);
91          }
92      }
93  
94      private static class TestAdjointTerm extends AbstractCartesianAdjointEquationTerm {
95          public TestAdjointTerm() {}
96  
97          @Override
98          protected Vector3D getAcceleration(AbsoluteDate date, double[] stateVariables, Frame frame) {
99              return new Vector3D(stateVariables[0], stateVariables[1], stateVariables[5]);
100         }
101 
102         @Override
103         protected <T extends CalculusFieldElement<T>> FieldVector3D<T> getFieldAcceleration(FieldAbsoluteDate<T> date, T[] stateVariables, Frame frame) {
104             return new FieldVector3D<>(date.getField(),
105                     new Vector3D(stateVariables[0].getReal(), stateVariables[1].getReal(), stateVariables[5].getReal()));
106         }
107     }
108 }