IsotropicDrag.java

  1. /* Copyright 2002-2019 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.drag;

  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 models isotropic drag effects.
  34.  * <p>The model of this spacecraft is a simple spherical model, this
  35.  * means that all coefficients are constant and do not depend of
  36.  * the direction.</p>
  37.  *
  38.  * @see org.orekit.forces.BoxAndSolarArraySpacecraft
  39.  * @see org.orekit.forces.radiation.IsotropicRadiationCNES95Convention
  40.  * @author Luc Maisonobe
  41.  * @since 7.1
  42.  */
  43. public class IsotropicDrag implements DragSensitive {

  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.     /** Drivers for drag coefficient parameter. */
  52.     private final ParameterDriver[] dragParametersDrivers;

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

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

  57.     /** Constructor with drag coefficient min/max set to ±∞.
  58.      * @param crossSection Surface (m²)
  59.      * @param dragCoeff drag coefficient
  60.      */
  61.     public IsotropicDrag(final double crossSection, final double dragCoeff) {
  62.         this(crossSection, dragCoeff, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
  63.     }

  64.     /** Constructor with drag coefficient min/max set by user.
  65.      * @param crossSection Surface (m²)
  66.      * @param dragCoeff drag coefficient
  67.      * @param dragCoeffMin Minimum value of drag coefficient
  68.      * @param dragCoeffMax Maximum value of drag coefficient
  69.      */
  70.     public IsotropicDrag(final double crossSection, final double dragCoeff,
  71.                          final double dragCoeffMin, final double dragCoeffMax) {
  72.         this.dragParametersDrivers     = new ParameterDriver[1];
  73.         try {
  74.             // in some corner cases (unknown spacecraft, fuel leaks, active piloting ...)
  75.             // the single coefficient may be arbitrary, and even negative
  76.             dragParametersDrivers[0] = new ParameterDriver(DragSensitive.DRAG_COEFFICIENT,
  77.                                                            dragCoeff, SCALE,
  78.                                                            dragCoeffMin, dragCoeffMax);
  79.         } catch (OrekitException oe) {
  80.             // this should never occur as valueChanged above never throws an exception
  81.             throw new OrekitInternalError(oe);
  82.         }
  83.         this.crossSection = crossSection;
  84.         this.factory      = new DSFactory(1, 1);
  85.     }

  86.     /** {@inheritDoc} */
  87.     @Override
  88.     public ParameterDriver[] getDragParametersDrivers() {
  89.         return dragParametersDrivers.clone();
  90.     }

  91.     /** {@inheritDoc} */
  92.     @Override
  93.     public Vector3D dragAcceleration(final AbsoluteDate date, final Frame frame, final Vector3D position,
  94.                                      final Rotation rotation, final double mass,
  95.                                      final double density, final Vector3D relativeVelocity,
  96.                                      final double[] parameters) {
  97.         final double dragCoeff = parameters[0];
  98.         return new Vector3D(relativeVelocity.getNorm() * density * dragCoeff * crossSection / (2 * mass),
  99.                             relativeVelocity);
  100.     }

  101.     /** {@inheritDoc} */
  102.     @Override
  103.     public <T extends RealFieldElement<T>> FieldVector3D<T>
  104.         dragAcceleration(final FieldAbsoluteDate<T> date, final Frame frame,
  105.                          final FieldVector3D<T> position, final FieldRotation<T> rotation,
  106.                          final T mass, final T density,
  107.                          final FieldVector3D<T> relativeVelocity,
  108.                          final T[] parameters) {
  109.         final T dragCoeff = parameters[0];
  110.         return new FieldVector3D<>(relativeVelocity.getNorm().multiply(density.multiply(dragCoeff).multiply(crossSection / 2)).divide(mass),
  111.                                    relativeVelocity);
  112.     }

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

  120.         if (!DRAG_COEFFICIENT.equals(paramName)) {
  121.             throw new OrekitException(OrekitMessages.UNSUPPORTED_PARAMETER_NAME, paramName, DRAG_COEFFICIENT);
  122.         }

  123.         final DerivativeStructure dragCoeffDS = factory.variable(0, parameters[0]);

  124.         return new FieldVector3D<>(dragCoeffDS.multiply(relativeVelocity.getNorm() * density * crossSection / (2 * mass)),
  125.                                    relativeVelocity);

  126.     }

  127. }