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

RungeKuttaFehlbergIntegrator.cpp

Go to the documentation of this file.
00001 //////////////////////////////////////////////////////////////////////////////////////////////////
00002 /*! \file RungeKuttaFehlbergIntegrator.cpp
00003 *  \brief Implementation of the Runge-Kutta-Fehlberg Fourth Order integrator.
00004 *  \author $Author: jayhawk_hokie $
00005 *  \version $Revision: 1.2 $
00006 *  \date    $Date: 2007/08/02 22:06:34 $
00007 *//////////////////////////////////////////////////////////////////////////////////////////////////
00008 /*! \warning NOT VERIFIED
00009 *  \todo Add test cases
00010 */
00011 //////////////////////////////////////////////////////////////////////////////////////////////////
00012 
00013 
00014 #include "RungeKuttaFehlbergIntegrator.h"
00015 namespace O_SESSAME {
00016 
00017 RungeKuttaFehlbergIntegrator::RungeKuttaFehlbergIntegrator() : m_Tolerance(0.00001), m_minStepSize(0.01), m_maxStepSize(0.25)
00018 {
00019 }
00020 
00021 /*
00022 Matrix RungeKuttaFehlbergIntegrator::Integrate(const vector<ssfTime>& _propTime, odeFunctor _odeFunctorPtr, const Vector& _initialConditions, Orbit* _pOrbit, Attitude* _pAttitude, const Matrix& _constants, const Functor& _functorPtr)
00023 {
00024         vector<ssfTime>::const_iterator timeIterator = _propTime.begin();
00025 
00026         ssfTime timeInitial = (*timeIterator);
00027         timeIterator = _propTime.end() - 1;
00028         ssfTime timeFinal = (*timeIterator);
00029         ssfTime t = timeInitial;
00030         double h = m_maxStepSize;
00031         double delta;
00032         bool hAccepted = false;
00033         
00034         int numEqs = _initialConditions.getIndexCount();
00035         Vector inputs = _initialConditions;
00036         Vector tempVector = inputs;
00037         Vector Error(numEqs);
00038         Vector K1(numEqs);
00039         Vector K2(numEqs);
00040         Vector K3(numEqs);
00041         Vector K4(numEqs);
00042         Vector K5(numEqs);      
00043         Vector K6(numEqs);
00044         vector<Vector> output; // state + time
00045         output.reserve( floor((timeFinal-timeInitial) / m_maxStepSize) );
00046     
00047         output.push_back(Vector(numEqs+1));
00048         output[0](MatrixIndexBase) = timeInitial.GetSeconds();
00049         output[0](_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = _initialConditions;
00050 
00051         ssfTime tTemp;
00052         Vector temp(numEqs);
00053         int ii = 1;
00054         while (t.GetSeconds() < timeFinal.GetSeconds())
00055         {
00056             hAccepted = true;
00057             K1 = h * _odeFunctorPtr(t, inputs, _pOrbit, _pAttitude, _constants, _functorPtr);
00058             tTemp = t + h / 4.;         temp = inputs + K1 / 4.0; 
00059             K2 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr);
00060             tTemp = t + 3/8. * h;       temp = inputs + (3/32. * K1 + 9/32. * K2);                      
00061             K3 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr);
00062             tTemp = t + 12/13. * h;     temp = inputs + (1932. * K1 - 7200. * K2 + 7296. * K3) / 2197.;                         
00063             K4 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr);
00064             tTemp = t + h;              temp = inputs + (439/216. * K1 - 8. * K2 +3680/513. * K3 - 845/4104. * K4);                     
00065             K5 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr);
00066             tTemp = t + h / 2;          temp = inputs - 8/27. * K1 +2. * K2 - 3544/2565. * K3 + 1859/4104. * K4 - 11/40.* K5; 
00067             K6 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr);
00068 
00069             // Check that all the variables are within tolerance
00070             for (int jj = MatrixIndexBase; jj < MatrixIndexBase + numEqs; ++jj)
00071             {
00072                 //  If error <= tolerance, calculate integral & output
00073                 Error(jj) = 1/h * abs(K1(jj)/360. - 128/4275. * K3(jj) - 2197/75240. * K4(jj) + K5(jj)/50. + K6(jj)/27.5);
00074 
00075 //      Could be used for testing
00076 //                wTilda = 16/135*K1(jj) + 6656/12825 * K3(jj) + 28561/56430 * K4(jj) - 9/50 * K5(jj) + 2/55*K6(jj);
00077 //                w = 25/216 * K1(jj) + 1408/2565 * K3(jj) + 2197/4104 * K4(jj) - 0.2* K5(jj);
00078 //                Error(jj) = abs(wTilda - w);
00079                 
00080                 if((Error(jj) <= m_Tolerance) || (h < m_minStepSize))
00081                 {
00082                         tempVector(jj) = inputs(jj) + 25/216. * K1(jj) + 1408/2565. * K3(jj) + 2197/4104. * K4(jj) - 0.2* K5(jj);
00083                 }
00084                 else
00085                 {// if error > tolerance, calc new step size, and re-integrate this step
00086                     hAccepted = false;
00087                     delta = 0.84 * pow((m_Tolerance / Error(jj)), 0.25);
00088                     if(delta <= 0.1)
00089                         h = 0.1*h;
00090                     else if(delta > 4)
00091                         h = 4*h;
00092                     else
00093                         h = delta * h;
00094                     if (h > m_maxStepSize)
00095                         h = m_maxStepSize;
00096                     break;
00097                 }
00098             }
00099             // if all variables are within tolerance, then save output and step forward
00100             if(hAccepted)
00101             {
00102                 t = t + h;
00103                 inputs = tempVector;
00104                 output.push_back(Vector(numEqs+1));
00105                 output[ii](MatrixIndexBase) = t.GetSeconds();
00106                 output[ii](_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = inputs;
00107                 ++ii;
00108                 
00109                 if(t.GetSeconds() + h > timeFinal.GetSeconds())
00110                     h = timeFinal - t;
00111             }
00112 
00113         }
00114     
00115         // Because we used a dynamic vector<Vector>, we need to move this a Matrix    
00116         Matrix outputMatrix(output.size(), numEqs + 1);
00117             
00118         for(ii = 0; ii < output.size(); ++ii)
00119         {
00120             outputMatrix(MatrixIndexBase + ii,_) = ~output[ii](_); 
00121         }
00122         return outputMatrix;
00123 }
00124 */
00125 
00126 } // close namespace O_SESSAME
00127 
00128 // Do not change the comments below - they will be added automatically by CVS
00129 /*****************************************************************************
00130 *       $Log: RungeKuttaFehlbergIntegrator.cpp,v $
00131 *       Revision 1.2  2007/08/02 22:06:34  jayhawk_hokie
00132 *       Commented function.
00133 *       
00134 *       Revision 1.1.1.1  2005/04/26 17:41:00  cakinli
00135 *       Adding OpenSESSAME to DSACSS distrib to capture fixed version.
00136 *       
00137 *       Revision 1.5  2003/06/05 20:30:52  nilspace
00138 *       Removed testing cout commands.
00139 *       
00140 *       Revision 1.4  2003/06/05 20:09:14  nilspace
00141 *       Finished implementation and verified against a short 2 second integration.
00142 *       
00143 *       Revision 1.3  2003/05/22 02:59:15  nilspace
00144 *       Updated comments. Changed to pass in pointers to Orbit & Attitude objects.
00145 *       
00146 *       Revision 1.2  2003/04/25 13:45:55  nilspace
00147 *       const'd Get() functions.
00148 *       
00149 *       Revision 1.1  2003/04/23 15:08:28  nilspace
00150 *       Initial submission of RKF integrator.
00151 *       
00152 *       
00153 ******************************************************************************/
00154 
00155 

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