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 org.orekit.propagation.SpacecraftState;
20  import org.orekit.propagation.integration.AdditionalDerivativesProvider;
21  
22  /** Generator for one column of a Jacobian matrix.
23   * <p>
24   * This generator is based on variational equations, so
25   * it implements {@link AdditionalDerivativesProvider} and
26   * computes only the derivative of the Jacobian column, to
27   * be integrated by the propagator alongside the primary state.
28   * </p>
29   * @author Luc Maisonobe
30   * @since 11.1
31   */
32  class IntegrableJacobianColumnGenerator
33      implements AdditionalDerivativesProvider, StateTransitionMatrixGenerator.PartialsObserver {
34  
35      /** Name of the state for State Transition Matrix. */
36      private final String stmName;
37  
38      /** Name of the parameter corresponding to the column. */
39      private final String columnName;
40  
41      /** Last value computed for the partial derivatives. */
42      private final double[] pDot;
43  
44      /** Simple constructor.
45       * <p>
46       * The generator for State Transition Matrix <em>must</em> be registered as
47       * an integrable generator to the same propagator as the instance, as it
48       * must be scheduled to update the state before the instance
49       * </p>
50       * @param stmGenerator generator for State Transition Matrix
51       * @param columnName name of the parameter corresponding to the column
52       */
53      IntegrableJacobianColumnGenerator(final StateTransitionMatrixGenerator stmGenerator, final String columnName) {
54          this.stmName    = stmGenerator.getName();
55          this.columnName = columnName;
56          this.pDot       = new double[getDimension()];
57          stmGenerator.addObserver(columnName, this);
58      }
59  
60      /** {@inheritDoc} */
61      @Override
62      public String getName() {
63          return columnName;
64      }
65  
66      /** Get the dimension of the generated column.
67       * @return dimension of the generated column
68       */
69      public int getDimension() {
70          return 6;
71      }
72  
73      /** {@inheritDoc}
74       * <p>
75       * The column derivative can be computed only if the State Transition Matrix derivatives
76       * are available, as it implies the STM generator has already been run.
77       * </p>
78       */
79      @Override
80      public boolean yield(final SpacecraftState state) {
81          return !state.hasAdditionalStateDerivative(stmName);
82      }
83  
84      /** {@inheritDoc} */
85      @Override
86      public void partialsComputed(final SpacecraftState state, final double[] factor, final double[] accelerationPartials) {
87          // retrieve current Jacobian column
88          final double[] p = state.getAdditionalState(getName());
89  
90          // compute time derivative of the Jacobian column
91          StateTransitionMatrixGenerator.multiplyMatrix(factor, p, pDot, 1);
92          pDot[3] += accelerationPartials[0];
93          pDot[4] += accelerationPartials[1];
94          pDot[5] += accelerationPartials[2];
95      }
96  
97      /** {@inheritDoc} */
98      @Override
99      public double[] derivatives(final SpacecraftState s) {
100         return pDot;
101     }
102 
103 }
104