1   /* Copyright 2010-2011 Centre National d'Études Spatiales
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.forces.gravity;
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.geometry.euclidean.threed.FieldVector3D;
25  import org.hipparchus.geometry.euclidean.threed.Vector3D;
26  import org.hipparchus.util.FastMath;
27  import org.orekit.forces.ForceModel;
28  import org.orekit.propagation.FieldSpacecraftState;
29  import org.orekit.propagation.SpacecraftState;
30  import org.orekit.propagation.numerical.FieldTimeDerivativesEquations;
31  import org.orekit.propagation.numerical.TimeDerivativesEquations;
32  import org.orekit.time.TimeInterval;
33  import org.orekit.utils.drivers.ParameterDriver;
34  
35  /** Force model for Newtonian central body attraction.
36   * @author Luc Maisonobe
37   */
38  public class NewtonianAttraction implements ForceModel {
39  
40      /** Name of the single parameter of this model: the central attraction coefficient. */
41      public static final String CENTRAL_ATTRACTION_COEFFICIENT = "central attraction coefficient";
42  
43      /** Central attraction scaling factor.
44       * <p>
45       * We use a power of 2 to avoid numeric noise introduction
46       * in the multiplications/divisions sequences.
47       * </p>
48       */
49      private static final double MU_SCALE = FastMath.scalb(1.0, 32);
50  
51      /** Driver for gravitational parameter. */
52      private final ParameterDriver gmParameterDriver;
53  
54     /** Simple constructor.
55       * @param mu central attraction coefficient (m^3/s^2)
56       */
57      public NewtonianAttraction(final double mu) {
58          gmParameterDriver = new ParameterDriver(NewtonianAttraction.CENTRAL_ATTRACTION_COEFFICIENT,
59                                                  mu, MU_SCALE,
60                                                  0.0, Double.POSITIVE_INFINITY, TimeInterval.UNLIMITED);
61      }
62  
63      /** {@inheritDoc} */
64      @Override
65      public boolean dependsOnPositionOnly() {
66          return true;
67      }
68  
69      /** Get the central attraction coefficient μ.
70       * @return mu central attraction coefficient (m³/s²)
71       */
72      public double getMu() {
73          return gmParameterDriver.getValue();
74      }
75  
76      /** Get the central attraction coefficient μ.
77       * @param <T> the type of the field element
78       * @param field field to which the state belongs
79       * @return mu central attraction coefficient (m³/s²)
80       */
81      public <T extends CalculusFieldElement<T>> T getMu(final Field<T> field) {
82          final T zero = field.getZero();
83          return zero.newInstance(gmParameterDriver.getValue());
84      }
85  
86      /** {@inheritDoc} */
87      @Override
88      public void addContribution(final SpacecraftState s, final TimeDerivativesEquations adder) {
89          adder.addKeplerContribution(getMu());
90      }
91  
92      /** {@inheritDoc} */
93      @Override
94      public <T extends CalculusFieldElement<T>> void addContribution(final FieldSpacecraftState<T> s,
95                                                                      final FieldTimeDerivativesEquations<T> adder) {
96          final Field<T> field = s.getDate().getField();
97          adder.addKeplerContribution(getMu(field));
98      }
99  
100     /** {@inheritDoc} */
101     @Override
102     public Vector3D acceleration(final SpacecraftState s, final double[] parameters) {
103         final double mu = parameters[0];
104         final double r2 = s.getPosition().getNorm2Sq();
105         return new Vector3D(-mu / (FastMath.sqrt(r2) * r2), s.getPosition());
106     }
107 
108     /** {@inheritDoc} */
109     @Override
110     public <T extends CalculusFieldElement<T>> FieldVector3D<T> acceleration(final FieldSpacecraftState<T> s,
111                                                                          final T[] parameters) {
112         final T mu = parameters[0];
113         final T r2 = s.getPosition().getNorm2Sq();
114         return new FieldVector3D<>(r2.sqrt().multiply(r2).reciprocal().multiply(mu).negate(), s.getPosition());
115     }
116 
117     /** {@inheritDoc} */
118     @Override
119     public List<ParameterDriver> getParametersDrivers() {
120         return Collections.singletonList(gmParameterDriver);
121     }
122 
123 }
124