IsotropicRadiationSingleCoefficient.java

  1. /* Copyright 2002-2018 CS Systèmes d'Information
  2.  * Licensed to CS Systèmes d'Information (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. import org.hipparchus.RealFieldElement;
  19. import org.hipparchus.analysis.differentiation.DSFactory;
  20. import org.hipparchus.analysis.differentiation.DerivativeStructure;
  21. import org.hipparchus.geometry.euclidean.threed.FieldRotation;
  22. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  23. import org.hipparchus.geometry.euclidean.threed.Rotation;
  24. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  25. import org.hipparchus.util.FastMath;
  26. import org.orekit.errors.OrekitException;
  27. import org.orekit.errors.OrekitInternalError;
  28. import org.orekit.errors.OrekitMessages;
  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. /** This class represents the features of a simplified spacecraft.
  34.  * <p>This model uses a single coefficient cr, considered to be
  35.  * a {@link RadiationSensitive#REFLECTION_COEFFICIENT}.
  36.  * </p>
  37.  *
  38.  * @see org.orekit.forces.BoxAndSolarArraySpacecraft
  39.  * @see org.orekit.forces.drag.IsotropicDrag
  40.  * @see IsotropicRadiationCNES95Convention
  41.  * @author Luc Maisonobe
  42.  * @since 7.1
  43.  */
  44. public class IsotropicRadiationSingleCoefficient implements RadiationSensitive {

  45.     /** Parameters scaling factor.
  46.      * <p>
  47.      * We use a power of 2 to avoid numeric noise introduction
  48.      * in the multiplications/divisions sequences.
  49.      * </p>
  50.      */
  51.     private final double SCALE = FastMath.scalb(1.0, -3);

  52.     /** Driver for reflection coefficient. */
  53.     private final ParameterDriver reflectionParameterDriver;

  54.     /** Cross section (m²). */
  55.     private final double crossSection;

  56.     /** Factory for the DerivativeStructure instances. */
  57.     private final DSFactory factory;

  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.     /** Constructor with reflection coefficient min/max set by user.
  66.     * @param crossSection Surface (m²)
  67.     * @param cr reflection coefficient
  68.     * @param crMin Minimum value of reflection coefficient
  69.     * @param crMax Maximum value of reflection coefficient
  70.     */
  71.     public IsotropicRadiationSingleCoefficient(final double crossSection, final double cr,
  72.                                                final double crMin, final double crMax) {
  73.         try {
  74.             // in some corner cases (unknown spacecraft, fuel leaks, active piloting ...)
  75.             // the single coefficient may be arbitrary, and even negative
  76.             reflectionParameterDriver = new ParameterDriver(RadiationSensitive.REFLECTION_COEFFICIENT,
  77.                                                             cr, SCALE,
  78.                                                             crMin, crMax);
  79.             factory = new DSFactory(1, 1);
  80.         } catch (OrekitException oe) {
  81.             // this should never occur as valueChanged above never throws an exception
  82.             throw new OrekitInternalError(oe);
  83.         }

  84.         this.crossSection = crossSection;

  85.     }

  86.     /** {@inheritDoc} */
  87.     @Override
  88.     public ParameterDriver[] getRadiationParametersDrivers() {
  89.         return new ParameterDriver[] {
  90.             reflectionParameterDriver
  91.         };
  92.     }

  93.     /** {@inheritDoc} */
  94.     @Override
  95.     public Vector3D radiationPressureAcceleration(final AbsoluteDate date, final Frame frame, final Vector3D position,
  96.                                                   final Rotation rotation, final double mass, final Vector3D flux,
  97.                                                   final double[] parameters) {
  98.         final double cr = parameters[0];
  99.         return new Vector3D(crossSection * cr / mass, flux);
  100.     }

  101.     /** {@inheritDoc} */
  102.     @Override
  103.     public <T extends RealFieldElement<T>> FieldVector3D<T>
  104.         radiationPressureAcceleration(final FieldAbsoluteDate<T> date, final Frame frame,
  105.                                       final FieldVector3D<T> position,
  106.                                       final FieldRotation<T> rotation, final T mass,
  107.                                       final FieldVector3D<T> flux,
  108.                                       final T[] parameters)
  109.         throws OrekitException {
  110.         final T cr = parameters[0];
  111.         return new FieldVector3D<>(mass.reciprocal().multiply(crossSection).multiply(cr), flux);

  112.     }

  113.     /** {@inheritDoc} */
  114.     @Override
  115.     public FieldVector3D<DerivativeStructure> radiationPressureAcceleration(final AbsoluteDate date, final Frame frame, final Vector3D position,
  116.                                                                             final Rotation rotation, final double mass,
  117.                                                                             final Vector3D flux, final double[] parameters,
  118.                                                                             final String paramName)
  119.         throws OrekitException {

  120.         final DerivativeStructure crDS;
  121.         if (REFLECTION_COEFFICIENT.equals(paramName)) {
  122.             crDS = factory.variable(0, parameters[0]);
  123.         } else {
  124.             throw new OrekitException(OrekitMessages.UNSUPPORTED_PARAMETER_NAME, paramName,
  125.                                       ABSORPTION_COEFFICIENT + ", " + REFLECTION_COEFFICIENT);
  126.         }

  127.         return new FieldVector3D<>(crDS.multiply(crossSection / mass), flux);

  128.     }

  129. }