00001 // DifferentialEquationMover.cpp: implementation of the DifferentialEquationMover class. 00002 // 00004 00005 #include "DifferentialEquationMover.h" 00006 00008 // Construction/Destruction 00010 00011 CDifferentialEquationMover::CDifferentialEquationMover() 00012 { 00013 00014 } 00015 00016 CDifferentialEquationMover::CDifferentialEquationMover(double frequency, double stepSize) 00017 :CReactionMover(0,frequency) 00018 { 00019 this->m_dStepSize = stepSize; 00020 this->m_dDefaultStepSize = stepSize; 00021 } 00022 00023 CDifferentialEquationMover::~CDifferentialEquationMover() 00024 { 00025 00026 } 00027 00028 void CDifferentialEquationMover::SetStepSize(double newSize) 00029 { 00030 this->m_dStepSize = newSize; 00031 } 00032 00033 void CDifferentialEquationMover::ResetStepSize() 00034 { 00035 this->m_dStepSize = m_dDefaultStepSize; 00036 } 00037 00038 void CDifferentialEquationMover::ComputeDerivatives(double *chem, double *dChemdt) 00039 { 00040 int cNum; 00041 // Set dChemdt = 0.0 00042 // Set chemicals to values in concentration array 00043 00044 int nChem = m_pReactionNetwork->GetNumberOfChemicals(); 00045 int nReac = m_pReactionNetwork->GetNumberOfReactions(); 00046 00047 00048 for (cNum = 0; cNum < nChem; cNum++) 00049 { 00050 dChemdt[cNum] = 0.0; 00051 Chemical* chemical = m_pReactionNetwork->GetChemicals()->at(cNum); 00052 //Chemical *chemical = m_pReactionNetwork->GetChemical(cNum); 00053 chemical->SetAmount(chem[cNum]); 00054 } 00055 00056 // Give contribution to dChemdt from each reaction 00057 std::vector<double> *reactionRates = m_pReactionNetwork->GetReactionRates(); 00058 std::vector<Reaction *> *reactions = m_pReactionNetwork->GetReactions(); 00059 00060 for (int rNum = 0; rNum < nReac; rNum++) 00061 { 00062 std::vector<Chemical *> *localChemicals = reactions->at(rNum)->GetChemicals(); 00063 double reactionRate = reactionRates->at(rNum); 00064 int nLC = localChemicals->size(); 00065 for (int lcNum = 0; lcNum < nLC; lcNum++) 00066 { 00067 cNum = localChemicals->at(lcNum)->GetChemicalNumber(); 00068 dChemdt[cNum] += (reactions->at(rNum)->GetNumberChangedByReaction(lcNum))*reactionRate; 00069 } 00070 } 00071 return; 00072 } 00073 00074 void CDifferentialEquationMover::ComputeJacobian(double *chem, double **dRHSdChem) 00075 { 00076 int i,j; 00077 int nChem = m_pReactionNetwork->GetNumberOfChemicals(); 00078 int nReac = m_pReactionNetwork->GetNumberOfReactions(); 00079 00080 // zero out the jacobian array 00081 for(i = 0; i < nChem; i++) 00082 { 00083 for(j = 0; j < nChem; j++) 00084 { 00085 dRHSdChem[i][j] = 0.0; 00086 } 00087 } 00088 // make sure chemicals are current 00089 for (int cNum = 0; cNum < nChem; cNum++) 00090 { 00091 Chemical* chemical = m_pReactionNetwork->GetChemicals()->at(cNum); 00092 chemical->SetAmount(chem[cNum]); 00093 } 00094 00095 std::vector<Reaction::JElement *> *jelements; 00096 std::vector<Reaction *> *reactions = m_pReactionNetwork->GetReactions(); 00097 00098 for (int rNum = 0; rNum < nReac; rNum++) 00099 { 00100 std::vector<Chemical *> *localChemicals = reactions->at(rNum)->GetChemicals(); 00101 int nLC = localChemicals->size(); 00102 for (int lcNum = 0; lcNum < nLC; lcNum++) 00103 { 00104 int nChg = reactions->at(rNum)->GetNumberChangedByReaction(lcNum); 00105 if(nChg != 0) 00106 { 00107 double sign = fabs((double) nChg)/nChg; 00108 int cNum = localChemicals->at(lcNum)->GetChemicalNumber(); 00109 jelements = reactions->at(rNum)->GetChemicalJacobian(); 00110 for(int nJac = 0; nJac < jelements->size(); nJac++) 00111 { 00112 int wrt = jelements->at(nJac)->GetWithRespectTo(); 00113 double jvalue = jelements->at(nJac)->GetJValue(); 00114 dRHSdChem[cNum][wrt] += sign*jvalue; 00115 } 00116 } 00117 00118 } 00119 } 00120 }