1   /* Copyright 2002-2024 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.forces.drag;
18  
19  import java.util.List;
20  
21  import org.hipparchus.CalculusFieldElement;
22  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
23  import org.hipparchus.geometry.euclidean.threed.Vector3D;
24  import org.orekit.frames.Frame;
25  import org.orekit.models.earth.atmosphere.Atmosphere;
26  import org.orekit.propagation.FieldSpacecraftState;
27  import org.orekit.propagation.SpacecraftState;
28  import org.orekit.time.AbsoluteDate;
29  import org.orekit.time.FieldAbsoluteDate;
30  import org.orekit.utils.ParameterDriver;
31  
32  
33  /** Atmospheric drag force model.
34   *
35   * The drag acceleration is computed as follows :
36   *
37   * γ = (1/2 * ρ * V² * S / Mass) * DragCoefVector
38   *
39   * With DragCoefVector = {C<sub>x</sub>, C<sub>y</sub>, C<sub>z</sub>} and S given by the user through the interface
40   * {@link DragSensitive}
41   *
42   * @author &Eacute;douard Delente
43   * @author Fabien Maussion
44   * @author V&eacute;ronique Pommier-Maurussane
45   * @author Pascal Parraud
46   * @author Melina Vanel
47   */
48  
49  public class DragForce extends AbstractDragForceModel {
50  
51      /** Spacecraft. */
52      private final DragSensitive spacecraft;
53  
54      /** Constructor with default flag for finite differences.
55       * @param atmosphere atmospheric model
56       * @param spacecraft the object physical and geometrical information
57       */
58      public DragForce(final Atmosphere atmosphere, final DragSensitive spacecraft) {
59          super(atmosphere);
60          this.spacecraft = spacecraft;
61      }
62  
63      /** Simple constructor.
64       * @param atmosphere atmospheric model
65       * @param spacecraft the object physical and geometrical information
66       * @param useFiniteDifferencesOnDensityWrtPosition flag to use finite differences to compute density derivatives w.r.t.
67       *                                                 position (is less accurate but can be faster depending on model)
68       * @since 12.1
69       */
70      public DragForce(final Atmosphere atmosphere, final DragSensitive spacecraft,
71                       final boolean useFiniteDifferencesOnDensityWrtPosition) {
72          super(atmosphere, useFiniteDifferencesOnDensityWrtPosition);
73          this.spacecraft = spacecraft;
74      }
75  
76      /** {@inheritDoc} */
77      @Override
78      public boolean dependsOnAttitudeRate() {
79          return getSpacecraft().dependsOnAttitudeRate();
80      }
81  
82      /** {@inheritDoc} */
83      @Override
84      public Vector3D acceleration(final SpacecraftState s, final double[] parameters) {
85  
86          final AbsoluteDate date     = s.getDate();
87          final Frame        frame    = s.getFrame();
88          final Vector3D     position = s.getPosition();
89  
90          final double rho    = getAtmosphere().getDensity(date, position, frame);
91          final Vector3D vAtm = getAtmosphere().getVelocity(date, position, frame);
92          final Vector3D relativeVelocity = vAtm.subtract(s.getPVCoordinates().getVelocity());
93  
94          return spacecraft.dragAcceleration(s, rho, relativeVelocity, parameters);
95  
96      }
97  
98      /** {@inheritDoc} */
99      @Override
100     public <T extends CalculusFieldElement<T>> FieldVector3D<T> acceleration(final FieldSpacecraftState<T> s,
101                                                                              final T[] parameters) {
102         // Density and its derivatives
103         final T rho = getFieldDensity(s);
104 
105         // Spacecraft relative velocity with respect to the atmosphere
106         final FieldAbsoluteDate<T> date     = s.getDate();
107         final Frame                frame    = s.getFrame();
108         final FieldVector3D<T>     position = s.getPosition();
109         final FieldVector3D<T> vAtm = getAtmosphere().getVelocity(date, position, frame);
110         final FieldVector3D<T> relativeVelocity = vAtm.subtract(s.getPVCoordinates().getVelocity());
111 
112         // Drag acceleration along with its derivatives
113         return spacecraft.dragAcceleration(s, rho, relativeVelocity, parameters);
114 
115     }
116 
117     /** {@inheritDoc} */
118     @Override
119     public List<ParameterDriver> getParametersDrivers() {
120         return spacecraft.getDragParametersDrivers();
121     }
122 
123     /** Get spacecraft that are sensitive to atmospheric drag forces.
124      * @return drag sensitive spacecraft model
125      */
126     public DragSensitive getSpacecraft() {
127         return spacecraft;
128     }
129 
130 }