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.hipparchus.Field;
20  import org.hipparchus.analysis.differentiation.Gradient;
21  import org.hipparchus.analysis.differentiation.GradientField;
22  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
23  import org.hipparchus.geometry.euclidean.threed.Vector3D;
24  import org.orekit.attitudes.AttitudeProvider;
25  import org.orekit.attitudes.FieldAttitude;
26  import org.orekit.orbits.FieldCartesianOrbit;
27  import org.orekit.orbits.FieldOrbit;
28  import org.orekit.propagation.FieldSpacecraftState;
29  import org.orekit.propagation.SpacecraftState;
30  import org.orekit.propagation.integration.AbstractGradientConverter;
31  import org.orekit.utils.TimeStampedFieldPVCoordinates;
32  
33  /** Converter for states and parameters arrays.
34   * @author Luc Maisonobe
35   * @since 10.2
36   */
37  class NumericalGradientConverter extends AbstractGradientConverter {
38  
39      /** Simple constructor.
40       * @param state regular state
41       * @param freeStateParameters number of free parameters, either 3 (position) or 6 (position-velocity)
42       * @param provider provider to use if attitude needs to be recomputed
43       */
44      NumericalGradientConverter(final SpacecraftState state, final int freeStateParameters,
45                                 final AttitudeProvider provider) {
46  
47          super(freeStateParameters);
48  
49          // Derivative field
50          final Field<Gradient> field =  GradientField.getField(freeStateParameters);
51  
52          // position always has derivatives
53          final Vector3D pos = state.getPVCoordinates().getPosition();
54          final FieldVector3D<Gradient> posG = new FieldVector3D<>(Gradient.variable(freeStateParameters, 0, pos.getX()),
55                                                                   Gradient.variable(freeStateParameters, 1, pos.getY()),
56                                                                   Gradient.variable(freeStateParameters, 2, pos.getZ()));
57  
58          // velocity may have derivatives or not
59          final Vector3D vel = state.getPVCoordinates().getVelocity();
60          final FieldVector3D<Gradient> velG;
61          if (freeStateParameters > 3) {
62              velG = new FieldVector3D<>(Gradient.variable(freeStateParameters, 3, vel.getX()),
63                                         Gradient.variable(freeStateParameters, 4, vel.getY()),
64                                         Gradient.variable(freeStateParameters, 5, vel.getZ()));
65          } else {
66              velG = new FieldVector3D<>(Gradient.constant(freeStateParameters, vel.getX()),
67                                         Gradient.constant(freeStateParameters, vel.getY()),
68                                         Gradient.constant(freeStateParameters, vel.getZ()));
69          }
70  
71          // acceleration never has derivatives
72          final Vector3D acc = state.getPVCoordinates().getAcceleration();
73          final FieldVector3D<Gradient> accG = new FieldVector3D<>(Gradient.constant(freeStateParameters, acc.getX()),
74                                                                   Gradient.constant(freeStateParameters, acc.getY()),
75                                                                   Gradient.constant(freeStateParameters, acc.getZ()));
76  
77          // mass never has derivatives
78          final Gradient gM = Gradient.constant(freeStateParameters, state.getMass());
79  
80          final Gradient gMu = Gradient.constant(freeStateParameters, state.getMu());
81  
82          final FieldOrbit<Gradient> gOrbit =
83                          new FieldCartesianOrbit<>(new TimeStampedFieldPVCoordinates<>(state.getDate(), posG, velG, accG),
84                                                    state.getFrame(), gMu);
85  
86          final FieldAttitude<Gradient> gAttitude;
87          if (freeStateParameters > 3) {
88              // compute attitude partial derivatives with respect to position/velocity
89              gAttitude = provider.getAttitude(gOrbit, gOrbit.getDate(), gOrbit.getFrame());
90          } else {
91              // force model does not depend on attitude, don't bother recomputing it
92              gAttitude = new FieldAttitude<>(field, state.getAttitude());
93          }
94  
95          // initialize the list with the state having 0 force model parameters
96          initStates(new FieldSpacecraftState<>(gOrbit, gAttitude, gM));
97  
98      }
99  
100 }