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.radiation;
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.geometry.euclidean.threed.FieldVector3D;
25 import org.hipparchus.geometry.euclidean.threed.Vector3D;
26 import org.hipparchus.util.FastMath;
27 import org.orekit.propagation.FieldSpacecraftState;
28 import org.orekit.propagation.SpacecraftState;
29 import org.orekit.utils.ParameterDriver;
30
31 /** This class represents the features of a simplified spacecraft.
32 * <p>This model uses a single coefficient cr, considered to be
33 * a {@link RadiationSensitive#REFLECTION_COEFFICIENT}.
34 * </p>
35 *
36 * @see org.orekit.forces.BoxAndSolarArraySpacecraft
37 * @see org.orekit.forces.drag.IsotropicDrag
38 * @see IsotropicRadiationCNES95Convention
39 * @author Luc Maisonobe
40 * @since 7.1
41 */
42 public class IsotropicRadiationSingleCoefficient implements RadiationSensitive {
43
44 /** Parameters scaling factor.
45 * <p>
46 * We use a power of 2 to avoid numeric noise introduction
47 * in the multiplications/divisions sequences.
48 * </p>
49 */
50 private final double SCALE = FastMath.scalb(1.0, -3);
51
52 /** Drivers for radiation coefficient. */
53 private final List<ParameterDriver> radiationParametersDrivers;
54
55 /** Cross section (m²). */
56 private final double crossSection;
57
58 /** Constructor with reflection coefficient min/max set to ±∞.
59 * @param crossSection Surface (m²)
60 * @param cr reflection coefficient
61 */
62 public IsotropicRadiationSingleCoefficient(final double crossSection, final double cr) {
63 this(crossSection, cr, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
64 }
65
66 /** Constructor with reflection coefficient min/max set by user.
67 * @param crossSection Surface (m²)
68 * @param cr reflection coefficient
69 * @param crMin Minimum value of reflection coefficient
70 * @param crMax Maximum value of reflection coefficient
71 */
72 public IsotropicRadiationSingleCoefficient(final double crossSection, final double cr,
73 final double crMin, final double crMax) {
74 // in some corner cases (unknown spacecraft, fuel leaks, active piloting ...)
75 // the single coefficient may be arbitrary, and even negative
76 // the REFLECTION_COEFFICIENT parameter should be sufficient, but GLOBAL_RADIATION_FACTOR
77 // was added as of 12.0 for consistency with BoxAndSolarArraySpacecraft
78 // that only has a global multiplicatof factor, hence allowing this name
79 // to be used for both models
80 this.radiationParametersDrivers = new ArrayList<>(2);
81 radiationParametersDrivers.add(new ParameterDriver(RadiationSensitive.GLOBAL_RADIATION_FACTOR,
82 1.0, SCALE,
83 0.0, Double.POSITIVE_INFINITY));
84 radiationParametersDrivers.add(new ParameterDriver(RadiationSensitive.REFLECTION_COEFFICIENT,
85 cr, SCALE,
86 crMin, crMax));
87
88 this.crossSection = crossSection;
89
90 }
91
92 /** {@inheritDoc} */
93 @Override
94 public List<ParameterDriver> getRadiationParametersDrivers() {
95 return Collections.unmodifiableList(radiationParametersDrivers);
96 }
97
98 /** {@inheritDoc} */
99 @Override
100 public Vector3D radiationPressureAcceleration(final SpacecraftState state, final Vector3D flux,
101 final double[] parameters) {
102 final double cr = parameters[1];
103 return new Vector3D(parameters[0] * crossSection * cr / state.getMass(), flux);
104 }
105
106 /** {@inheritDoc} */
107 @Override
108 public <T extends CalculusFieldElement<T>> FieldVector3D<T>
109 radiationPressureAcceleration(final FieldSpacecraftState<T> state,
110 final FieldVector3D<T> flux,
111 final T[] parameters) {
112 final T cr = parameters[1];
113 return new FieldVector3D<>(state.getMass().reciprocal().multiply(parameters[0]).multiply(crossSection).multiply(cr),
114 flux);
115
116 }
117 }