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