00001
00002
00004
00005 #include "SynchronizedRungeKuttaMover.h"
00006
00008
00010
00011 CSynchronizedRungeKuttaMover::CSynchronizedRungeKuttaMover(double frequency, double stepSize, double eps)
00012 :CQualityControlRungeKuttaMover(frequency,stepSize,eps)
00013 {
00014 m_bSyncFlag = false;
00015 }
00016
00017 CSynchronizedRungeKuttaMover::~CSynchronizedRungeKuttaMover()
00018 {
00019
00020 }
00021
00022 void CSynchronizedRungeKuttaMover::Move(double xInitial, double xFinal, ReactionNetwork *pReactionNetwork)
00023 {
00024 int i;
00025
00026 double xInterval = xFinal-xInitial;
00027 if(this->MoveTimeIsZero(xInterval)) {return;}
00028 if(m_dInitialStepSize > xInterval) {m_dInitialStepSize = xInterval;}
00029
00030 this->SetMinStepSize(xInterval);
00031 this->SetMaxStepSize(0.0);
00032 m_iTotalStepsTaken = 0;
00033
00034
00035 m_pReactionNetwork = pReactionNetwork;
00036 m_dTime = xInitial;
00037 m_iCount = (int) xInitial;
00038 m_dStepSize = m_dLastStep = m_dNextStep = m_dInitialStepSize;
00039
00040 double nextTime = m_dTime;
00041 int nChem = m_pReactionNetwork->GetNumberOfChemicals();
00042 double *chem = new double[nChem];
00043 double *dChemdt = new double[nChem];
00044 m_pdScale = new double[nChem];
00045
00046
00047 for(i = 0; i < nChem; i++)
00048 {
00049 chem[i] = m_pReactionNetwork->GetChemical(i)->GetAmount();
00050 }
00051
00052
00053
00054 int stepCounter = 0;
00055
00056 while(m_dTime < xFinal)
00057 {
00058
00059 while(m_dTime < nextTime)
00060 {
00061 if((m_bSyncFlag == false) || (m_vdSteps.size() == 0))
00062 {
00063
00064 ComputeDerivatives(chem,dChemdt);
00065
00066
00067
00068 for(i = 0; i < nChem; i++)
00069 {
00070 m_pdScale[i] = __max(1.0,fabs(chem[i]) + fabs(m_dStepSize*dChemdt[i]) + m_scdTINY);
00071 }
00072
00073
00074 if( ((m_dTime + m_dNextStep) - nextTime) > 0.0 )
00075 {
00076 m_dNextStep = nextTime-m_dTime;
00077 }
00078
00079
00080 Stepper(nChem,chem,dChemdt);
00081
00082 m_vdSteps.push_back(m_dLastStep);
00083
00084
00085 if(m_dLastStep < this->GetMinStepSize()) {this->SetMinStepSize(m_dLastStep);}
00086 if(m_dLastStep > this->GetMaxStepSize()) {this->SetMaxStepSize(m_dLastStep);}
00087 this->IncrementTotalSteps();
00088 }
00089 else
00090 {
00091 ComputeDerivatives(chem,dChemdt);
00092 m_dStepSize = m_vdSteps[stepCounter];
00093 stepCounter++;
00094 FourthOrderStep(nChem,chem,dChemdt);
00095 m_dTime += m_dStepSize;
00096 }
00097 }
00098
00099
00100 for(int i = 0; i < nChem; i++)
00101 {
00102 m_pReactionNetwork->GetChemical(i)->SetAmount(chem[i]);
00103 }
00104
00105 m_iCount++;
00106 Notify();
00107 nextTime += 1.0;
00108
00109 }
00110
00111 delete [] chem;
00112 delete [] dChemdt;
00113 delete [] m_pdScale;
00114
00115
00116
00117 m_bSyncFlag = true;
00118 }