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 *
33 * <p>This model uses the coefficients described in the collective
34 * book edited by CNES in 1995: Spaceflight Dynamics (part I), in
35 * section 5.2.2.1.3.1 (page 296 of the English edition). The absorption
36 * coefficient is called α and the specular reflection coefficient is
37 * called τ. A comment in section 5.2.2.1.3.2 of the same book reads:
38 * <pre>
39 * Some authors prefer to express thermo-optical properties for surfaces
40 * using the following coefficients: Ka = α, Ks = (1-α)τ, Kd = (1-α)(1-τ)
41 * </pre>
42 * <p> Ka is the same absorption coefficient, and Ks is also called specular
43 * reflection coefficient, which leads to a confusion. In fact, as the Ka,
44 * Ks and Kd coefficients are the most frequently used ones (using the
45 * names Ca, Cs and Cd), when speaking about reflection coefficients, it
46 * is more often Cd that is considered rather than τ.
47 *
48 * <p>
49 * The classical set of coefficients Ca, Cs, and Cd are implemented in the
50 * sister class {@link IsotropicRadiationClassicalConvention}, which should
51 * probably be preferred to this legacy class.
52 * </p>
53 *
54 * @see org.orekit.forces.BoxAndSolarArraySpacecraft
55 * @see org.orekit.forces.drag.IsotropicDrag
56 * @see IsotropicRadiationClassicalConvention
57 * @author Luc Maisonobe
58 * @since 7.1
59 */
60 public class IsotropicRadiationCNES95Convention implements RadiationSensitive {
61
62 /** Parameters scaling factor.
63 * <p>
64 * We use a power of 2 to avoid numeric noise introduction
65 * in the multiplications/divisions sequences.
66 * </p>
67 */
68 private final double SCALE = FastMath.scalb(1.0, -3);
69
70 /** Drivers for absorption and specular reflection coefficients. */
71 private final List<ParameterDriver> parameterDrivers;
72
73 /** Cross section (m²). */
74 private final double crossSection;
75
76 /** Simple constructor.
77 * @param crossSection Surface (m²)
78 * @param alpha absorption coefficient α between 0.0 an 1.0
79 * @param tau specular reflection coefficient τ between 0.0 an 1.0
80 */
81 public IsotropicRadiationCNES95Convention(final double crossSection, final double alpha, final double tau) {
82 this.parameterDrivers = new ArrayList<>(3);
83 parameterDrivers.add(new ParameterDriver(RadiationSensitive.GLOBAL_RADIATION_FACTOR, 1.0, SCALE, 0.0, Double.POSITIVE_INFINITY));
84 parameterDrivers.add(new ParameterDriver(RadiationSensitive.ABSORPTION_COEFFICIENT, alpha, SCALE, 0.0, 1.0));
85 parameterDrivers.add(new ParameterDriver(RadiationSensitive.REFLECTION_COEFFICIENT, tau, SCALE, 0.0, 1.0));
86 this.crossSection = crossSection;
87 }
88
89 /** {@inheritDoc} */
90 @Override
91 public List<ParameterDriver> getRadiationParametersDrivers() {
92 return Collections.unmodifiableList(parameterDrivers);
93 }
94
95 /** {@inheritDoc} */
96 @Override
97 public Vector3D radiationPressureAcceleration(final SpacecraftState state, final Vector3D flux,
98 final double[] parameters) {
99 final double alpha = parameters[1];
100 final double tau = parameters[2];
101 final double kP = parameters[0] * crossSection * (1 + 4 * (1.0 - alpha) * (1.0 - tau) / 9.0);
102 return new Vector3D(kP / state.getMass(), flux);
103 }
104
105 /** {@inheritDoc} */
106 @Override
107 public <T extends CalculusFieldElement<T>> FieldVector3D<T>
108 radiationPressureAcceleration(final FieldSpacecraftState<T> state,
109 final FieldVector3D<T> flux,
110 final T[] parameters) {
111 final T alpha = parameters[1];
112 final T tau = parameters[2];
113 final T kP = alpha.negate().add(1).multiply(tau.negate().add(1)).multiply(4.0 / 9.0).add(1).
114 multiply(parameters[0]).multiply(crossSection);
115 return new FieldVector3D<>(state.getMass().reciprocal().multiply(kP), flux);
116 }
117 }