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