00001
00002
00004
00005 #include "RK4Mover.h"
00006
00008
00010
00011 CRK4Mover::CRK4Mover()
00012 {
00013
00014 }
00015
00016 CRK4Mover::CRK4Mover(double frequency, double stepSize)
00017 :CDifferentialEquationMover(frequency,stepSize)
00018 {
00019
00020 }
00021
00022 CRK4Mover::~CRK4Mover()
00023 {
00024
00025 }
00026
00027 void CRK4Mover::Move(double xInitial, double xFinal, ReactionNetwork *pReactionNetwork)
00028 {
00029
00030 double xInterval = xFinal-xInitial;
00031 if(this->MoveTimeIsZero(xInterval)) {return;}
00032 if(m_dStepSize > xInterval) {m_dStepSize = xInterval;}
00033
00034
00035 this->m_pReactionNetwork = pReactionNetwork;
00036
00037 int dataCnt=0;
00038 int nChem = m_pReactionNetwork->GetNumberOfChemicals();
00039 double *chem = new double[nChem];
00040 double *dChemdt = new double[nChem];
00041 int freq = 1.0/m_dStepSize;
00042
00043 m_dTime = xInitial;
00044
00045
00046 m_iCount = (int) xInitial;
00047 double nextTime = m_dTime;
00048
00049 for (int cNum = 0; cNum < nChem; cNum++)
00050 {
00051 chem[cNum] = m_pReactionNetwork->GetChemical(cNum)->GetAmount();
00052 }
00053
00054 while(m_dTime < xFinal)
00055 {
00056 while(m_dTime < nextTime)
00057 {
00058 ComputeDerivatives(chem,dChemdt);
00059 FourthOrderStep(nChem,chem,dChemdt);
00060
00061 m_dTime += m_dStepSize;
00062 }
00063
00064
00065 for(int i = 0; i < nChem; i++)
00066 {
00067 m_pReactionNetwork->GetChemical(i)->SetAmount(chem[i]);
00068 }
00069
00070 m_iCount++;
00071 Notify();
00072 nextTime += 1.0;
00073 }
00074
00075
00076
00077 delete [] chem;
00078 delete [] dChemdt;
00079 }
00080
00082
00083
00084
00086
00087 void CRK4Mover::FourthOrderStep(int nRHS, double *y, double *dydt)
00088 {
00089 int i;
00090 double *yTemp = new double[nRHS];
00091 double *dydtTemp1 = new double[nRHS];
00092 double *dydtTemp2 = new double[nRHS];
00093
00094 double halfStep = 0.5*m_dStepSize;
00095 double stepOverSix = m_dStepSize/6.0;
00096
00097 for(i = 0; i < nRHS; i++)
00098 {
00099 yTemp[i] = y[i] + halfStep*dydt[i];
00100 }
00101 ComputeDerivatives(yTemp,dydtTemp1);
00102
00103 for(i = 0; i < nRHS; i++)
00104 {
00105 yTemp[i] = y[i] + halfStep*dydtTemp1[i];
00106 }
00107 ComputeDerivatives(yTemp,dydtTemp2);
00108
00109 for(i = 0; i < nRHS; i++)
00110 {
00111 yTemp[i] = y[i] + m_dStepSize*dydtTemp2[i];
00112 dydtTemp2[i] += dydtTemp1[i];
00113 }
00114 ComputeDerivatives(yTemp,dydtTemp1);
00115
00116 for(i = 0; i < nRHS; i++)
00117 {
00118 y[i] = y[i] + stepOverSix*(dydt[i] + dydtTemp1[i] + 2.0*dydtTemp2[i]);
00119 }
00120
00121
00122 delete [] yTemp;
00123 delete [] dydtTemp1;
00124 delete [] dydtTemp2;
00125 }