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.forces.maneuvers.jacobians;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.Field;
21  import org.hipparchus.geometry.euclidean.threed.Vector3D;
22  import org.junit.jupiter.api.Test;
23  import org.orekit.TestUtils;
24  import org.orekit.forces.ForceModel;
25  import org.orekit.forces.maneuvers.Control3DVectorCostType;
26  import org.orekit.forces.maneuvers.Maneuver;
27  import org.orekit.forces.maneuvers.propulsion.BasicConstantThrustPropulsionModel;
28  import org.orekit.forces.maneuvers.propulsion.PropulsionModel;
29  import org.orekit.forces.maneuvers.trigger.ManeuverTriggers;
30  import org.orekit.propagation.SpacecraftState;
31  import org.orekit.propagation.events.EventDetector;
32  import org.orekit.propagation.events.FieldEventDetector;
33  import org.orekit.propagation.integration.CombinedDerivatives;
34  import org.orekit.time.AbsoluteDate;
35  import org.orekit.time.FieldAbsoluteDate;
36  import org.orekit.utils.ParameterDriver;
37  
38  import java.util.Collections;
39  import java.util.List;
40  import java.util.stream.Stream;
41  
42  import static org.junit.jupiter.api.Assertions.assertEquals;
43  import static org.mockito.Mockito.mock;
44  import static org.mockito.Mockito.when;
45  
46  class MassDepletionDelayTest {
47  
48      @Test
49      void testGetDimension() {
50          // GIVEN
51          final Maneuver mockedManeuver = mock();
52          // WHEN
53          final MassDepletionDelay depletionDelay = new MassDepletionDelay("", true, mockedManeuver);
54          // THEN
55          assertEquals(6, depletionDelay.getDimension());
56      }
57  
58      @Test
59      void testCombinedDerivatives() {
60          // GIVEN
61          final double mass = 10;
62          final double[] depletionVariables = new double[] {0., 0., 0, 1, 2, 3};
63          final SpacecraftState state = new SpacecraftState(TestUtils.getDefaultOrbit(AbsoluteDate.ARBITRARY_EPOCH))
64                  .addAdditionalData("Orekit-depletion-", depletionVariables).withMass(mass);
65          final PropulsionModel propulsionModel = new DummyPropulsionModel();
66          final Maneuver maneuver = new Maneuver(null, new DummyTrigger(), propulsionModel);
67          final Vector3D acceleration = new Vector3D(4, 5, 6);
68          final ForceModel mockedForceModel = mock(ForceModel.class);
69          final double[] parameters = new double[0];
70          when(mockedForceModel.acceleration(state, parameters)).thenReturn(acceleration);
71          when(mockedForceModel.getParameters(state.getDate())).thenReturn(parameters);
72          final MassDepletionDelay depletionDelay = new MassDepletionDelay("", true, maneuver,
73                  mockedForceModel);
74          // WHEN
75          depletionDelay.init(state, AbsoluteDate.FUTURE_INFINITY);
76          final CombinedDerivatives combinedDerivatives = depletionDelay.combinedDerivatives(state);
77          // THEN
78          final double[] derivatives = combinedDerivatives.getAdditionalDerivatives();
79          assertEquals(depletionVariables[3], derivatives[0]);
80          assertEquals(depletionVariables[4], derivatives[1]);
81          assertEquals(depletionVariables[5], derivatives[2]);
82          final double delta = 1e-12;
83          assertEquals(-acceleration.getX() / mass, derivatives[3], delta);
84          assertEquals(-acceleration.getY() / mass, derivatives[4], delta);
85          assertEquals(-acceleration.getZ() / mass, derivatives[5], delta);
86      }
87  
88      private static class DummyTrigger implements ManeuverTriggers {
89  
90          @Override
91          public boolean isFiring(AbsoluteDate date, double[] parameters) {
92              return true;
93          }
94  
95          @Override
96          public <T extends CalculusFieldElement<T>> boolean isFiring(FieldAbsoluteDate<T> date, T[] parameters) {
97              return true;
98          }
99  
100         @Override
101         public Stream<EventDetector> getEventDetectors() {
102             return Stream.empty();
103         }
104 
105         @Override
106         public <T extends CalculusFieldElement<T>> Stream<FieldEventDetector<T>> getFieldEventDetectors(Field<T> field) {
107             return Stream.empty();
108         }
109 
110         @Override
111         public List<ParameterDriver> getParametersDrivers() {
112             return Collections.emptyList();
113         }
114     }
115 
116     private static class DummyPropulsionModel extends BasicConstantThrustPropulsionModel {
117 
118         public DummyPropulsionModel() {
119             super(0., Double.POSITIVE_INFINITY, Vector3D.MINUS_I, Control3DVectorCostType.NONE, "name");
120         }
121     }
122 }