1   /* Copyright 2002-2022 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.maneuvers.propulsion;
18  
19  import java.util.List;
20  
21  import org.hipparchus.CalculusFieldElement;
22  import org.hipparchus.analysis.differentiation.DSFactory;
23  import org.hipparchus.analysis.differentiation.DerivativeStructure;
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.junit.Assert;
28  import org.junit.Test;
29  import org.orekit.frames.FramesFactory;
30  import org.orekit.orbits.CircularOrbit;
31  import org.orekit.orbits.Orbit;
32  import org.orekit.propagation.FieldSpacecraftState;
33  import org.orekit.propagation.SpacecraftState;
34  import org.orekit.time.AbsoluteDate;
35  import org.orekit.utils.Constants;
36  import org.orekit.utils.PVCoordinates;
37  import org.orekit.utils.ParameterDriver;
38  
39  /** Test for AbstractConstantThrust class and its sub-classes. */
40  public class AbstractConstantThrustTest {
41  
42      /** Test non-abstract methods of constant thrust model. */
43      @Test
44      public void testNonAbstractMethods() {
45          
46          final double thrust = 1.;
47          final double isp = 300.;
48          final Vector3D direction = Vector3D.PLUS_I;
49          final String name = "man";
50          
51          final Vector3D thrustVector = direction.scalarMultiply(thrust);
52          final double flowRate = -thrust / (Constants.G0_STANDARD_GRAVITY * isp);
53          
54          // A simple model without any parameter driver
55          final AbstractConstantThrustPropulsionModel model =
56                          new AbstractConstantThrustPropulsionModel(thrust, isp, direction, name) {
57              
58              @Override
59              public <T extends CalculusFieldElement<T>> FieldVector3D<T> getThrustVector(T[] parameters) {
60                  return new FieldVector3D<T>(parameters[0].getField(), thrustVector);
61              }
62              
63              @Override
64              public Vector3D getThrustVector(double[] parameters) {
65                  return thrustVector;
66              }
67              
68              @Override
69              public Vector3D getThrustVector() {
70                  return thrustVector;
71              }
72              
73              @Override
74              public <T extends CalculusFieldElement<T>> T getFlowRate(T[] parameters) {
75                  return parameters[0].getField().getZero().add(flowRate);
76              }
77              
78              @Override
79              public double getFlowRate(double[] parameters) {
80                  return flowRate;
81              }
82              
83              @Override
84              public double getFlowRate() {
85                  return flowRate;
86              }
87          };
88          
89          // Test non-abstract methods
90          Assert.assertEquals(0, model.getParametersDrivers().size());
91          Assert.assertEquals(name, model.getName());
92          Assert.assertEquals(isp , model.getIsp(), 0.);
93          Assert.assertArrayEquals(direction.toArray(), model.getDirection().toArray(), 0.);
94          Assert.assertEquals(thrust, model.getThrust(), 0.);
95          
96          // Dummy spacecraft state        
97          Orbit orbit =  new CircularOrbit(new PVCoordinates(Vector3D.PLUS_I, Vector3D.PLUS_J),
98                                           FramesFactory.getEME2000(), AbsoluteDate.J2000_EPOCH, Constants.EIGEN5C_EARTH_MU);
99          SpacecraftState s = new SpacecraftState(orbit);
100 
101         Assert.assertArrayEquals(thrustVector.toArray(), model.getThrustVector(s).toArray(), 0.);
102         Assert.assertArrayEquals(thrustVector.toArray(), model.getThrustVector(s, new double[] {1.}).toArray(), 0.);
103         Assert.assertEquals(flowRate, model.getFlowRate(s), 0.);
104         Assert.assertEquals(flowRate, model.getFlowRate(s, new double[] {0.}), 0.);
105         
106         // Dummy DS factory
107         DSFactory factory = new DSFactory(1, 1);
108         DerivativeStructure ds = factory.build(1., 1.);
109         DerivativeStructure[] dsArray = new DerivativeStructure[] {ds};
110         FieldSpacecraftState<DerivativeStructure> fs = new FieldSpacecraftState<>(ds.getField(), s);
111         
112         // Thrust DS        
113         Assert.assertEquals(thrustVector.getX(), model.getThrustVector(fs, dsArray).getX().getReal(), 0.);
114         Assert.assertEquals(0., model.getThrustVector(fs, dsArray).getX().getPartialDerivative(1), 0.);
115         Assert.assertEquals(thrustVector.getY(), model.getThrustVector(fs, dsArray).getY().getReal(), 0.);
116         Assert.assertEquals(0., model.getThrustVector(fs, dsArray).getY().getPartialDerivative(1), 0.);
117         Assert.assertEquals(thrustVector.getZ(), model.getThrustVector(fs, dsArray).getZ().getReal(), 0.);
118         Assert.assertEquals(0., model.getThrustVector(fs, dsArray).getZ().getPartialDerivative(1), 0.);
119         
120         // Flow rate DS      
121         Assert.assertEquals(flowRate, model.getFlowRate(fs, dsArray).getReal(), 0.);
122         Assert.assertEquals(0., model.getFlowRate(fs, dsArray).getPartialDerivative(1), 0.);
123     }
124     
125     /** Test the 1-dimensional constant thrust model. */
126     @Test
127     public void testConstantThrust1D() {
128         
129         final double thrust = 1.;
130         final double isp = 300.;
131         final Vector3D direction = new Vector3D(FastMath.PI / 3., FastMath.PI / 4);
132         final String name = "man-1";
133         
134         // 1D constant thrust model
135         final BasicConstantThrustPropulsionModel model =
136                         new BasicConstantThrustPropulsionModel(thrust, isp, direction, name);
137         List<ParameterDriver> drivers = model.getParametersDrivers();
138         
139         // References
140         final Vector3D refThrustVector = direction.scalarMultiply(thrust);
141         final double refFlowRate = -thrust / (Constants.G0_STANDARD_GRAVITY * isp);
142         
143         
144         // Thrust & flow rate
145         final double mult = 10.;
146         Assert.assertArrayEquals(direction.toArray(), model.getDirection().toArray(), 0.);
147         Assert.assertArrayEquals(refThrustVector.toArray(), model.getThrustVector().toArray(), 0.);
148         Assert.assertArrayEquals(refThrustVector.scalarMultiply(mult).toArray(),
149                                  model.getThrustVector(new double[] {mult * thrust, mult * refFlowRate}).toArray(), 0.);
150         Assert.assertEquals(refFlowRate, model.getFlowRate(), 0.);
151         Assert.assertEquals(mult * refFlowRate, model.getFlowRate(new double[] {mult * thrust, mult * refFlowRate}), 0.);
152         
153         // Drivers
154         Assert.assertEquals(2, drivers.size());
155         Assert.assertEquals(name + BasicConstantThrustPropulsionModel.THRUST, drivers.get(0).getName());
156         Assert.assertEquals(name + BasicConstantThrustPropulsionModel.FLOW_RATE, drivers.get(1).getName());
157         Assert.assertEquals(thrust, drivers.get(0).getValue(), 0.);
158         Assert.assertEquals(refFlowRate, drivers.get(1).getValue(), 0.);
159         
160         // Thrust DS
161         final DSFactory factory = new DSFactory(2, 1);
162         DerivativeStructure t = factory.build(mult * thrust, 1., 0.);
163         DerivativeStructure f = factory.build(mult * refFlowRate, 0., 1.);
164         
165         DerivativeStructure[] dsArray = new DerivativeStructure[] {t, f};
166 
167         Assert.assertEquals(t.getReal() * direction.getX(), model.getThrustVector(dsArray).getX().getReal(), 0.);
168         Assert.assertEquals(direction.getX(), model.getThrustVector(dsArray).getX().getPartialDerivative(1, 0), 0.);
169         Assert.assertEquals(0., model.getThrustVector(dsArray).getX().getPartialDerivative(0, 1), 0.);
170         
171         Assert.assertEquals(t.getReal() * direction.getY(), model.getThrustVector(dsArray).getY().getReal(), 0.);
172         Assert.assertEquals(direction.getY(), model.getThrustVector(dsArray).getY().getPartialDerivative(1, 0), 0.);
173         Assert.assertEquals(0., model.getThrustVector(dsArray).getY().getPartialDerivative(0, 1), 0.);
174         
175         Assert.assertEquals(t.getReal() * direction.getZ(), model.getThrustVector(dsArray).getZ().getReal(), 0.);
176         Assert.assertEquals(direction.getZ(), model.getThrustVector(dsArray).getZ().getPartialDerivative(1, 0), 0.);
177         Assert.assertEquals(0., model.getThrustVector(dsArray).getZ().getPartialDerivative(0, 1), 0.);
178         
179         // Flow rate DS      
180         Assert.assertEquals(f.getReal(), model.getFlowRate(dsArray).getReal(), 0.);
181         Assert.assertEquals(0., model.getFlowRate(dsArray).getPartialDerivative(1, 0), 0.);
182         Assert.assertEquals(1., model.getFlowRate(dsArray).getPartialDerivative(0, 1), 0.);
183     }  
184     
185   /** Test the 3-dimensional "scaled" constant thrust model. */
186   @Test
187   public void testConstantThrust3DScaled() {
188       
189       final double thrust = 1.;
190       final double isp = 300.;
191       final Vector3D direction = new Vector3D(FastMath.PI / 3., FastMath.PI / 4);
192       final String name = "man-1";
193       
194       // 3D "scaled" constant thrust model
195       final ScaledConstantThrustPropulsionModel mod1 =
196                       new ScaledConstantThrustPropulsionModel(thrust, isp, direction, name);
197       List<ParameterDriver> drivers = mod1.getParametersDrivers();
198       
199       // References
200       final Vector3D refThrustVector = direction.scalarMultiply(thrust);
201       final double refFlowRate = -thrust / (Constants.G0_STANDARD_GRAVITY * isp);
202       
203       
204       // Thrust & flow rate
205       Assert.assertArrayEquals(direction.toArray(), mod1.getDirection().toArray(), 0.);
206       Assert.assertArrayEquals(refThrustVector.toArray(), mod1.getThrustVector().toArray(), 0.);
207       Assert.assertArrayEquals(refThrustVector.toArray(), mod1.getThrustVector(new double[] {1., 1., 1.}).toArray(), 0.);
208       Assert.assertEquals(refFlowRate, mod1.getFlowRate(), 0.);
209       Assert.assertEquals(refFlowRate, mod1.getFlowRate(new double[] {0.}), 0.);
210       
211       // Drivers
212       Assert.assertEquals(3, drivers.size());
213       Assert.assertEquals(name + ScaledConstantThrustPropulsionModel.THRUSTX_SCALE_FACTOR, drivers.get(0).getName());
214       Assert.assertEquals(name + ScaledConstantThrustPropulsionModel.THRUSTY_SCALE_FACTOR, drivers.get(1).getName());
215       Assert.assertEquals(name + ScaledConstantThrustPropulsionModel.THRUSTZ_SCALE_FACTOR, drivers.get(2).getName());
216       Assert.assertEquals(1., drivers.get(0).getValue(), 0.);
217       Assert.assertEquals(1., drivers.get(1).getValue(), 0.);
218       Assert.assertEquals(1., drivers.get(2).getValue(), 0.);
219       
220       // Thrust DS
221       final DSFactory factory = new DSFactory(3, 1);
222       DerivativeStructure fx = factory.build(1., 1., 0., 0.);
223       DerivativeStructure fy = factory.build(0.5, 0., 1., 0.);
224       DerivativeStructure fz = factory.build(1.5, 0., 0., 1.);
225       
226       DerivativeStructure[] fArray = new DerivativeStructure[] {fx, fy, fz};
227 
228       Assert.assertEquals(fx.getReal() * refThrustVector.getX(), mod1.getThrustVector(fArray).getX().getReal(), 0.);
229       Assert.assertEquals(refThrustVector.getX(), mod1.getThrustVector(fArray).getX().getPartialDerivative(1, 0, 0), 0.);
230       Assert.assertEquals(0., mod1.getThrustVector(fArray).getX().getPartialDerivative(0, 1, 0), 0.);
231       Assert.assertEquals(0., mod1.getThrustVector(fArray).getX().getPartialDerivative(0, 0, 1), 0.);
232       
233       Assert.assertEquals(fy.getReal() * refThrustVector.getY(), mod1.getThrustVector(fArray).getY().getReal(), 0.);
234       Assert.assertEquals(0., mod1.getThrustVector(fArray).getY().getPartialDerivative(1, 0, 0), 0.);
235       Assert.assertEquals(refThrustVector.getY(), mod1.getThrustVector(fArray).getY().getPartialDerivative(0, 1, 0), 0.);
236       Assert.assertEquals(0., mod1.getThrustVector(fArray).getY().getPartialDerivative(0, 0, 1), 0.);
237       
238       Assert.assertEquals(fz.getReal() * refThrustVector.getZ(), mod1.getThrustVector(fArray).getZ().getReal(), 0.);
239       Assert.assertEquals(0., mod1.getThrustVector(fArray).getZ().getPartialDerivative(1, 0, 0), 0.);
240       Assert.assertEquals(0., mod1.getThrustVector(fArray).getZ().getPartialDerivative(0, 1, 0), 0.);
241       Assert.assertEquals(refThrustVector.getZ(), mod1.getThrustVector(fArray).getZ().getPartialDerivative(0, 0, 1), 0.);
242       
243       // Flow rate DS      
244       Assert.assertEquals(refFlowRate, mod1.getFlowRate(fArray).getReal(), 0.);
245       Assert.assertEquals(0., mod1.getFlowRate(fArray).getPartialDerivative(1, 0, 0), 0.);
246       Assert.assertEquals(0., mod1.getFlowRate(fArray).getPartialDerivative(0, 1, 0), 0.);
247       Assert.assertEquals(0., mod1.getFlowRate(fArray).getPartialDerivative(0, 1, 0), 0.);
248   }
249 }