AbstractDynamicAssemblerMixin.hpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2009
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
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         // as bypassing AssembleSystem, need to make sure we call 
00074         // Prepare and Finalize
00075         this->PrepareForAssembleSystem(currentSolution, time);
00076 
00077         HeartEventHandler::BeginEvent(HeartEventHandler::ASSEMBLE_RHS);
00078 
00079         (*(this->GetLinearSystem()))->ZeroRhsVector();
00080 
00081         // construct z 
00082         ConstructVectorForMatrixBasedRhsAssembly(currentSolution);
00083         
00084         // b = Bz
00085         MatMult(*mpMatrixForMatrixBasedRhsAssembly, mVectorForMatrixBasedRhsAssembly, (*(this->GetLinearSystem()))->rGetRhsVector()); 
00086 
00087         // apply boundary conditions
00088         this->ApplyNeummanBoundaryConditions();        
00089         (*(this->GetLinearSystem()))->AssembleRhsVector();
00090         
00091         this->ApplyDirichletConditions(currentSolution, false);
00092 
00093         // as bypassing AssembleSystem, need to make sure we call 
00094         // Prepare and Finalise
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             // NOTE: even if mUseMatrixBasedRhsAssembly==true,
00195             // the RHS is assembled without using matrix-based assembly
00196             // in the first timestep (when the LHS matrix is set up) - no
00197             // easy way around this
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             // Avoid memory leaks
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_

Generated on Wed Mar 18 12:51:56 2009 for Chaste by  doxygen 1.5.5