1   /* Copyright 2002-2022 CS GROUP
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.propagation.numerical;
18  
19  import java.util.List;
20  
21  import org.hipparchus.geometry.euclidean.threed.Vector3D;
22  import org.hipparchus.linear.MatrixUtils;
23  import org.hipparchus.linear.RealMatrix;
24  import org.hipparchus.ode.nonstiff.AdaptiveStepsizeIntegrator;
25  import org.hipparchus.ode.nonstiff.DormandPrince853Integrator;
26  import org.junit.After;
27  import org.junit.Assert;
28  import org.junit.Before;
29  import org.junit.Test;
30  import org.orekit.errors.OrekitException;
31  import org.orekit.errors.OrekitMessages;
32  import org.orekit.forces.maneuvers.Maneuver;
33  import org.orekit.forces.maneuvers.propulsion.BasicConstantThrustPropulsionModel;
34  import org.orekit.forces.maneuvers.propulsion.PropulsionModel;
35  import org.orekit.forces.maneuvers.trigger.DateBasedManeuverTriggers;
36  import org.orekit.frames.FramesFactory;
37  import org.orekit.orbits.KeplerianOrbit;
38  import org.orekit.orbits.Orbit;
39  import org.orekit.orbits.OrbitType;
40  import org.orekit.orbits.PositionAngle;
41  import org.orekit.propagation.SpacecraftState;
42  import org.orekit.time.AbsoluteDate;
43  import org.orekit.utils.AbsolutePVCoordinates;
44  import org.orekit.utils.Constants;
45  import org.orekit.utils.DoubleArrayDictionary;
46  
47  public class NumericalPropagationHarvesterTest {
48  
49      @Test
50      public void testNullStmName() {
51           try {
52              propagator.setupMatricesComputation(null, null, null);
53              Assert.fail("an exception should have been thrown");
54          } catch (OrekitException oe) {
55              Assert.assertEquals(OrekitMessages.NULL_ARGUMENT, oe.getSpecifier());
56              Assert.assertEquals("stmName", oe.getParts()[0]);
57          }
58      }
59  
60      @Test
61      public void testUnknownStmName() {
62          NumericalPropagationHarvester harvester =
63                          (NumericalPropagationHarvester) propagator.setupMatricesComputation("stm",
64                                                                                              MatrixUtils.createRealIdentityMatrix(6),
65                                                                                              new DoubleArrayDictionary());
66          Assert.assertNull(harvester.getStateTransitionMatrix(propagator.getInitialState()));
67      }
68  
69      @Test
70      public void testUnknownColumnName() {
71          NumericalPropagationHarvester harvester =
72                          (NumericalPropagationHarvester) propagator.setupMatricesComputation("stm",
73                                                                                              MatrixUtils.createRealIdentityMatrix(6),
74                                                                                              new DoubleArrayDictionary());
75          Assert.assertNull(harvester.getParametersJacobian(propagator.getInitialState()));
76      }
77  
78      @Test
79      public void testDefaultNonNullInitialJacobian() {
80          NumericalPropagationHarvester harvester =
81                          (NumericalPropagationHarvester) propagator.setupMatricesComputation("stm",
82                                                                                              MatrixUtils.createRealIdentityMatrix(6),
83                                                                                              new DoubleArrayDictionary());
84          Assert.assertNotNull(harvester.getInitialJacobianColumn("xyz"));
85      }
86  
87      @Test
88      public void testInitialStmCartesian() {
89          doTestInitialStm(OrbitType.CARTESIAN, 0.0);
90      }
91  
92      @Test
93      public void testInitialStmKeplerian() {
94          doTestInitialStm(OrbitType.KEPLERIAN, 2160.746);
95      }
96  
97      @Test
98      public void testInitialStmAbsPV() {
99          SpacecraftState state = propagator.getInitialState();
100         SpacecraftState absPV =
101                         new SpacecraftState(new AbsolutePVCoordinates(state.getFrame(),
102                                                                       state.getPVCoordinates()));
103         propagator.setInitialState(absPV);
104         doTestInitialStm(null, 0.0);
105     }
106 
107     @Test
108     public void testColumnsNames() {
109 
110         NumericalPropagationHarvester harvester =
111                         (NumericalPropagationHarvester) propagator.setupMatricesComputation("stm",
112                                                                                             MatrixUtils.createRealIdentityMatrix(6),
113                                                                                             new DoubleArrayDictionary());
114         Assert.assertTrue(harvester.getJacobiansColumnsNames().isEmpty());
115 
116         DateBasedManeuverTriggers triggers = new DateBasedManeuverTriggers("apogee_boost", propagator.getInitialState().getDate().shiftedBy(60.0), 120.0);
117         PropulsionModel propulsion = new BasicConstantThrustPropulsionModel(400.0, 350.0, Vector3D.PLUS_I, "ABM-");
118         propagator.addForceModel(new Maneuver(null, triggers, propulsion));
119         Assert.assertTrue(harvester.getJacobiansColumnsNames().isEmpty());
120 
121         triggers.getParametersDrivers().get(1).setSelected(true);
122         propulsion.getParametersDrivers().get(0).setSelected(true);
123         List<String> columnsNames = harvester.getJacobiansColumnsNames();
124         Assert.assertEquals(2, columnsNames.size());
125         Assert.assertEquals("ABM-" + BasicConstantThrustPropulsionModel.THRUST, columnsNames.get(0));
126         Assert.assertEquals("apogee_boost_STOP", columnsNames.get(1));
127 
128     }
129 
130     private void doTestInitialStm(OrbitType type, double deltaId) {
131         NumericalPropagationHarvester harvester =
132                         (NumericalPropagationHarvester) propagator.setupMatricesComputation("stm", null, null);
133         propagator.setOrbitType(type);
134         propagator.setPositionAngleType(PositionAngle.TRUE);
135         double[] p = new double[36];
136         for (int i = 0; i < p.length; i += 7) {
137             p[i] = 1.0;
138         }
139         SpacecraftState s = propagator.getInitialState().addAdditionalState(harvester.getStmName(), p);
140         RealMatrix stm = harvester.getStateTransitionMatrix(s);
141         Assert.assertEquals(deltaId, stm.subtract(MatrixUtils.createRealIdentityMatrix(6)).getNorm1(), 1.0e-3);
142     }
143 
144     @Before
145     public void setUp() {
146         Orbit initialOrbit =
147                         new KeplerianOrbit(8000000.0, 0.01, 0.1, 0.7, 0, 1.2, PositionAngle.TRUE,
148                                            FramesFactory.getEME2000(), AbsoluteDate.J2000_EPOCH,
149                                            Constants.EIGEN5C_EARTH_MU);
150         double minStep = 0.0001;
151         double maxStep = 60;
152         double[][] tolerances = NumericalPropagator.tolerances(0.001, initialOrbit, initialOrbit.getType());
153         AdaptiveStepsizeIntegrator integrator = new DormandPrince853Integrator(minStep, maxStep, tolerances[0], tolerances[1]);
154         integrator.setInitialStepSize(1.0);
155         propagator = new NumericalPropagator(integrator);
156         propagator.setInitialState(new SpacecraftState(initialOrbit));
157     }
158 
159     @After
160     public void tearDown() {
161         propagator = null;
162     }
163 
164     private NumericalPropagator propagator;
165 
166 }