00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef ABSTRACTDYNAMICLINEARPDESOLVER_HPP_
00031 #define ABSTRACTDYNAMICLINEARPDESOLVER_HPP_
00032
00033 #include "TimeStepper.hpp"
00034 #include "AbstractLinearPdeSolver.hpp"
00035 #include "PdeSimulationTime.hpp"
00036
00037
00044 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00045 class AbstractDynamicLinearPdeSolver : public AbstractLinearPdeSolver<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>
00046 {
00047 protected:
00049 double mTstart;
00050
00052 double mTend;
00053
00055 double mDt;
00056
00058 double mDtInverse;
00059
00061 bool mTimesSet;
00062
00064 Vec mInitialCondition;
00065
00067 bool mMatrixIsAssembled;
00068
00071 bool mMatrixIsConstant;
00072
00073
00074 public:
00080 AbstractDynamicLinearPdeSolver(AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>* pMesh);
00081
00089 void SetTimes(double tStart, double tEnd, double dt);
00090
00096 void SetInitialCondition(Vec initialCondition);
00097
00099 Vec Solve();
00100 };
00101
00102
00103 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00104 AbstractDynamicLinearPdeSolver<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>::AbstractDynamicLinearPdeSolver(AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>* pMesh)
00105 : AbstractLinearPdeSolver<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>(pMesh),
00106 mTimesSet(false),
00107 mInitialCondition(NULL),
00108 mMatrixIsAssembled(false),
00109 mMatrixIsConstant(false)
00110
00111 {
00112 }
00113
00114 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00115 void AbstractDynamicLinearPdeSolver<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>::SetTimes(double tStart, double tEnd, double dt)
00116 {
00117 mTstart = tStart;
00118 mTend = tEnd;
00119 mDt = dt;
00120
00121 if (mTstart >= mTend)
00122 {
00123 EXCEPTION("Starting time has to less than ending time");
00124 }
00125
00126 if (mDt <= 0)
00127 {
00128 EXCEPTION("Time step has to be greater than zero");
00129 }
00130
00131 mDtInverse = 1/dt;
00132 mTimesSet = true;
00133 }
00134
00135 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00136 void AbstractDynamicLinearPdeSolver<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>::SetInitialCondition(Vec initialCondition)
00137 {
00138 assert(initialCondition!=NULL);
00139 mInitialCondition = initialCondition;
00140 }
00141
00142 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00143 Vec AbstractDynamicLinearPdeSolver<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>::Solve()
00144 {
00145 assert(mTimesSet);
00146 assert(mInitialCondition != NULL);
00147
00148 this->InitialiseForSolve(mInitialCondition);
00149
00150 TimeStepper stepper(mTstart, mTend, mDt, mMatrixIsConstant);
00151
00152 Vec current_solution = mInitialCondition;
00153 Vec next_solution;
00154
00155 while ( !stepper.IsTimeAtEnd() )
00156 {
00157 mDt = stepper.GetNextTimeStep();
00158 mDtInverse = 1.0/mDt;
00159
00160 PdeSimulationTime::SetTime(stepper.GetTime());
00161
00162 this->PrepareForSetupLinearSystem(current_solution);
00163
00164 bool compute_matrix = (!mMatrixIsConstant || !mMatrixIsAssembled);
00165 this->SetupLinearSystem(current_solution, compute_matrix);
00166
00167 this->FinaliseLinearSystem(current_solution);
00168
00169 next_solution = this->mpLinearSystem->Solve(current_solution);
00170
00171 if (mMatrixIsConstant)
00172 {
00173 mMatrixIsAssembled = true;
00174 }
00175
00176 stepper.AdvanceOneTimeStep();
00177
00178
00179 if (current_solution != mInitialCondition)
00180 {
00181 HeartEventHandler::BeginEvent(HeartEventHandler::COMMUNICATION);
00182 VecDestroy(current_solution);
00183 HeartEventHandler::EndEvent(HeartEventHandler::COMMUNICATION);
00184 }
00185 current_solution = next_solution;
00186 }
00187 return current_solution;
00188 }
00189
00190
00191 #endif