CR3BPMultipleShooter.java

  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.cr3bp;

  18. import java.util.List;
  19. import java.util.Map;
  20. import java.util.stream.Collectors;

  21. import org.orekit.propagation.SpacecraftState;
  22. import org.orekit.propagation.numerical.NumericalPropagator;
  23. import org.orekit.utils.AbsolutePVCoordinates;
  24. import org.orekit.utils.AbstractMultipleShooting;

  25. /**
  26.  * Multiple shooting method applicable for orbits, either propagation in CR3BP, or in an ephemeris model.
  27.  * @see "TRAJECTORY DESIGN AND ORBIT MAINTENANCE STRATEGIES IN MULTI-BODY DYNAMICAL REGIMES by Thomas A. Pavlak, Purdue University"
  28.  * @author William Desprats
  29.  */
  30. public class CR3BPMultipleShooter extends AbstractMultipleShooting {

  31.     /** Name of the derivatives. */
  32.     private static final String STM = "stmEquations";

  33.     /** Derivatives linked to the Propagators.
  34.      * @since 11.1
  35.      */
  36.     private final List<STMEquations> stmEquations;

  37.     /** Number of patch points. */
  38.     private int npoints;

  39.     /** Simple Constructor.
  40.      * <p> Standard constructor for multiple shooting which can be used with the CR3BP model.</p>
  41.      * @param initialGuessList initial patch points to be corrected.
  42.      * @param propagatorList list of propagators associated to each patch point.
  43.      * @param additionalEquations list of additional equations linked to propagatorList.
  44.      * @param arcDuration initial guess of the duration of each arc.
  45.      * @param tolerance convergence tolerance on the constraint vector
  46.      * @deprecated as of 11.1, replaced by {@link #CR3BPMultipleShooter(List, List, List, double, double, int)}
  47.      */
  48.     @Deprecated
  49.     public CR3BPMultipleShooter(final List<SpacecraftState> initialGuessList, final List<NumericalPropagator> propagatorList,
  50.                                  final List<org.orekit.propagation.integration.AdditionalEquations> additionalEquations,
  51.                                  final double arcDuration, final double tolerance) {
  52.         super(initialGuessList, propagatorList, additionalEquations, arcDuration, tolerance, STM);
  53.         stmEquations = additionalEquations.stream().map(ae -> (STMEquations) ae).collect(Collectors.toList());
  54.         npoints      = initialGuessList.size();
  55.     }

  56.     /** Simple Constructor.
  57.      * <p> Standard constructor for multiple shooting which can be used with the CR3BP model.</p>
  58.      * @param initialGuessList initial patch points to be corrected.
  59.      * @param propagatorList list of propagators associated to each patch point.
  60.      * @param stmEquations list of additional derivatives providers linked to propagatorList.
  61.      * @param arcDuration initial guess of the duration of each arc.
  62.      * @param tolerance convergence tolerance on the constraint vector
  63.      * @param maxIter maximum number of iterations
  64.      */
  65.     public CR3BPMultipleShooter(final List<SpacecraftState> initialGuessList, final List<NumericalPropagator> propagatorList,
  66.                                 final List<STMEquations> stmEquations, final double arcDuration,
  67.                                 final double tolerance, final int maxIter) {
  68.         super(initialGuessList, propagatorList, arcDuration, tolerance, maxIter, STM);
  69.         this.stmEquations = stmEquations;
  70.         this.npoints      = initialGuessList.size();
  71.     }

  72.     /** {@inheritDoc} */
  73.     protected SpacecraftState getAugmentedInitialState(final int i) {
  74.         return stmEquations.get(i).setInitialPhi(getPatchPoint(i));
  75.     }

  76.     /** {@inheritDoc} */
  77.     protected double[][] computeAdditionalJacobianMatrix(final List<SpacecraftState> propagatedSP) {

  78.         final Map<Integer, Double> mapConstraints = getConstraintsMap();

  79.         // Number of additional constraints
  80.         final int n = mapConstraints.size() + (isClosedOrbit() ? 6 : 0);

  81.         final int ncolumns = getNumberOfFreeVariables() - 1;

  82.         final double[][] M = new double[n][ncolumns];

  83.         int k = 0;
  84.         if (isClosedOrbit()) {
  85.             // The Jacobian matrix has the following form:
  86.             //
  87.             //      [-1  0              0  ...  1  0             ]
  88.             //      [ 0 -1  0           0  ...     1  0          ]
  89.             // C =  [    0 -1  0        0  ...        1  0       ]
  90.             //      [       0 -1  0     0  ...           1  0    ]
  91.             //      [          0  -1 0  0  ...              1  0 ]
  92.             //      [          0  0 -1  0  ...              0  1 ]

  93.             for (int i = 0; i < 6; i++) {
  94.                 M[i][i] = -1;
  95.                 M[i][ncolumns - 6 + i] = 1;
  96.             }
  97.             k = 6;
  98.         }

  99.         for (int index : mapConstraints.keySet()) {
  100.             M[k][index] = 1;
  101.             k++;
  102.         }
  103.         return M;
  104.     }

  105.     /** {@inheritDoc} */
  106.     @Override
  107.     protected double[][] computeEpochJacobianMatrix(final List<SpacecraftState> propagatedSP) {
  108.         final int nFreeEpoch = getNumberOfFreeEpoch();
  109.         // Rows and columns dimensions
  110.         final int ncolumns   = 1 + nFreeEpoch;
  111.         final int nrows      = npoints - 1;
  112.         // Return an empty array
  113.         return new double[nrows][ncolumns];
  114.     }

  115.     /** {@inheritDoc} */
  116.     protected double[] computeAdditionalConstraints(final List<SpacecraftState> propagatedSP) {

  117.         // The additional constraint vector has the following form :

  118.         //           [ xni - x1i ]----
  119.         //           [ yni - x1i ]    |
  120.         // Fadd(X) = [ zni - x1i ] vector's component
  121.         //           [vxni - vx1i] for a closed orbit
  122.         //           [vyni - vy1i]    |
  123.         //           [vzni - vz1i]----
  124.         //           [ y1i - y1d ]---- other constraints (component of
  125.         //           [    ...    ]    | a patch point equals to a
  126.         //           [vz2i - vz2d]----  desired value)

  127.         final Map<Integer, Double> mapConstraints = getConstraintsMap();
  128.         // Number of additional constraints
  129.         final int n = mapConstraints.size() + (isClosedOrbit() ? 6 : 0);

  130.         final List<SpacecraftState> patchedSpacecraftStates = getPatchedSpacecraftState();

  131.         final double[] fxAdditionnal = new double[n];
  132.         int i = 0;

  133.         if (isClosedOrbit()) {

  134.             final AbsolutePVCoordinates apv1i = patchedSpacecraftStates.get(0).getAbsPVA();
  135.             final AbsolutePVCoordinates apvni = patchedSpacecraftStates.get(npoints - 1).getAbsPVA();

  136.             fxAdditionnal[0] = apvni.getPosition().getX() - apv1i.getPosition().getX();
  137.             fxAdditionnal[1] = apvni.getPosition().getY() - apv1i.getPosition().getY();
  138.             fxAdditionnal[2] = apvni.getPosition().getZ() - apv1i.getPosition().getZ();
  139.             fxAdditionnal[3] = apvni.getVelocity().getX() - apv1i.getVelocity().getX();
  140.             fxAdditionnal[4] = apvni.getVelocity().getY() - apv1i.getVelocity().getY();
  141.             fxAdditionnal[5] = apvni.getVelocity().getZ() - apv1i.getVelocity().getZ();

  142.             i = 6;
  143.         }

  144.         // Update additional constraints
  145.         updateAdditionalConstraints(i, fxAdditionnal);
  146.         return fxAdditionnal;
  147.     }

  148. }