Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages | Examples

RungeKuttaIntegrator.cpp

Go to the documentation of this file.
00001 //////////////////////////////////////////////////////////////////////////////////////////////////
00002 /*! \file RungeKuttaIntegrator.cpp
00003 *  \brief Implementation of the Runge-Kutta Fourth Order integrator.
00004 *  \author $Author: cakinli $
00005 *  \version $Revision: 1.1.1.1 $
00006 *  \date    $Date: 2005/04/26 17:41:00 $
00007 //////////////////////////////////////////////////////////////////////////////////////////////////
00008 *  \todo Add test cases
00009 */
00010 //////////////////////////////////////////////////////////////////////////////////////////////////
00011 
00012 
00013 #include "RungeKuttaIntegrator.h"
00014 namespace O_SESSAME {
00015 
00016 /*! \brief Creates a default, unitialized RK-integrator.
00017     */
00018 RungeKuttaIntegrator::RungeKuttaIntegrator()
00019 {
00020     m_NumSteps = 1;
00021 }
00022 
00023 /** \todo pull out RungeKuttaIntegrator::Step function */
00024 /*
00025 Matrix RungeKuttaIntegrator::Integrate(const Vector &_propTime, odeFunc _FuncPtr, const Vector &_initialConditions, const Matrix &_constants, vectorFuncPtr _vectorFuncPtr)
00026 {
00027         double timeInitial = _propTime(VectorIndexBase);
00028         double t = timeInitial;
00029         double h = (_propTime(VectorIndexBase + 1) - t) / m_NumSteps;
00030 
00031         int numEqs = _initialConditions.getIndexCount();
00032         Vector inputs = _initialConditions;
00033         Vector K1(numEqs);
00034         Vector K2(numEqs);
00035         Vector K3(numEqs);
00036         Vector K4(numEqs);
00037 
00038         Matrix output(m_NumSteps + 1, numEqs + 1);
00039 
00040         output(MatrixIndexBase,MatrixIndexBase) = timeInitial;
00041         output(MatrixIndexBase,_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = ~_initialConditions;
00042 
00043         Vector temp(numEqs);
00044         for (int ii = 1; ii <= m_NumSteps; ++ii)
00045         {
00046             K1 = h * _FuncPtr(t, inputs, _constants, _vectorFuncPtr);
00047             temp = inputs + K1 / 2.0;
00048             K2 = h * _FuncPtr(t + h/2, temp, _constants, _vectorFuncPtr);
00049             temp = inputs + K2 / 2.0;
00050             K3 = h * _FuncPtr(t + h/2, temp, _constants, _vectorFuncPtr);
00051             temp = inputs + K3;
00052             K4 = h * _FuncPtr(t + h, temp, _constants, _vectorFuncPtr);
00053             for (int jj = MatrixIndexBase; jj < MatrixIndexBase + numEqs; ++jj)
00054             {
00055                 inputs(jj) += (K1(jj)
00056                                  + 2.0 * K2(jj)
00057                                  + 2.0 * K3(jj)
00058                                  + K4(jj)) / 6.0;
00059             }
00060             t = timeInitial + ii * h;
00061             output(MatrixIndexBase + ii,MatrixIndexBase) = t;
00062             output(MatrixIndexBase + ii,_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = ~inputs; 
00063         }
00064         return output;
00065 }
00066 */
00067 
00068     /*! \brief Integrates the Right-Hand Side (RHS) equation using a Runge-Kutta 4th Order %integrator.
00069         * 
00070         * This function will integrate an equation of the form \f$\dot{\bf x} = f(t,{\bf x})\f$ from \f$t_0\f$ to \f$t_f\f$ given 
00071         * initial conditions, an orbit and attitude object (or empty references if not required), a matrix of constants, and an 
00072         * external call-back function. 
00073         *
00074         * @param _propTime This input variable specifies the list of integration times, from the starting value (first time) to the ending integration (last time) with the specified intervals.
00075         *       If no specific intervals are required (and can be interpolated later), the user needs to just specify the beginning and end times of integration.
00076         *       This vector is built by creating ssfTime object, and "push_back" them onto the vector list:
00077             * \code
00078             * vector<ssfTime> integrationTimes;
00079             * ssfTime begin(0);
00080             * ssfTime end(begin + 20);
00081             * integrationTimes.push_back(begin);
00082             * integrationTimes.push_back(end);
00083             * \endcode
00084         * @param _FunctorPtr This is the reference (odeFunctor) to the Right-Hand side (RHS) of the integration equation. It should be a single function that computes the time derivative 
00085         *       of the state given the time, current state, and other parameters.
00086         * @param _initialConditions The vector of initial conditions of the state being integrated. It can be any sized.
00087         * @param _pOrbit This is a pointer to an Orbit object. It will be passed directly to the RHS and may be used for evaluating the dynamics or disturbance torque/forces. 
00088         *       However, if no orbit is required, or used, the user should only pass a NULL pointer and the orbit object shouldn't be used in the user's RHS function.
00089         * @param _pAttitude This is a pointer to an Attitude object. It behaves much the same way as _Orbit above. It will be passed directly to the RHS function for use in 
00090         *       evaluation, but if not used, the user should only pass a NULL pointer, and the attitude object not used in the RHS function. 
00091         * @param _constants This is a matrix of constants that is required by the RHS function. The constants are passed to each evaluation of the RHS, and may be any size, and 
00092         *       store any values the user requires. Examples include Moments of Inertia, ballistic coefficients, mass, etc.
00093         * @param _functorPtr The Functor is a call-back function that the RHS can use to evaluate an external function call. The prototype of the _functorPtr must correspond to the Functor 
00094         *       definition, but other than that, may perform any calculations required by the user in the RHS function.
00095         * @return The output of the integration function is a matrix of calculated integration times (meshpoints), and integrated state values at each of the meshpoints.
00096             * \f[
00097             * \begin{bmatrix}
00098             * t_0 & x_{1,0} & x_{2,0} & ...\\
00099             * t_1 & x_{1,1} & x_{2,1} & ...\\
00100             * t_2 & x_{1,2} & x_{2,2} & ...\\
00101             * . & . & . & . \\
00102             * t_{final} & x_{1,f} & x_{2,f} & ...
00103             * \end{bmatrix}
00104             * \f]
00105             * where /f$t_T/f$ is the time at step T, and /f$x_{i,T}/f$ is the state value of element i, at time step T.
00106         */
00107 Matrix RungeKuttaIntegrator::Integrate(const vector<ssfTime>& _propTime, odeFunctor _odeFunctorPtr, const Vector& _initialConditions, Orbit* _pOrbit, Attitude* _pAttitude, const Matrix& _constants, const Functor& _functorPtr)
00108 {
00109         vector<ssfTime> propTime = _propTime; // need to create copy to prevent the stl .begin() and .end() from discarding the const-ness
00110         vector<ssfTime>::iterator timeIterator = propTime.begin();
00111 
00112         ssfTime timeInitial = (*timeIterator);
00113         ssfTime t = timeInitial;
00114         timeIterator = propTime.end() - 1;
00115         double h = ((*timeIterator).GetSeconds() - timeInitial.GetSeconds()) / m_NumSteps; // Calculation step size (seconds)
00116         int numEqs = _initialConditions.getIndexCount();
00117         Vector inputs = _initialConditions;
00118         Vector K1(numEqs);
00119         Vector K2(numEqs);
00120         Vector K3(numEqs);
00121         Vector K4(numEqs);
00122 
00123         Matrix output(m_NumSteps + 1, numEqs + 1);
00124 
00125         output(MatrixIndexBase,MatrixIndexBase) = timeInitial.GetSeconds();
00126         output(MatrixIndexBase,_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = ~_initialConditions;
00127         ssfTime tTemp;
00128         Vector temp(numEqs);
00129         for (int ii = 1; ii <= m_NumSteps; ++ii)
00130         {
00131             K1 = h * _odeFunctorPtr(t, inputs, _pOrbit, _pAttitude, _constants, _functorPtr);
00132             temp = inputs + K1 / 2.0;           tTemp = t + h/2;        
00133             K2 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr);
00134             temp = inputs + K2 / 2.0;                           
00135             K3 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr);
00136             temp = inputs + K3;         tTemp = t + h;          
00137             K4 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr);
00138             for (int jj = MatrixIndexBase; jj < MatrixIndexBase + numEqs; ++jj)
00139             {
00140                 inputs(jj) += (K1(jj)
00141                                  + 2.0 * K2(jj)
00142                                  + 2.0 * K3(jj)
00143                                  + K4(jj)) / 6.0;
00144             }
00145             t = timeInitial + ii * h;
00146             output(MatrixIndexBase + ii,MatrixIndexBase) = t.GetSeconds();
00147             output(MatrixIndexBase + ii,_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = ~inputs; 
00148         }
00149         return output;
00150 }
00151 } // close namespace O_SESSAME
00152 
00153 // Do not change the comments below - they will be added automatically by CVS
00154 /*****************************************************************************
00155 *       $Log: RungeKuttaIntegrator.cpp,v $
00156 *       Revision 1.1.1.1  2005/04/26 17:41:00  cakinli
00157 *       Adding OpenSESSAME to DSACSS distrib to capture fixed version.
00158 *       
00159 *       Revision 1.7  2003/05/22 02:59:15  nilspace
00160 *       Updated comments. Changed to pass in pointers to Orbit & Attitude objects.
00161 *       
00162 *       Revision 1.6  2003/05/13 18:58:27  nilspace
00163 *       Cleaned up comments.
00164 *       
00165 *       Revision 1.5  2003/04/27 22:04:34  nilspace
00166 *       Created the namespace O_SESSAME.
00167 *       
00168 *       Revision 1.4  2003/04/25 14:15:06  nilspace
00169 *       Created a temporary vectro<ssfTime> to prevent the STL .begin() and .end() functions from discarding the const-ness of _propTime in Integrate().
00170 *       
00171 *       Revision 1.3  2003/04/25 13:45:55  nilspace
00172 *       const'd Get() functions.
00173 *       
00174 *       Revision 1.2  2003/04/23 16:30:59  nilspace
00175 *       Various bugfixes & uploading of all changed code for new programmers.
00176 *       
00177 *       Revision 1.1  2003/04/08 22:29:55  nilspace
00178 *       Initial submission. Made a subclass of Integrator.
00179 *       
00180 *       
00181 *
00182 ******************************************************************************/

Generated on Wed Sep 5 12:54:25 2007 for DSACSS Operational Code by  doxygen 1.3.9.1