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