00001 
00002 
00008 
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 Matrix RungeKuttaFehlbergIntegrator::Integrate(const vector<ssfTime>& _propTime, odeFunctor _odeFunctorPtr, const Vector& _initialConditions, Orbit* _pOrbit, Attitude* _pAttitude, const Matrix& _constants, const Functor& _functorPtr)
00022 {
00023         vector<ssfTime>::const_iterator timeIterator = _propTime.begin();
00024 
00025         ssfTime timeInitial = (*timeIterator);
00026         timeIterator = _propTime.end() - 1;
00027         ssfTime timeFinal = (*timeIterator);
00028         ssfTime t = timeInitial;
00029         double h = m_maxStepSize;
00030         double delta;
00031         bool hAccepted = false;
00032         
00033         int numEqs = _initialConditions.getIndexCount();
00034         Vector inputs = _initialConditions;
00035         Vector tempVector = inputs;
00036         Vector Error(numEqs);
00037         Vector K1(numEqs);
00038         Vector K2(numEqs);
00039         Vector K3(numEqs);
00040         Vector K4(numEqs);
00041         Vector K5(numEqs);      
00042         Vector K6(numEqs);
00043         vector<Vector> output; 
00044         output.reserve(floor((timeFinal-timeInitial) / m_maxStepSize));
00045     
00046         output.push_back(Vector(numEqs+1));
00047         output[0](MatrixIndexBase) = timeInitial.GetSeconds();
00048         output[0](_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = _initialConditions;
00049 
00050         ssfTime tTemp;
00051         Vector temp(numEqs);
00052         int ii = 1;
00053         while (t.GetSeconds() < timeFinal.GetSeconds())
00054         {
00055             hAccepted = true;
00056             K1 = h * _odeFunctorPtr(t, inputs, _pOrbit, _pAttitude, _constants, _functorPtr);
00057             tTemp = t + h / 4.;         temp = inputs + K1 / 4.0; 
00058             K2 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr);
00059             tTemp = t + 3/8. * h;       temp = inputs + (3/32. * K1 + 9/32. * K2);                      
00060             K3 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr);
00061             tTemp = t + 12/13. * h;     temp = inputs + (1932. * K1 - 7200. * K2 + 7296. * K3) / 2197.;                         
00062             K4 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr);
00063             tTemp = t + h;              temp = inputs + (439/216. * K1 - 8. * K2 +3680/513. * K3 - 845/4104. * K4);                     
00064             K5 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr);
00065             tTemp = t + h / 2;          temp = inputs - 8/27. * K1 +2. * K2 - 3544/2565. * K3 + 1859/4104. * K4 - 11/40.* K5; 
00066             K6 = h * _odeFunctorPtr(tTemp, temp, _pOrbit, _pAttitude, _constants, _functorPtr);
00067 
00068             
00069             for (int jj = MatrixIndexBase; jj < MatrixIndexBase + numEqs; ++jj)
00070             {
00071                 
00072                 Error(jj) = 1/h * abs(K1(jj)/360. - 128/4275. * K3(jj) - 2197/75240. * K4(jj) + K5(jj)/50. + K6(jj)/27.5);
00073 
00074 
00075 
00076 
00077 
00078                 
00079                 if((Error(jj) <= m_Tolerance) || (h < m_minStepSize))
00080                 {
00081                         tempVector(jj) = inputs(jj) + 25/216. * K1(jj) + 1408/2565. * K3(jj) + 2197/4104. * K4(jj) - 0.2* K5(jj);
00082                 }
00083                 else
00084                 {
00085                     hAccepted = false;
00086                     delta = 0.84 * pow((m_Tolerance / Error(jj)), 0.25);
00087                     if(delta <= 0.1)
00088                         h = 0.1*h;
00089                     else if(delta > 4)
00090                         h = 4*h;
00091                     else
00092                         h = delta * h;
00093                     if (h > m_maxStepSize)
00094                         h = m_maxStepSize;
00095                     break;
00096                 }
00097             }
00098             
00099             if(hAccepted)
00100             {
00101                 t = t + h;
00102                 inputs = tempVector;
00103                 output.push_back(Vector(numEqs+1));
00104                 output[ii](MatrixIndexBase) = t.GetSeconds();
00105                 output[ii](_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = inputs;
00106                 ++ii;
00107                 
00108                 if(t.GetSeconds() + h > timeFinal.GetSeconds())
00109                     h = timeFinal - t;
00110             }
00111 
00112         }
00113     
00114         
00115         Matrix outputMatrix(output.size(), numEqs + 1);
00116             
00117         for(ii = 0; ii < output.size(); ++ii)
00118         {
00119             outputMatrix(MatrixIndexBase + ii,_) = ~output[ii](_); 
00120         }
00121         return outputMatrix;
00122 }
00123 } 
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138 
00139 
00140 
00141 
00142 
00143 
00144 
00145 
00146