Commit 29658769 authored by Pascal Parraud's avatar Pascal Parraud
Browse files

added partial numerical propagator handling partial derivatives

parent 5da9f1b6
......@@ -58,6 +58,7 @@ import org.orekit.utils.PVCoordinatesProvider;
*
* @see SphericalSpacecraft
* @author Luc Maisonobe
* @author Pascal Parraud
* @version $Revision$ $Date$
*/
public class BoxAndSolarArraySpacecraft implements RadiationSensitive, DragSensitive {
......@@ -87,13 +88,16 @@ public class BoxAndSolarArraySpacecraft implements RadiationSensitive, DragSensi
private final Vector3D saZ;
/** Drag coefficient. */
private final double dragCoeff;
private double dragCoeff;
/** Absorption coefficient. */
private double absorptionCoeff;
/** Specular reflection coefficient. */
private final double specularReflectionCoeff;
private double specularReflectionCoeff;
/** Diffuse reflection coefficient. */
private final double diffuseReflectionCoeff;
private double diffuseReflectionCoeff;
/** Sun model. */
private final PVCoordinatesProvider sun;
......@@ -167,9 +171,9 @@ public class BoxAndSolarArraySpacecraft implements RadiationSensitive, DragSensi
this.saX = null;
this.dragCoeff = dragCoeff;
this.absorptionCoeff = absorptionCoeff;
this.specularReflectionCoeff = reflectionCoeff;
this.diffuseReflectionCoeff = 1 - (absorptionCoeff + reflectionCoeff);
}
/** Build a spacecraft model with linear rotation of solar array.
......@@ -256,6 +260,7 @@ public class BoxAndSolarArraySpacecraft implements RadiationSensitive, DragSensi
this.saX = Vector3D.crossProduct(saY, saZ);
this.dragCoeff = dragCoeff;
this.absorptionCoeff = absorptionCoeff;
this.specularReflectionCoeff = reflectionCoeff;
this.diffuseReflectionCoeff = 1 - (absorptionCoeff + reflectionCoeff);
......@@ -452,4 +457,36 @@ public class BoxAndSolarArraySpacecraft implements RadiationSensitive, DragSensi
return filtered;
}
/** {@inheritDoc} */
public void setAbsorptionCoefficient(double value) {
absorptionCoeff = value;
diffuseReflectionCoeff = 1 - (absorptionCoeff + specularReflectionCoeff);
}
/** {@inheritDoc} */
public double getAbsorptionCoefficient() {
return absorptionCoeff;
}
/** {@inheritDoc} */
public void setReflectionCoefficient(double value) {
specularReflectionCoeff = value;
diffuseReflectionCoeff = 1 - (absorptionCoeff + specularReflectionCoeff);
}
/** {@inheritDoc} */
public double getReflectionCoefficient() {
return specularReflectionCoeff;
}
/** {@inheritDoc} */
public void setDragCoefficient(double value) {
dragCoeff = value;
}
/** {@inheritDoc} */
public double getDragCoefficient() {
return dragCoeff;
}
}
/* Copyright 2002-2010 CS Communication & Systèmes
* Licensed to CS Communication & Systèmes (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.forces;
import org.orekit.errors.OrekitException;
import org.orekit.propagation.SpacecraftState;
import org.orekit.propagation.numerical.TimeDerivativesEquationsWithJacobians;
/** This interface represents a force modifying spacecraft motion.
*
* <p> Objects implementing this interface are intended to be added to a
* {@link org.orekit.propagation.numerical.NumericalPropagatorWithJacobians numerical propagator}
* processing the jacobians before the propagation is started. </p>
*
* @see ForceModel
*
* @author Pascal Parraud
* @version $Revision$ $Date$
*/
public interface ForceModelWithJacobians extends Parameterizable, ForceModel {
/** Compute the contribution of the force model to the perturbing
* acceleration and to the jacobians.
* @param s current state information: date, kinematics, attitude
* @param adder object where the contribution should be added
* @exception OrekitException if some specific error occurs
*/
void addContributionWithJacobians(SpacecraftState s, TimeDerivativesEquationsWithJacobians adder)
throws OrekitException;
}
package org.orekit.forces;
import java.util.Collection;
/** This interface enables the parameters jacobian processing.
*
* @author Pascal Parraud
* @version $Revision$ $Date$
*/
public interface Parameterizable {
/** Get the names of the supported parameters.
* @return parameters names
*/
Collection<String> getParametersNames();
/** Get parameter value from its name.
* @param name parameter name
* @return parameter value
* @exception IllegalArgumentException if parameter is not supported
*/
double getParameter(String name) throws IllegalArgumentException;
/** Set the value for a given parameter.
* @param name parameter name
* @param value parameter value
* @exception IllegalArgumentException if parameter is not supported
*/
void setParameter(String name, double value) throws IllegalArgumentException;
}
......@@ -30,6 +30,7 @@ import org.orekit.propagation.SpacecraftState;
* @see BoxAndSolarArraySpacecraft
* @author &Eacute;douard Delente
* @author Fabien Maussion
* @author Pascal Parraud
* @version $Revision:1665 $ $Date:2008-06-11 12:12:59 +0200 (mer., 11 juin 2008) $
*/
public class SphericalSpacecraft implements RadiationSensitive, DragSensitive {
......@@ -37,11 +38,23 @@ public class SphericalSpacecraft implements RadiationSensitive, DragSensitive {
/** Serializable UID. */
private static final long serialVersionUID = -1596721390500187750L;
/** Cross section (m<sup>2</sup>). */
private final double crossSection;
/** Drag coefficient. */
private double dragCoeff;
/** Absorption coefficient. */
private double absorptionCoeff;
/** Specular reflection coefficient. */
private double specularReflectionCoeff;
/** Composite drag coefficient (S.Cd/2). */
private final double kD;
private double kD;
/** Composite radiation pressure coefficient. */
private final double kP;
private double kP;
/** Simple constructor.
* @param crossSection Surface (m<sup>2</sup>)
......@@ -51,10 +64,18 @@ public class SphericalSpacecraft implements RadiationSensitive, DragSensitive {
* @param reflectionCoeff specular reflection coefficient between 0.0 an 1.0
* (used only for radiation pressure)
*/
public SphericalSpacecraft(final double crossSection, final double dragCoeff,
final double absorptionCoeff, final double reflectionCoeff) {
kD = dragCoeff * crossSection / 2;
kP = crossSection * (1 + 4 * (1.0 - absorptionCoeff) * (1.0 - reflectionCoeff) / 9);
public SphericalSpacecraft(final double crossSection,
final double dragCoeff,
final double absorptionCoeff,
final double reflectionCoeff) {
this.crossSection = crossSection;
this.dragCoeff = dragCoeff;
this.absorptionCoeff = absorptionCoeff;
this.specularReflectionCoeff = reflectionCoeff;
this.setKD();
this.setKP();
}
/** {@inheritDoc} */
......@@ -68,4 +89,47 @@ public class SphericalSpacecraft implements RadiationSensitive, DragSensitive {
return new Vector3D(kP / state.getMass(), flux);
}
/** {@inheritDoc} */
public void setDragCoefficient(double value) {
dragCoeff = value;
this.setKD();
}
/** {@inheritDoc} */
public double getDragCoefficient() {
return dragCoeff;
}
/** {@inheritDoc} */
public void setAbsorptionCoefficient(double value) {
absorptionCoeff = value;
this.setKP();
}
/** {@inheritDoc} */
public double getAbsorptionCoefficient() {
return absorptionCoeff;
}
/** {@inheritDoc} */
public void setReflectionCoefficient(double value) {
specularReflectionCoeff = value;
this.setKP();
}
/** {@inheritDoc} */
public double getReflectionCoefficient() {
return specularReflectionCoeff;
}
/** Set kD value */
private void setKD() {
kD = dragCoeff * crossSection / 2;
}
/** Set kP value */
private void setKP() {
kP = crossSection * (1 + 4 * (1.0 - absorptionCoeff) * (1.0 - specularReflectionCoeff) / 9);
}
}
......@@ -16,13 +16,17 @@
*/
package org.orekit.forces.drag;
import java.util.ArrayList;
import java.util.Collection;
import org.apache.commons.math.geometry.Vector3D;
import org.orekit.errors.OrekitException;
import org.orekit.forces.ForceModel;
import org.orekit.forces.ForceModelWithJacobians;
import org.orekit.frames.Frame;
import org.orekit.propagation.SpacecraftState;
import org.orekit.propagation.events.EventDetector;
import org.orekit.propagation.numerical.TimeDerivativesEquations;
import org.orekit.propagation.numerical.TimeDerivativesEquationsWithJacobians;
import org.orekit.time.AbsoluteDate;
......@@ -31,16 +35,20 @@ import org.orekit.time.AbsoluteDate;
*
* &gamma = (1/2 * Ro * V<sup>2</sup> * S / Mass) * DragCoefVector
*
* With DragCoefVector = {Cx, Cy, Cz} and S given by the user threw the interface
* With DragCoefVector = {Cx, Cy, Cz} and S given by the user through the interface
* {@link DragSensitive}
*
* @author &Eacute;douard Delente
* @author Fabien Maussion
* @author V&eacute;ronique Pommier-Maurussane
* @author Pascal Parraud
* @version $Revision:1665 $ $Date:2008-06-11 12:12:59 +0200 (mer., 11 juin 2008) $
*/
public class DragForce implements ForceModel {
public class DragForce implements ForceModelWithJacobians {
/** Parameter name for drag coefficient. */
public static final String DRAG_COEFFICIENT = "DRAG COEFFICIENT";
/** Serializable UID. */
private static final long serialVersionUID = 2574653656986559955L;
......@@ -50,6 +58,9 @@ public class DragForce implements ForceModel {
/** Spacecraft. */
private final DragSensitive spacecraft;
/** List of the parameters names. */
private final ArrayList<String> parametersNames = new ArrayList<String>();
/** Simple constructor.
* @param atmosphere atmospheric model
......@@ -58,6 +69,7 @@ public class DragForce implements ForceModel {
public DragForce(final Atmosphere atmosphere, final DragSensitive spacecraft) {
this.atmosphere = atmosphere;
this.spacecraft = spacecraft;
this.parametersNames.add(DRAG_COEFFICIENT);
}
/** Compute the contribution of the drag to the perturbing acceleration.
......@@ -89,4 +101,32 @@ public class DragForce implements ForceModel {
return new EventDetector[0];
}
/** {@inheritDoc} */
public void addContributionWithJacobians(SpacecraftState s,
TimeDerivativesEquationsWithJacobians adder) throws OrekitException {
}
/** {@inheritDoc} */
public Collection<String> getParametersNames() {
return parametersNames;
}
/** {@inheritDoc} */
public double getParameter(String name) throws IllegalArgumentException {
if (name.matches(DRAG_COEFFICIENT)) {
return spacecraft.getDragCoefficient();
} else {
throw OrekitException.createIllegalArgumentException("unknown parameter {0}", name);
}
}
/** {@inheritDoc} */
public void setParameter(String name, double value) throws IllegalArgumentException {
if (name.matches(DRAG_COEFFICIENT)) {
spacecraft.setDragCoefficient(value);
} else {
throw OrekitException.createIllegalArgumentException("unknown parameter {0}", name);
}
}
}
......@@ -26,6 +26,7 @@ import org.orekit.propagation.SpacecraftState;
*
* @see DragForce
* @author Luc Maisonobe
* @author Pascal Parraud
* @version $Revision$ $Date$
*/
public interface DragSensitive extends Serializable {
......@@ -43,6 +44,16 @@ public interface DragSensitive extends Serializable {
* @throws OrekitException if acceleration cannot be computed
*/
Vector3D dragAcceleration(SpacecraftState state, double density, Vector3D relativeVelocity)
throws OrekitException;
throws OrekitException;
/** Set the drag coefficient.
* @param value drag coefficient
*/
void setDragCoefficient(double value);
/** Get the drag coefficient.
* @return drag coefficient
*/
double getDragCoefficient();
}
......@@ -26,6 +26,7 @@ import org.orekit.propagation.SpacecraftState;
*
* @see SolarRadiationPressure
* @author Luc Maisonobe
* @author Pascal Parraud
* @version $Revision$ $Date$
*/
public interface RadiationSensitive extends Serializable {
......@@ -43,4 +44,24 @@ public interface RadiationSensitive extends Serializable {
Vector3D radiationPressureAcceleration(SpacecraftState state, Vector3D flux)
throws OrekitException;
/** Set the absorption coefficient.
* @param value absorption coefficient
*/
void setAbsorptionCoefficient(double value);
/** Get the absorption coefficient.
* @return absorption coefficient
*/
double getAbsorptionCoefficient();
/** Set the specular reflection coefficient.
* @param value specular reflection coefficient
*/
void setReflectionCoefficient(double value);
/** Get the specular reflection coefficient.
* @return reflection coefficient
*/
double getReflectionCoefficient();
}
......@@ -16,14 +16,18 @@
*/
package org.orekit.forces.radiation;
import java.util.ArrayList;
import java.util.Collection;
import org.apache.commons.math.geometry.Vector3D;
import org.orekit.errors.OrekitException;
import org.orekit.forces.ForceModel;
import org.orekit.forces.ForceModelWithJacobians;
import org.orekit.frames.Frame;
import org.orekit.propagation.SpacecraftState;
import org.orekit.propagation.events.AbstractDetector;
import org.orekit.propagation.events.EventDetector;
import org.orekit.propagation.numerical.TimeDerivativesEquations;
import org.orekit.propagation.numerical.TimeDerivativesEquationsWithJacobians;
import org.orekit.time.AbsoluteDate;
import org.orekit.utils.PVCoordinates;
import org.orekit.utils.PVCoordinatesProvider;
......@@ -33,9 +37,16 @@ import org.orekit.utils.PVCoordinatesProvider;
* @author Fabien Maussion
* @author &Eacute;douard Delente
* @author V&eacute;ronique Pommier-Maurussane
* @author Pascal Parraud
* @version $Revision:1665 $ $Date:2008-06-11 12:12:59 +0200 (mer., 11 juin 2008) $
*/
public class SolarRadiationPressure implements ForceModel {
public class SolarRadiationPressure implements ForceModelWithJacobians {
/** Parameter name for absorption coefficient. */
public static final String ABSORPTION_COEFFICIENT = "ABSORPTION COEFFICIENT";
/** Parameter name for specular reflection coefficient. */
public static final String REFLECTION_COEFFICIENT = "REFLECTION COEFFICIENT";
/** Serializable UID. */
private static final long serialVersionUID = 8874297900604482921L;
......@@ -58,6 +69,9 @@ public class SolarRadiationPressure implements ForceModel {
/** Spacecraft. */
private final RadiationSensitive spacecraft;
/** List of the parameters names. */
private final ArrayList<String> parametersNames = new ArrayList<String>();
/** Simple constructor with default reference values.
* <p>When this constructor is used, the reference values are:</p>
......@@ -94,6 +108,8 @@ public class SolarRadiationPressure implements ForceModel {
this.sun = sun;
this.equatorialRadius = equatorialRadius;
this.spacecraft = spacecraft;
this.parametersNames.add(ABSORPTION_COEFFICIENT);
this.parametersNames.add(REFLECTION_COEFFICIENT);
}
/** {@inheritDoc} */
......@@ -198,6 +214,38 @@ public class SolarRadiationPressure implements ForceModel {
};
}
/** {@inheritDoc} */
public void addContributionWithJacobians(SpacecraftState s,
TimeDerivativesEquationsWithJacobians adder) throws OrekitException {
}
/** {@inheritDoc} */
public Collection<String> getParametersNames() {
return parametersNames;
}
/** {@inheritDoc} */
public double getParameter(String name) throws IllegalArgumentException {
if (name.matches(ABSORPTION_COEFFICIENT)) {
return spacecraft.getAbsorptionCoefficient();
} else if (name.matches(REFLECTION_COEFFICIENT)) {
return spacecraft.getReflectionCoefficient();
} else {
throw OrekitException.createIllegalArgumentException("unknown parameter {0}", name);
}
}
/** {@inheritDoc} */
public void setParameter(String name, double value) throws IllegalArgumentException {
if (name.matches(ABSORPTION_COEFFICIENT)) {
spacecraft.setAbsorptionCoefficient(value);
} else if (name.matches(REFLECTION_COEFFICIENT)) {
spacecraft.setReflectionCoefficient(value);
} else {
throw OrekitException.createIllegalArgumentException("unknown parameter {0}", name);
}
}
/** This class defines the umbra entry/exit detector. */
private class UmbraDetector extends AbstractDetector {
......
......@@ -127,43 +127,43 @@ public class NumericalPropagator implements Propagator {
private static final long serialVersionUID = -2385169798425713766L;
/** Attitude law. */
private AttitudeLaw attitudeLaw;
protected AttitudeLaw attitudeLaw;
/** Central body gravitational constant. */
private double mu;
protected double mu;
/** Force models used during the extrapolation of the Orbit. */
private final List<ForceModel> forceModels;
protected final List<ForceModel> forceModels;
/** Event detectors not related to force models. */
private final List<EventDetector> detectors;
protected final List<EventDetector> detectors;
/** State vector. */
private final double[] stateVector;
protected final double[] stateVector;
/** Start date. */
private AbsoluteDate startDate;
protected AbsoluteDate startDate;
/** Initial state to propagate. */
private SpacecraftState initialState;
protected SpacecraftState initialState;
/** Current state to propagate. */
private SpacecraftState currentState;
protected SpacecraftState currentState;
/** Integrator selected by the user for the orbital extrapolation process. */
private transient FirstOrderIntegrator integrator;
protected transient FirstOrderIntegrator integrator;
/** Counter for differential equations calls. */
private int calls;
protected int calls;
/** Gauss equations handler. */
private TimeDerivativesEquations adder;
protected TimeDerivativesEquations adder;
/** Propagator mode handler. */
private ModeHandler modeHandler;
protected ModeHandler modeHandler;
/** Current mode. */
private int mode;
protected int mode;
/** Create a new instance of NumericalPropagator, based on orbit definition mu.
* After creation, the instance is empty, i.e. the attitude law is set to an
......@@ -443,7 +443,7 @@ public class NumericalPropagator implements Propagator {
/** Wrap an Orekit event detector and register it to the integrator.
* @param osf event handler to wrap
*/
private void setUpEventDetector(final EventDetector osf) {
protected void setUpEventDetector(final EventDetector osf) {
final EventHandler handler =
new AdaptedEventDetector(osf, startDate, mu,
initialState.getFrame(), attitudeLaw);
......
......@@ -256,7 +256,7 @@ public class TimeDerivativesEquations implements Serializable {
}
/** Add the contribution of the Kepler evolution.
* <p>Since the Kepler evolution if the most important, it should
* <p>Since the Kepler evolution is the most important, it should
* be added after all the other ones, in order to improve
* numerical accuracy.</p>
*/
......
/* Copyright 2002-2010 CS Communication & Systèmes
* Licensed to CS Communication & Systèmes (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*