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 #include "AbstractTimeAdaptivityController.hpp"
00037
00038
00045 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00046 class AbstractDynamicLinearPdeSolver : public AbstractLinearPdeSolver<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>
00047 {
00048 friend class TestSimpleLinearParabolicSolver;
00049
00050 protected:
00052 double mTstart;
00053
00055 double mTend;
00056
00058 bool mTimesSet;
00059
00061 Vec mInitialCondition;
00062
00064 bool mMatrixIsAssembled;
00065
00068 bool mMatrixIsConstant;
00069
00073 double mIdealTimeStep;
00074
00076 double mLastWorkingTimeStep;
00077
00079 AbstractTimeAdaptivityController* mpTimeAdaptivityController;
00080
00081 public:
00086 AbstractDynamicLinearPdeSolver(AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>* pMesh);
00087
00093 void SetTimes(double tStart, double tEnd);
00094
00098 void SetTimeStep(double dt);
00099
00104 void SetInitialCondition(Vec initialCondition);
00105
00107 Vec Solve();
00108
00110 void SetMatrixIsNotAssembled()
00111 {
00112 mMatrixIsAssembled = false;
00113 }
00114
00118 void SetTimeAdaptivityController(AbstractTimeAdaptivityController* pTimeAdaptivityController)
00119 {
00120 assert(pTimeAdaptivityController != NULL);
00121 assert(mpTimeAdaptivityController == NULL);
00122 mpTimeAdaptivityController = pTimeAdaptivityController;
00123 }
00124 };
00125
00126
00127 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00128 AbstractDynamicLinearPdeSolver<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>::AbstractDynamicLinearPdeSolver(AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>* pMesh)
00129 : AbstractLinearPdeSolver<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>(pMesh),
00130 mTimesSet(false),
00131 mInitialCondition(NULL),
00132 mMatrixIsAssembled(false),
00133 mMatrixIsConstant(false),
00134 mIdealTimeStep(-1.0),
00135 mLastWorkingTimeStep(-1),
00136 mpTimeAdaptivityController(NULL)
00137 {
00138 }
00139
00140 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00141 void AbstractDynamicLinearPdeSolver<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>::SetTimes(double tStart, double tEnd)
00142 {
00143 mTstart = tStart;
00144 mTend = tEnd;
00145
00146 if (mTstart >= mTend)
00147 {
00148 EXCEPTION("Starting time has to less than ending time");
00149 }
00150
00151 mTimesSet = true;
00152 }
00153
00154 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00155 void AbstractDynamicLinearPdeSolver<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>::SetTimeStep(double dt)
00156 {
00157 if (dt <= 0)
00158 {
00159 EXCEPTION("Time step has to be greater than zero");
00160 }
00161
00162 mIdealTimeStep = dt;
00163 }
00164
00165 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00166 void AbstractDynamicLinearPdeSolver<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>::SetInitialCondition(Vec initialCondition)
00167 {
00168 assert(initialCondition!=NULL);
00169 mInitialCondition = initialCondition;
00170 }
00171
00172 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00173 Vec AbstractDynamicLinearPdeSolver<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>::Solve()
00174 {
00175 assert(mTimesSet);
00176 assert(mIdealTimeStep > 0.0 || mpTimeAdaptivityController);
00177 assert(mInitialCondition != NULL);
00178
00179 this->InitialiseForSolve(mInitialCondition);
00180
00181 if(mIdealTimeStep < 0)
00182 {
00183 mIdealTimeStep = mpTimeAdaptivityController->GetNextTimeStep(mTstart, mInitialCondition);
00184 }
00185
00186
00187
00188
00189
00190
00191 TimeStepper stepper(mTstart, mTend, mIdealTimeStep, mMatrixIsConstant);
00192
00193 Vec current_solution = mInitialCondition;
00194 Vec next_solution;
00195
00196 while ( !stepper.IsTimeAtEnd() )
00197 {
00198 bool timestep_changed = false;
00199
00200 PdeSimulationTime::SetTime(stepper.GetTime());
00201
00203
00205 double new_dt;
00206 if (mpTimeAdaptivityController)
00207 {
00208
00209 mIdealTimeStep = mpTimeAdaptivityController->GetNextTimeStep(stepper.GetTime(), current_solution);
00210
00211 stepper.ResetTimeStep(mIdealTimeStep);
00212
00213
00214 new_dt = stepper.GetNextTimeStep();
00215
00216 timestep_changed = (fabs(mLastWorkingTimeStep-new_dt) > 1e-8);
00217 }
00218 else
00219 {
00220 new_dt = stepper.GetNextTimeStep();
00221 }
00222
00223
00224
00225 mLastWorkingTimeStep = new_dt;
00226 PdeSimulationTime::SetPdeTimeStep( new_dt );
00227
00229
00231
00232 this->PrepareForSetupLinearSystem(current_solution);
00233
00234 bool compute_matrix = (!mMatrixIsConstant || !mMatrixIsAssembled || timestep_changed);
00235
00236 this->SetupLinearSystem(current_solution, compute_matrix);
00237
00238 this->FinaliseLinearSystem(current_solution);
00239
00240 if (compute_matrix)
00241 {
00242 this->mpLinearSystem->ResetKspSolver();
00243 }
00244
00245 next_solution = this->mpLinearSystem->Solve(current_solution);
00246
00247 if (mMatrixIsConstant)
00248 {
00249 mMatrixIsAssembled = true;
00250 }
00251
00252 this->FollowingSolveLinearSystem(next_solution);
00253
00254 stepper.AdvanceOneTimeStep();
00255
00256
00257 if (current_solution != mInitialCondition)
00258 {
00259 HeartEventHandler::BeginEvent(HeartEventHandler::COMMUNICATION);
00260 VecDestroy(current_solution);
00261 HeartEventHandler::EndEvent(HeartEventHandler::COMMUNICATION);
00262 }
00263 current_solution = next_solution;
00264 }
00265
00266 return current_solution;
00267 }
00268
00269
00270 #endif