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 #ifndef _ABSTRACTDYNAMICASSEMBLERMIXIN_HPP_
00029 #define _ABSTRACTDYNAMICASSEMBLERMIXIN_HPP_
00030
00031 #include <vector>
00032 #include <petscvec.h>
00033
00034 #include "AbstractAssembler.hpp"
00035 #include "TimeStepper.hpp"
00036 #include "PdeSimulationTime.hpp"
00037
00038 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00039 class AbstractDynamicAssemblerMixin : virtual public AbstractAssembler<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>
00040 {
00041 protected:
00042 double mTstart;
00043 double mTend;
00044 double mDt, mDtInverse;
00045 bool mTimesSet;
00046
00047 Vec mInitialCondition;
00048
00050 bool mMatrixIsAssembled;
00051
00053 bool mMatrixIsConstant;
00054
00056 bool mUseMatrixBasedRhsAssembly;
00058 Mat* mpMatrixForMatrixBasedRhsAssembly;
00060 Vec mVectorForMatrixBasedRhsAssembly;
00061
00069 void DoMatrixBasedRhsAssembly(Vec currentSolution, double time)
00070 {
00071 assert(mpMatrixForMatrixBasedRhsAssembly!=NULL);
00072
00073
00074
00075 this->PrepareForAssembleSystem(currentSolution, time);
00076
00077 HeartEventHandler::BeginEvent(HeartEventHandler::ASSEMBLE_RHS);
00078
00079 (*(this->GetLinearSystem()))->ZeroRhsVector();
00080
00081
00082 ConstructVectorForMatrixBasedRhsAssembly(currentSolution);
00083
00084
00085 MatMult(*mpMatrixForMatrixBasedRhsAssembly, mVectorForMatrixBasedRhsAssembly, (*(this->GetLinearSystem()))->rGetRhsVector());
00086
00087
00088 this->ApplyNeummanBoundaryConditions();
00089 (*(this->GetLinearSystem()))->AssembleRhsVector();
00090
00091 this->ApplyDirichletConditions(currentSolution, false);
00092
00093
00094
00095 this->FinaliseAssembleSystem(currentSolution, time);
00096 (*(this->GetLinearSystem()))->AssembleRhsVector();
00097
00098 HeartEventHandler::EndEvent(HeartEventHandler::ASSEMBLE_RHS);
00099 }
00100
00101 public:
00106 AbstractDynamicAssemblerMixin()
00107 {
00108 mTimesSet = false;
00109 mInitialCondition = NULL;
00110 mMatrixIsAssembled = false;
00111 mMatrixIsConstant = false;
00112
00113 mUseMatrixBasedRhsAssembly = false;
00114 mpMatrixForMatrixBasedRhsAssembly = NULL;
00115 }
00116
00120 void SetTimes(double Tstart, double Tend, double dt)
00121 {
00122 mTstart = Tstart;
00123 mTend = Tend;
00124 mDt = dt;
00125 mDtInverse = 1/dt;
00126
00127 if (mTstart >= mTend)
00128 {
00129 EXCEPTION("Starting time has to less than ending time");
00130 }
00131 if (mDt <= 0)
00132 {
00133 EXCEPTION("Time step has to be greater than zero");
00134 }
00135
00136 mTimesSet = true;
00137 }
00138
00142 void SetInitialCondition(Vec initialCondition)
00143 {
00144 assert(initialCondition!=NULL);
00145 mInitialCondition = initialCondition;
00146 }
00147
00151 void SetMatrixIsConstant(bool matrixIsConstant = true)
00152 {
00153 mMatrixIsConstant = matrixIsConstant;
00154 this->SetMatrixIsConst(mMatrixIsConstant);
00155 }
00156
00157 void SetMatrixIsNotAssembled()
00158 {
00159 mMatrixIsAssembled = false;
00160 }
00161
00173 Vec Solve(Vec currentSolutionOrGuess=NULL, double currentTime=0.0)
00174 {
00175 assert(mTimesSet);
00176 assert(mInitialCondition != NULL);
00177
00178 this->PrepareForSolve();
00179 this->InitialiseForSolve(mInitialCondition);
00180
00181 TimeStepper stepper(mTstart, mTend, mDt);
00182
00183 Vec current_solution = mInitialCondition;
00184 Vec next_solution;
00185
00186 while ( !stepper.IsTimeAtEnd() )
00187 {
00189 mDt = stepper.GetNextTimeStep();
00190 mDtInverse = 1.0/mDt;
00191
00192 PdeSimulationTime::SetTime(stepper.GetTime());
00193
00194
00195
00196
00197
00198 if(!mUseMatrixBasedRhsAssembly || !mMatrixIsAssembled)
00199 {
00200 next_solution = this->StaticSolve(current_solution, stepper.GetTime(), !mMatrixIsAssembled);
00201 }
00202 else
00203 {
00204 DoMatrixBasedRhsAssembly(current_solution, stepper.GetTime());
00205 next_solution = (*(this->GetLinearSystem()))->Solve(current_solution);
00206 }
00207
00208 mMatrixIsAssembled = true;
00209 stepper.AdvanceOneTimeStep();
00210
00211
00212 if (current_solution != mInitialCondition)
00213 {
00214 VecDestroy(current_solution);
00215 }
00216 current_solution = next_solution;
00217 }
00218 return current_solution;
00219 }
00220
00225 virtual void ConstructVectorForMatrixBasedRhsAssembly(Vec currentSolution)
00226 {
00227 #define COVERAGE_IGNORE
00228 EXCEPTION("mUseMatrixBasedRhsAssembly=true but ConstructVectorForMatrixBasedRhsAssembly() has not been overloaded");
00229 #undef COVERAGE_IGNORE
00230 }
00231 };
00232
00233 #endif //_ABSTRACTDYNAMICASSEMBLERMIXIN_HPP_