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.geometry.euclidean.threed.FieldVector3D;
20  import org.hipparchus.geometry.euclidean.threed.Vector3D;
21  import org.hipparchus.util.Binary64;
22  import org.hipparchus.util.Binary64Field;
23  import org.hipparchus.util.MathArrays;
24  import org.junit.jupiter.api.Assertions;
25  import org.junit.jupiter.api.Test;
26  import org.mockito.Mockito;
27  import org.orekit.bodies.CelestialBody;
28  import org.orekit.forces.gravity.ThirdBodyAttraction;
29  import org.orekit.frames.Frame;
30  import org.orekit.frames.FramesFactory;
31  import org.orekit.orbits.CartesianOrbit;
32  import org.orekit.orbits.OrbitType;
33  import org.orekit.orbits.PositionAngleType;
34  import org.orekit.propagation.SpacecraftState;
35  import org.orekit.time.AbsoluteDate;
36  import org.orekit.time.FieldAbsoluteDate;
37  import org.orekit.utils.ExtendedPositionProvider;
38  import org.orekit.utils.TimeStampedPVCoordinates;
39  
40  class CartesianAdjointThirdBodyTermTest {
41  
42      @Test
43      void testGetAcceleration() {
44          // GIVEN
45          final double mu = 2.;
46          final Frame frame = FramesFactory.getGCRF();
47          final AbsoluteDate date = AbsoluteDate.ARBITRARY_EPOCH;
48          final CelestialBody mockedPositionProvider = Mockito.mock(CelestialBody.class);
49          final Vector3D bodyPosition = new Vector3D(1, -2, 10);
50          Mockito.when(mockedPositionProvider.getPosition(date, frame)).thenReturn(bodyPosition);
51          final CartesianAdjointThirdBodyTerm thirdBodyTerm = new CartesianAdjointThirdBodyTerm(mu,
52                  mockedPositionProvider);
53          final CartesianOrbit orbit = new CartesianOrbit(new TimeStampedPVCoordinates(date, Vector3D.MINUS_J, Vector3D.MINUS_K),
54                  frame, mu);
55          final double[] state = new double[6];
56          OrbitType.CARTESIAN.mapOrbitToArray(orbit, PositionAngleType.ECCENTRIC, state, null);
57          // WHEN
58          final Vector3D acceleration = thirdBodyTerm.getAcceleration(date, state, frame);
59          // THEN
60          final ThirdBodyAttraction thirdBodyAttraction = new ThirdBodyAttraction(mockedPositionProvider);
61          final Vector3D expectedAcceleration = thirdBodyAttraction.acceleration(new SpacecraftState(orbit), new double[] {mu});
62          final double tolerance = 1e-15;
63          Assertions.assertEquals(expectedAcceleration.getX(), acceleration.getX(), tolerance);
64          Assertions.assertEquals(expectedAcceleration.getY(), acceleration.getY(), tolerance);
65          Assertions.assertEquals(expectedAcceleration.getZ(), acceleration.getZ(), tolerance);
66      }
67  
68      @Test
69      void testGetFieldAcceleration() {
70          // GIVEN
71          final double mu = 3e14;
72          final Frame frame = FramesFactory.getGCRF();
73          final Binary64Field field = Binary64Field.getInstance();
74          final FieldAbsoluteDate<Binary64> fieldDate = FieldAbsoluteDate.getArbitraryEpoch(field);
75          final ExtendedPositionProvider mockedPositionProvider = Mockito.mock(ExtendedPositionProvider.class);
76          final AbsoluteDate date = fieldDate.toAbsoluteDate();
77          final Vector3D bodyPosition = new Vector3D(1e4, -2e5, 1e4);
78          Mockito.when(mockedPositionProvider.getPosition(date, frame)).thenReturn(bodyPosition);
79          Mockito.when(mockedPositionProvider.getPosition(fieldDate, frame)).thenReturn(new FieldVector3D<>(field, bodyPosition));
80          final CartesianAdjointThirdBodyTerm thirdBodyTerm = new CartesianAdjointThirdBodyTerm(mu,
81                  mockedPositionProvider);
82          final Binary64[] fieldAdjoint = MathArrays.buildArray(field, 6);
83          final Binary64[] fieldState = MathArrays.buildArray(field, 6);
84          for (int i = 0; i < fieldAdjoint.length; i++) {
85              fieldState[i] = field.getZero().newInstance(i*10);
86              fieldAdjoint[i] = field.getZero().newInstance(i*2+1);
87          }
88          // WHEN
89          final FieldVector3D<Binary64> fieldAcceleration = thirdBodyTerm.getFieldAcceleration(fieldDate,
90                  fieldState, frame);
91          // THEN
92          final double[] state = new double[fieldState.length];
93          for (int i = 0; i < fieldState.length; i++) {
94              state[i] = fieldState[i].getReal();
95          }
96          final Vector3D acceleration = thirdBodyTerm.getAcceleration(date, state, frame);
97          Assertions.assertEquals(fieldAcceleration.getX().getReal(), acceleration.getX());
98          Assertions.assertEquals(fieldAcceleration.getY().getReal(), acceleration.getY());
99          Assertions.assertEquals(fieldAcceleration.getZ().getReal(), acceleration.getZ());
100     }
101 
102     @Test
103     void testGetPositionAdjointFieldContributionAgainstKeplerian() {
104         // GIVEN
105         final double mu = 1.32712440017987E20;
106         final Frame frame = FramesFactory.getGCRF();
107         final Binary64Field field = Binary64Field.getInstance();
108         final FieldAbsoluteDate<Binary64> fieldDate = FieldAbsoluteDate.getArbitraryEpoch(field);
109         final ExtendedPositionProvider mockedPositionProvider = Mockito.mock(ExtendedPositionProvider.class);
110         Mockito.when(mockedPositionProvider.getPosition(fieldDate, frame)).thenReturn(FieldVector3D.getZero(field));
111         final CartesianAdjointThirdBodyTerm thirdBodyTerm = new CartesianAdjointThirdBodyTerm(mu,
112                 mockedPositionProvider);
113         final Binary64[] fieldAdjoint = MathArrays.buildArray(field, 6);
114         final Binary64[] fieldState = MathArrays.buildArray(field, 6);
115         for (int i = 0; i < fieldAdjoint.length; i++) {
116             fieldState[i] = field.getZero().newInstance(-i*20);
117             fieldAdjoint[i] = field.getZero().newInstance(i);
118         }
119         // WHEN
120         final Binary64[] fieldContribution = thirdBodyTerm.getPositionAdjointFieldContribution(fieldDate,
121                 fieldState, fieldAdjoint, frame);
122         // THEN
123         final CartesianAdjointKeplerianTerm keplerianTerm = new CartesianAdjointKeplerianTerm(mu);
124         final Binary64[] contribution = keplerianTerm.getPositionAdjointFieldContribution(fieldDate, fieldState,
125                 fieldAdjoint, frame);
126         for (int i = 0; i < contribution.length; i++) {
127             Assertions.assertEquals(fieldContribution[i], contribution[i]);
128         }
129     }
130 }