00001 ////////////////////////////////////////////////////////////////////////////////////////////////// 00002 /*! \file RungeKutta.h 00003 * \brief Runge-Kutta 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 #ifndef RUNGEKUTTA_H 00013 #define RUNGEKUTTA_H 00014 00015 #include <Matrix.h> 00016 00017 /*! defines a pointer to a Runge-Kutta right-hand side (RHS) function */ 00018 typedef Vector(*ptr2RKFunc)(const double &_time, const Vector &_states, const Matrix &_params); 00019 00020 /** 00021 * Integrate an equation of the form \f$\dot{y} = f\left(t,x\right)\f$ using the Runge-Kutta integration method. 00022 * \detail The Runge-Kutta integrator uses a right-hand side equation, \f$f\left(t,x\right)\f$ to compute the integration of the function over the specified time interval, given initial conditions, constants of integration, and number of steps desired (since this is a fixed step integrator). 00023 * @param odeFunc Pointer to the right-hand side (RHS) equation 00024 * @param timeInput time of current step to RHS file function 00025 * @param stateInput vector of state inputs at current step to RHS file function 00026 * @param constantsInput vector of constants that are not integrated and passed to the RHS function 00027 * @param _initialConditions vector of initial conditions of the state 00028 * @param _constants matrix of constants that should be passed to the RHS function 00029 * @param _timeInitial initial time of integration 00030 * @param _timeFinal final time of integration 00031 * @param _numSteps number of steps to integrate over (therefore timeStep = _timeFinal - _timeInitial / _numSteps) 00032 * @return matrix of integrated state outputs from the initial to final times. Format: 00033 /f[ 00034 \begin{bmatrix} 00035 t_0 & x_{1,0} & x_{2,0} & ...\\ 00036 t_1 & x_{1,1} & x_{2,1} & ...\\ 00037 t_2 & x_{1,2} & x_{2,2} & ...\\ 00038 . & . & . & . \\ 00039 t_final & x_{1,f} & x_{2,f} & ... 00040 \end{bmatrix} 00041 /f] 00042 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. 00043 */ 00044 inline Matrix RungeKuttaSolve(Vector (*odeFunc)(const double &timeInput, const Vector &stateInput, const Matrix &constantsInput), const Vector &_initialConditions, const Matrix &_constants, const double &_timeInitial, const double &_timeFinal, const int &_numSteps) 00045 { 00046 double h = (_timeFinal - _timeInitial) / _numSteps; 00047 double t = _timeInitial; 00048 int numEqs = _initialConditions.getIndexCount(); 00049 Vector inputs(numEqs); inputs = _initialConditions; 00050 Vector K1(numEqs); 00051 Vector K2(numEqs); 00052 Vector K3(numEqs); 00053 Vector K4(numEqs); 00054 00055 Matrix output(_numSteps + 1, numEqs + 1); 00056 00057 output(MatrixIndexBase,MatrixIndexBase) = _timeInitial; 00058 output(MatrixIndexBase,_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = ~_initialConditions; 00059 00060 Vector temp(numEqs); 00061 for (int ii = 1; ii <= _numSteps; ++ii) 00062 { 00063 K1 = h * odeFunc(t, inputs, _constants); 00064 temp = inputs + K1 / 2.0; 00065 K2 = h * odeFunc(t + h/2, temp, _constants); 00066 temp = inputs + K2 / 2.0; 00067 K3 = h * odeFunc(t + h/2, temp, _constants); 00068 temp = inputs + K3; 00069 K4 = h * odeFunc(t + h, temp, _constants); 00070 for (int jj = MatrixIndexBase; jj < MatrixIndexBase + numEqs; ++jj) 00071 { 00072 inputs(jj) += (K1(jj) 00073 + 2.0 * K2(jj) 00074 + 2.0 * K3(jj) 00075 + K4(jj)) / 6.0; 00076 } 00077 t = _timeInitial + ii * h; 00078 output(MatrixIndexBase + ii,MatrixIndexBase) = t; 00079 output(MatrixIndexBase + ii,_(MatrixIndexBase+1,MatrixIndexBase+numEqs)) = ~inputs; 00080 } 00081 return output; 00082 } 00083 00084 00085 #endif /* RungeKutta */ 00086 00087 // Do not change the comments below - they will be added automatically by CVS 00088 /***************************************************************************** 00089 * $Log: RungeKutta.h,v $ 00090 * Revision 1.1.1.1 2005/04/26 17:41:00 cakinli 00091 * Adding OpenSESSAME to DSACSS distrib to capture fixed version. 00092 * 00093 * Revision 1.4 2003/10/18 21:37:28 rsharo 00094 * Removed "../utils" from all qmake project paths. Prepended "utils 00095 * /" to all #include directives for utils. Removed ".h" extensions from STL header 00096 * s and referenced STL components from "std::" namespace. Overall, changed to be 00097 * more portable. 00098 * 00099 * Revision 1.3 2003/04/23 16:30:59 nilspace 00100 * Various bugfixes & uploading of all changed code for new programmers. 00101 * 00102 * Revision 1.2 2003/03/26 16:38:58 nilspace 00103 * Updated comments to better work with Doxygen. 00104 * 00105 * Revision 1.1 2003/03/05 20:41:04 nilspace 00106 * Initial submission of example source code file. 00107 * 00108 * 00109 ******************************************************************************/