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.empirical;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.List;
22
23 import org.hipparchus.CalculusFieldElement;
24 import org.hipparchus.util.FastMath;
25 import org.orekit.propagation.FieldSpacecraftState;
26 import org.orekit.propagation.SpacecraftState;
27 import org.orekit.time.AbsoluteDate;
28 import org.orekit.utils.ParameterDriver;
29
30 /** Polynomial acceleration model.
31 * @since 10.3
32 * @author Luc Maisonobe
33 * @author Bryan Cazabonne
34 */
35 public class PolynomialAccelerationModel implements AccelerationModel {
36
37 /** Acceleration scaling factor.
38 * <p>
39 * 2⁻²⁰ is the order of magnitude of third body perturbing acceleration.
40 * </p>
41 * <p>
42 * We use a power of 2 to avoid numeric noise introduction
43 * in the multiplications/divisions sequences.
44 * </p>
45 */
46 private static final double ACCELERATION_SCALE = FastMath.scalb(1.0, -20);
47
48 /** Drivers for the polynomial coefficients. */
49 private final List<ParameterDriver> drivers;
50
51 /** Reference date for computing polynomials. */
52 private AbsoluteDate referenceDate;
53
54 /** Simple constructor.
55 * @param prefix prefix to use for parameter drivers
56 * @param referenceDate reference date for computing polynomials, if null
57 * the reference date will be automatically set at propagation start
58 * @param degree polynomial degree (i.e. a value of 0 corresponds to a constant acceleration)
59 */
60 public PolynomialAccelerationModel(final String prefix,
61 final AbsoluteDate referenceDate,
62 final int degree) {
63 // Reference date
64 this.referenceDate = referenceDate;
65 // Parameter drivers
66 drivers = new ArrayList<>();
67 for (int i = 0; i < degree + 1; ++i) {
68 drivers.add(new ParameterDriver(prefix + "[" + i + "]", 0.0, ACCELERATION_SCALE,
69 Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
70 }
71 }
72
73 /** {@inheritDoc} */
74 @Override
75 public void init(final SpacecraftState initialState, final AbsoluteDate target) {
76 if (referenceDate == null) {
77 referenceDate = initialState.getDate();
78 }
79 }
80
81 /** {@inheritDoc} */
82 @Override
83 public double signedAmplitude(final SpacecraftState state,
84 final double[] parameters) {
85 final double dt = state.getDate().durationFrom(referenceDate);
86 double amplitude = 0;
87 for (int i = parameters.length - 1; i >= 0; --i) {
88 amplitude += amplitude * dt + parameters[i];
89 }
90 return amplitude;
91 }
92
93 /** {@inheritDoc} */
94 @Override
95 public <T extends CalculusFieldElement<T>> T signedAmplitude(final FieldSpacecraftState<T> state,
96 final T[] parameters) {
97 final T dt = state.getDate().durationFrom(referenceDate);
98 T amplitude = dt.getField().getZero();
99 for (int i = parameters.length - 1; i >= 0; --i) {
100 amplitude = amplitude.add(amplitude.multiply(dt).add(parameters[i]));
101 }
102 return amplitude;
103 }
104
105 /** {@inheritDoc} */
106 @Override
107 public List<ParameterDriver> getParametersDrivers() {
108 return Collections.unmodifiableList(drivers);
109 }
110
111 }