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.semianalytical.dsst.forces;
18  
19  import java.util.Collections;
20  import java.util.List;
21  
22  import org.hipparchus.CalculusFieldElement;
23  import org.hipparchus.Field;
24  import org.hipparchus.util.FastMath;
25  import org.hipparchus.util.MathArrays;
26  import org.orekit.attitudes.AttitudeProvider;
27  import org.orekit.orbits.EquinoctialOrbit;
28  import org.orekit.orbits.FieldEquinoctialOrbit;
29  import org.orekit.orbits.OrbitType;
30  import org.orekit.orbits.PositionAngleType;
31  import org.orekit.propagation.FieldSpacecraftState;
32  import org.orekit.propagation.PropagationType;
33  import org.orekit.propagation.SpacecraftState;
34  import org.orekit.propagation.semianalytical.dsst.DSSTPropagator;
35  import org.orekit.propagation.semianalytical.dsst.utilities.AuxiliaryElements;
36  import org.orekit.propagation.semianalytical.dsst.utilities.FieldAuxiliaryElements;
37  import org.orekit.time.AbsoluteDate;
38  import org.orekit.utils.ParameterDriver;
39  
40  /** Force model for Newtonian central body attraction for the {@link DSSTPropagator DSST propagator}.
41   *  @author Bryan Cazabonne
42   *  @author Luc Maisonobe
43   *  @since 10.0
44   */
45  public class DSSTNewtonianAttraction implements DSSTForceModel {
46  
47      /** Name of the single parameter of this model: the central attraction coefficient. */
48      public static final String CENTRAL_ATTRACTION_COEFFICIENT = "central attraction coefficient";
49  
50      /** Central attraction scaling factor.
51       * <p>
52       * We use a power of 2 to avoid numeric noise introduction
53       * in the multiplications/divisions sequences.
54       * </p>
55       */
56      private static final double MU_SCALE = FastMath.scalb(1.0, 32);
57  
58      /** Driver for gravitational parameter. */
59      private final ParameterDriver gmParameterDriver;
60  
61      /** Simple constructor.
62       * @param mu central attraction coefficient (m^3/s^2)
63       */
64      public DSSTNewtonianAttraction(final double mu) {
65          gmParameterDriver = new ParameterDriver(DSSTNewtonianAttraction.CENTRAL_ATTRACTION_COEFFICIENT,
66                                                  mu, MU_SCALE,
67                                                  0.0, Double.POSITIVE_INFINITY);
68      }
69  
70      /** Get the central attraction coefficient μ at specific date.
71       * @param date date at which mu wants to be known
72       * @return mu central attraction coefficient (m³/s²)
73       */
74      public double getMu(final AbsoluteDate date) {
75          return gmParameterDriver.getValue(date);
76      }
77  
78      /** {@inheritDoc} */
79      @Override
80      public List<ShortPeriodTerms> initializeShortPeriodTerms(final AuxiliaryElements auxiliaryElements,
81                                               final PropagationType type,
82                                               final double[] parameters) {
83          return Collections.emptyList();
84      }
85  
86      /** {@inheritDoc} */
87      @Override
88      public <T extends CalculusFieldElement<T>> List<FieldShortPeriodTerms<T>> initializeShortPeriodTerms(final FieldAuxiliaryElements<T> auxiliaryElements,
89                                                                                       final PropagationType type,
90                                                                                       final T[] parameters) {
91          return Collections.emptyList();
92      }
93  
94      /** Performs initialization at each integration step for the current force model.
95       *  <p>
96       *  This method aims at being called before mean elements rates computation.
97       *  </p>
98       *  @param auxiliaryElements auxiliary elements related to the current orbit
99       *  @param parameters values of the force model parameters
100      *  @return new force model context
101      */
102     private DSSTNewtonianAttractionContext initializeStep(final AuxiliaryElements auxiliaryElements, final double[] parameters) {
103         return new DSSTNewtonianAttractionContext(auxiliaryElements, parameters);
104     }
105 
106     /** Performs initialization at each integration step for the current force model.
107      *  <p>
108      *  This method aims at being called before mean elements rates computation.
109      *  </p>
110      *  @param <T> type of the elements
111      *  @param auxiliaryElements auxiliary elements related to the current orbit
112      *  @param parameters values of the force model parameters
113      *  @return new force model context
114      */
115     private <T extends CalculusFieldElement<T>> FieldDSSTNewtonianAttractionContext<T> initializeStep(final FieldAuxiliaryElements<T> auxiliaryElements,
116                                                                                                   final T[] parameters) {
117         return new FieldDSSTNewtonianAttractionContext<>(auxiliaryElements, parameters);
118     }
119 
120     /** {@inheritDoc} */
121     @Override
122     public double[] getMeanElementRate(final SpacecraftState state,
123                                        final AuxiliaryElements auxiliaryElements,
124                                        final double[] parameters) {
125 
126         // Container for attributes
127         final DSSTNewtonianAttractionContext context = initializeStep(auxiliaryElements, parameters);
128 
129         final double[] yDot = new double[7];
130         final EquinoctialOrbit orbit = (EquinoctialOrbit) OrbitType.EQUINOCTIAL.convertType(state.getOrbit());
131         orbit.addKeplerContribution(PositionAngleType.MEAN, context.getGM(), yDot);
132 
133         return yDot;
134 
135     }
136 
137     /** {@inheritDoc} */
138     @Override
139     public <T extends CalculusFieldElement<T>> T[] getMeanElementRate(final FieldSpacecraftState<T> state,
140                                                                   final FieldAuxiliaryElements<T> auxiliaryElements,
141                                                                   final T[] parameters) {
142 
143         // Field for array building
144         final Field<T> field = state.getMass().getField();
145         // Container for attributes
146         final FieldDSSTNewtonianAttractionContext<T> context = initializeStep(auxiliaryElements, parameters);
147 
148         final T[] yDot = MathArrays.buildArray(field, 7);
149         final FieldEquinoctialOrbit<T> orbit = (FieldEquinoctialOrbit<T>) OrbitType.EQUINOCTIAL.convertType(state.getOrbit());
150         orbit.addKeplerContribution(PositionAngleType.MEAN, context.getGM(), yDot);
151 
152         return yDot;
153     }
154 
155     /** {@inheritDoc} */
156     @Override
157     public void registerAttitudeProvider(final AttitudeProvider provider) {
158       //nothing is done since this contribution is not sensitive to attitude
159     }
160 
161     /** {@inheritDoc} */
162     @Override
163     public void updateShortPeriodTerms(final double[] parameters,
164                                        final SpacecraftState... meanStates) {
165     }
166 
167     /** {@inheritDoc} */
168     @Override
169     @SuppressWarnings("unchecked")
170     public <T extends CalculusFieldElement<T>> void updateShortPeriodTerms(final T[] parameters,
171                                                                        final FieldSpacecraftState<T>... meanStates) {
172     }
173 
174     /** {@inheritDoc} */
175     @Override
176     public List<ParameterDriver> getParametersDrivers() {
177         return Collections.singletonList(gmParameterDriver);
178     }
179 
180 }