1   /* Copyright 2002-2026 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.OrbitParamsType;
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.TimeInterval;
38  import org.orekit.utils.drivers.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, TimeInterval.UNLIMITED);
68      }
69  
70      /** Get the central attraction coefficient μ.
71       * @return mu central attraction coefficient (m³/s²)
72       */
73      public double getMu() {
74          return gmParameterDriver.getValue();
75      }
76  
77      /** {@inheritDoc} */
78      @Override
79      public List<ShortPeriodTerms> initializeShortPeriodTerms(final AuxiliaryElements auxiliaryElements,
80                                               final PropagationType type,
81                                               final double[] parameters) {
82          return Collections.emptyList();
83      }
84  
85      /** {@inheritDoc} */
86      @Override
87      public <T extends CalculusFieldElement<T>> List<FieldShortPeriodTerms<T>>
88          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,
103                                                           final double[] parameters) {
104         return new DSSTNewtonianAttractionContext(auxiliaryElements, parameters);
105     }
106 
107     /** Performs initialization at each integration step for the current force model.
108      *  <p>
109      *  This method aims at being called before mean elements rates computation.
110      *  </p>
111      *  @param <T> type of the elements
112      *  @param auxiliaryElements auxiliary elements related to the current orbit
113      *  @param parameters values of the force model parameters
114      *  @return new force model context
115      */
116     private <T extends CalculusFieldElement<T>> FieldDSSTNewtonianAttractionContext<T>
117         initializeStep(final FieldAuxiliaryElements<T> auxiliaryElements,
118                        final T[] parameters) {
119         return new FieldDSSTNewtonianAttractionContext<>(auxiliaryElements, parameters);
120     }
121 
122     /** {@inheritDoc} */
123     @Override
124     public double[] getMeanElementRate(final SpacecraftState state,
125                                        final AuxiliaryElements auxiliaryElements,
126                                        final double[] parameters) {
127 
128         // Container for attributes
129         final DSSTNewtonianAttractionContext context = initializeStep(auxiliaryElements, parameters);
130 
131         final double[] yDot = new double[7];
132         final EquinoctialOrbit orbit = (EquinoctialOrbit) OrbitParamsType.EQUINOCTIAL.convertType(state.getOrbit());
133         orbit.addKeplerContribution(PositionAngleType.MEAN, context.getGM(), yDot);
134 
135         return yDot;
136 
137     }
138 
139     /** {@inheritDoc} */
140     @Override
141     public <T extends CalculusFieldElement<T>> T[] getMeanElementRate(final FieldSpacecraftState<T> state,
142                                                                       final FieldAuxiliaryElements<T> auxiliaryElements,
143                                                                       final T[] parameters) {
144 
145         // Field for array building
146         final Field<T> field = state.getMass().getField();
147         // Container for attributes
148         final FieldDSSTNewtonianAttractionContext<T> context = initializeStep(auxiliaryElements, parameters);
149 
150         final T[] yDot = MathArrays.buildArray(field, 7);
151         final FieldEquinoctialOrbit<T> orbit = (FieldEquinoctialOrbit<T>) OrbitParamsType.EQUINOCTIAL.convertType(state.getOrbit());
152         orbit.addKeplerContribution(PositionAngleType.MEAN, context.getGM(), yDot);
153 
154         return yDot;
155     }
156 
157     /** {@inheritDoc} */
158     @Override
159     public void registerAttitudeProvider(final AttitudeProvider provider) {
160       //nothing is done since this contribution is not sensitive to attitude
161     }
162 
163     /** {@inheritDoc} */
164     @Override
165     public void updateShortPeriodTerms(final double[] parameters,
166                                        final SpacecraftState... meanStates) {
167     }
168 
169     /** {@inheritDoc} */
170     @Override
171     @SuppressWarnings("unchecked")
172     public <T extends CalculusFieldElement<T>> void updateShortPeriodTerms(final T[] parameters,
173                                                                        final FieldSpacecraftState<T>... meanStates) {
174     }
175 
176     /** {@inheritDoc} */
177     @Override
178     public List<ParameterDriver> getParametersDrivers() {
179         return Collections.singletonList(gmParameterDriver);
180     }
181 
182 }