1   /* Copyright 2002-2021 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  
18  package org.orekit.forces.maneuvers.propulsion;
19  
20  import org.hipparchus.CalculusFieldElement;
21  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
22  import org.hipparchus.geometry.euclidean.threed.Vector3D;
23  import org.orekit.propagation.FieldSpacecraftState;
24  import org.orekit.propagation.SpacecraftState;
25  import org.orekit.utils.Constants;
26  
27  /** This abstract class simply serve as a container for a constant thrust maneuver.
28   * It re-writes all spacecraft dependent methods from {@link ThrustPropulsionModel}
29   * and removes their dependencies to current spacecraft state.
30   * Indeed since the thrust is constant (i.e. not variable during the maneuver), most of the
31   * calculated parameters (thrust vector, flow rate etc.) do not depend on current spacecraft state.
32   * @author Maxime Journot
33   * @since 10.2
34   */
35  public abstract class AbstractConstantThrustPropulsionModel implements ThrustPropulsionModel {
36  
37      /** Initial thrust vector (N) in S/C frame, when building the object. */
38      private final Vector3D initialThrustVector;
39  
40      /** Initial flow rate (kg/s), when building the object. */
41      private final double initialFlowRate;
42  
43      /** User-defined name of the maneuver.
44       * This String attribute is empty by default.
45       * It is added as a prefix to the parameter drivers of the maneuver.
46       * The purpose is to differentiate between drivers in the case where several maneuvers
47       * were added to a propagator force model.
48       * Additionally, the user can retrieve the whole maneuver by looping on the force models of a propagator,
49       * scanning for its name.
50       * @since 9.2
51       */
52      private final String name;
53  
54      /** Generic constructor.
55       * @param thrust initial thrust value (N)
56       * @param isp initial isp value (s)
57       * @param direction initial thrust direction in S/C frame
58       * @param name name of the maneuver
59       */
60      public AbstractConstantThrustPropulsionModel(final double thrust,
61                                                   final double isp,
62                                                   final Vector3D direction,
63                                                   final String name) {
64          this.name = name;
65          this.initialThrustVector = direction.normalize().scalarMultiply(thrust);
66          this.initialFlowRate = -thrust / (Constants.G0_STANDARD_GRAVITY * isp);
67      }
68  
69      protected Vector3D getInitialThrustVector() {
70          return initialThrustVector;
71      }
72  
73      protected double getInitialFlowrate() {
74          return initialFlowRate;
75      }
76  
77      /** {@inheritDoc} */
78      @Override
79      public String getName() {
80          return name;
81      }
82  
83      /** Get the specific impulse.
84       * @return specific impulse (s).
85       */
86      public double getIsp() {
87          final double thrust   = getThrust();
88          final double flowRate = getFlowRate();
89          return -thrust / (Constants.G0_STANDARD_GRAVITY * flowRate);
90      }
91  
92      /** Get the thrust direction in S/C frame.
93       * @return the thrust direction in S/C frame
94       */
95      public Vector3D getDirection() {
96          return getThrustVector().normalize();
97      }
98  
99      /** Get the thrust value (N).
100      * @return the thrust value (N)
101      */
102     public double getThrust() {
103         return getThrustVector().getNorm();
104     }
105 
106     /** {@inheritDoc}
107      * Here the thrust vector do not depend on current S/C state.
108      */
109     @Override
110     public Vector3D getThrustVector(final SpacecraftState s) {
111         // Call the abstract function that do not depend on current S/C state
112         return getThrustVector();
113     }
114 
115     /** {@inheritDoc}
116      * Here the flow rate do not depend on current S/C state
117      */
118     @Override
119     public double getFlowRate(final SpacecraftState s) {
120         // Call the abstract function that do not depend on current S/C state
121         return getFlowRate();
122     }
123 
124     /** {@inheritDoc}
125      * Here the thrust vector do not depend on current S/C state.
126      */
127     @Override
128     public Vector3D getThrustVector(final SpacecraftState s, final double[] parameters) {
129         // Call the abstract function that do not depend on current S/C state
130         return getThrustVector(parameters);
131     }
132 
133     /** {@inheritDoc}
134      * Here the flow rate do not depend on current S/C state
135      */
136     public double getFlowRate(final SpacecraftState s, final double[] parameters) {
137         // Call the abstract function that do not depend on current S/C state
138         return getFlowRate(parameters);
139     }
140 
141     /** {@inheritDoc}
142      * Here the thrust vector do not depend on current S/C state.
143      */
144     public <T extends CalculusFieldElement<T>> FieldVector3D<T> getThrustVector(final FieldSpacecraftState<T> s,
145                                                                             final T[] parameters) {
146         // Call the abstract function that do not depend on current S/C state
147         return getThrustVector(parameters);
148     }
149 
150     /** {@inheritDoc}
151      * Here the flow rate do not depend on current S/C state
152      */
153     public <T extends CalculusFieldElement<T>> T getFlowRate(final FieldSpacecraftState<T> s, final T[] parameters) {
154         // Call the abstract function that do not depend on current S/C state
155         return getFlowRate(parameters);
156     }
157 
158     /** Get the thrust vector in spacecraft frame (N).
159      * Here it does not depend on current S/C state.
160      * @return thrust vector in spacecraft frame (N)
161      */
162     public abstract Vector3D getThrustVector();
163 
164     /** Get the flow rate (kg/s).
165      * Here it does not depend on current S/C.
166      * @return flow rate (kg/s)
167      */
168     public abstract double getFlowRate();
169 
170     /** Get the thrust vector in spacecraft frame (N).
171      * Here it does not depend on current S/C state.
172      * @param parameters propulsion model parameters
173      * @return thrust vector in spacecraft frame (N)
174      */
175     public abstract Vector3D getThrustVector(double[] parameters);
176 
177     /** Get the flow rate (kg/s).
178      * Here it does not depend on current S/C state.
179      * @param parameters propulsion model parameters
180      * @return flow rate (kg/s)
181      */
182     public abstract double getFlowRate(double[] parameters);
183 
184     /** Get the thrust vector in spacecraft frame (N).
185      * Here it does not depend on current S/C state.
186      * @param parameters propulsion model parameters
187      * @param <T> extends CalculusFieldElement&lt;T&gt;
188      * @return thrust vector in spacecraft frame (N)
189      */
190     public abstract <T extends CalculusFieldElement<T>> FieldVector3D<T> getThrustVector(T[] parameters);
191 
192     /** Get the flow rate (kg/s).
193      * Here it does not depend on current S/C state.
194      * @param parameters propulsion model parameters
195      * @param <T> extends CalculusFieldElement&lt;T&gt;
196      * @return flow rate (kg/s)
197      */
198     public abstract <T extends CalculusFieldElement<T>> T getFlowRate(T[] parameters);
199 }