1   /* Copyright 2002-2025 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.utils;
18  
19  import java.util.List;
20  import java.util.Map;
21  
22  import org.orekit.propagation.SpacecraftState;
23  import org.orekit.propagation.numerical.EpochDerivativesEquations;
24  import org.orekit.propagation.numerical.NumericalPropagator;
25  
26  /**
27   * Multiple shooting method applicable for trajectories, in an ephemeris model.
28   * Not suited for closed orbits.
29   * @see "TRAJECTORY DESIGN AND ORBIT MAINTENANCE STRATEGIES IN MULTI-BODY DYNAMICAL REGIMES by Thomas A. Pavlak, Purdue University"
30   * @author William Desprats
31   * @author Alberto Fossà
32   * @since 10.2
33   */
34  public class MultipleShooter extends AbstractMultipleShooting {
35  
36      /** Name of the additional derivatives. */
37      private static final String DERIVATIVES = "derivatives";
38  
39      /** Derivatives linked to the Propagators.
40       * @since 11.1
41       */
42      private final List<EpochDerivativesEquations> epochEquations;
43  
44      /** Simple Constructor.
45       * <p> Standard constructor for multiple shooting which can be used with non-autonomous systems.</p>
46       * @param initialGuessList initial patch points to be corrected
47       * @param propagatorList list of propagators associated to each patch point
48       * @param epochEquations list of additional derivatives providers linked to propagatorList
49       * @param tolerance convergence tolerance on the constraint vector
50       * @param maxIter maximum number of iterations
51       */
52      public MultipleShooter(final List<SpacecraftState> initialGuessList,
53                             final List<NumericalPropagator> propagatorList,
54                             final List<EpochDerivativesEquations> epochEquations,
55                             final double tolerance, final int maxIter) {
56          super(initialGuessList, propagatorList, tolerance, maxIter, false, DERIVATIVES);
57          this.epochEquations = epochEquations;
58      }
59  
60      /** {@inheritDoc} */
61      protected SpacecraftState getAugmentedInitialState(final int i) {
62          return epochEquations.get(i).setInitialJacobians(getPatchPoint(i));
63      }
64  
65      /** {@inheritDoc} */
66      protected double[][] computeAdditionalJacobianMatrix(final List<SpacecraftState> propagatedSP) {
67  
68          final Map<Integer, Double> mapConstraints = getConstraintsMap();
69          final double[][] M = new double[mapConstraints.size()][getNumberOfFreeComponents()];
70  
71          int k = 0;
72          for (int index : mapConstraints.keySet()) {
73              M[k][index] = 1.0;
74              k++;
75          }
76          return M;
77      }
78  
79      /** {@inheritDoc} */
80      protected double[] computeAdditionalConstraints(final List<SpacecraftState> propagatedSP) {
81          // The additional constraint vector has the following form :
82  
83          //           [ y1i - y1d ]---- other constraints (component of
84          // Fadd(X) = [    ...    ]    | a patch point equals to a
85          //           [vz2i - vz2d]----  desired value)
86  
87          // Number of additional constraints
88          final double[] fxAdditional = new double[getConstraintsMap().size()];
89  
90          // Update additional constraints
91          updateAdditionalConstraints(0, fxAdditional);
92          return fxAdditional;
93      }
94  
95  }