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 _ABSTRACTASSEMBLER_HPP_
00029 #define _ABSTRACTASSEMBLER_HPP_
00030
00031 #include "LinearBasisFunction.hpp"
00032 #include "GaussianQuadratureRule.hpp"
00033 #include "BoundaryConditionsContainer.hpp"
00034 #include "LinearSystem.hpp"
00035 #include "GaussianQuadratureRule.hpp"
00036 #include "ReplicatableVector.hpp"
00037 #include "DistributedVector.hpp"
00038 #include "HeartEventHandler.hpp"
00039
00076 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00077 class AbstractAssembler
00078 {
00079 protected:
00080
00082 BoundaryConditionsContainer<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM> *mpBoundaryConditions;
00083
00084 #define COVERAGE_IGNORE
00085
00090 virtual void SetMatrixIsConst(bool matrixIsConstant=true)
00091 {
00092 }
00093 #undef COVERAGE_IGNORE
00094
00114 virtual c_matrix<double,PROBLEM_DIM*(ELEMENT_DIM+1),PROBLEM_DIM*(ELEMENT_DIM+1)> ComputeMatrixTerm(
00115 c_vector<double, ELEMENT_DIM+1>& rPhi,
00116 c_matrix<double, SPACE_DIM, ELEMENT_DIM+1>& rGradPhi,
00117 ChastePoint<SPACE_DIM>& rX,
00118 c_vector<double,PROBLEM_DIM>& rU,
00119 c_matrix<double, PROBLEM_DIM, SPACE_DIM>& rGradU,
00120 Element<ELEMENT_DIM,SPACE_DIM>* pElement)=0;
00121
00141 virtual c_vector<double,PROBLEM_DIM*(ELEMENT_DIM+1)> ComputeVectorTerm(
00142 c_vector<double, ELEMENT_DIM+1>& rPhi,
00143 c_matrix<double, SPACE_DIM, ELEMENT_DIM+1>& rGradPhi,
00144 ChastePoint<SPACE_DIM>& rX,
00145 c_vector<double,PROBLEM_DIM>& rU,
00146 c_matrix<double, PROBLEM_DIM, SPACE_DIM>& rGradU,
00147 Element<ELEMENT_DIM,SPACE_DIM>* pElement)=0;
00148
00162 virtual c_vector<double, PROBLEM_DIM*ELEMENT_DIM> ComputeVectorSurfaceTerm(
00163 const BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>& rSurfaceElement,
00164 c_vector<double, ELEMENT_DIM>& rPhi,
00165 ChastePoint<SPACE_DIM>& rX)=0;
00166
00187 virtual void AssembleOnElement(Element<ELEMENT_DIM,SPACE_DIM>& rElement,
00188 c_matrix<double, PROBLEM_DIM*(ELEMENT_DIM+1), PROBLEM_DIM*(ELEMENT_DIM+1) >& rAElem,
00189 c_vector<double, PROBLEM_DIM*(ELEMENT_DIM+1)>& rBElem,
00190 bool assembleVector,
00191 bool assembleMatrix)=0;
00192
00204 virtual void AssembleOnSurfaceElement(const BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>& rSurfaceElement,
00205 c_vector<double, PROBLEM_DIM*ELEMENT_DIM>& rBSurfElem)=0;
00206
00229 virtual void AssembleSystem(bool assembleVector, bool assembleMatrix,
00230 Vec currentSolutionOrGuess=NULL, double currentTime=0.0)=0;
00231
00236 virtual void PrepareForSolve()=0;
00237
00247 virtual void PrepareForAssembleSystem(Vec currentSolutionOrGuess, double currentTime)
00248 {}
00249
00257 virtual void FinaliseAssembleSystem(Vec currentSolutionOrGuess, double currentTime)
00258 {}
00259
00269 virtual void FinaliseLinearSystem(Vec currentSolutionOrGuess, double currentTime, bool assembleVector, bool assembleMatrix)
00270 {}
00271
00278 virtual void ApplyDirichletConditions(Vec currentSolutionOrGuess, bool applyToMatrix)=0;
00279
00283 virtual bool ProblemIsNonlinear()=0;
00284
00296 virtual Vec StaticSolve(Vec currentSolutionOrGuess=NULL,
00297 double currentTime=0.0,
00298 bool assembleMatrix=true)=0;
00299
00305 virtual void InitialiseForSolve(Vec initialGuess)=0;
00306
00307 public:
00311 virtual LinearSystem** GetLinearSystem()=0;
00312
00313 protected:
00317 virtual ReplicatableVector& rGetCurrentSolutionOrGuess()=0;
00318
00331 void ApplyNeummanBoundaryConditions();
00332
00333 public:
00334
00338 AbstractAssembler();
00339
00345 void SetBoundaryConditionsContainer(BoundaryConditionsContainer<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>* pBoundaryConditions);
00346
00350 virtual ~AbstractAssembler()
00351 {
00352 }
00353
00354
00355
00356
00362 virtual void ResetInterpolatedQuantities()
00363 {}
00364
00373 virtual void IncrementInterpolatedQuantities(double phiI, const Node<SPACE_DIM>* pNode)
00374 {}
00375
00376 };
00377
00378
00380
00382
00383
00384 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00385 void AbstractAssembler<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>::ApplyNeummanBoundaryConditions()
00386 {
00387 assert(mpBoundaryConditions!=NULL);
00388 HeartEventHandler::BeginEvent(HeartEventHandler::NEUMANN_BCS);
00389 if (mpBoundaryConditions->AnyNonZeroNeumannConditions())
00390 {
00391 typename BoundaryConditionsContainer<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::NeumannMapIterator
00392 neumann_iterator = mpBoundaryConditions->BeginNeumann();
00393 c_vector<double, PROBLEM_DIM*ELEMENT_DIM> b_surf_elem;
00394
00395
00396 while (neumann_iterator != mpBoundaryConditions->EndNeumann())
00397 {
00398 const BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>& surf_element = *(neumann_iterator->first);
00399 AssembleOnSurfaceElement(surf_element, b_surf_elem);
00400
00401 const size_t STENCIL_SIZE=PROBLEM_DIM*ELEMENT_DIM;
00402 unsigned p_indices[STENCIL_SIZE];
00403 surf_element.GetStiffnessMatrixGlobalIndices(PROBLEM_DIM, p_indices);
00404 (*(this->GetLinearSystem()))->AddRhsMultipleValues(p_indices, b_surf_elem);
00405 ++neumann_iterator;
00406 }
00407 }
00408 HeartEventHandler::EndEvent(HeartEventHandler::NEUMANN_BCS);
00409 }
00410
00411 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00412 AbstractAssembler<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>::AbstractAssembler()
00413 : mpBoundaryConditions(NULL)
00414 {
00415 }
00416
00417 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, unsigned PROBLEM_DIM>
00418 void AbstractAssembler<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>::SetBoundaryConditionsContainer(BoundaryConditionsContainer<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>* pBoundaryConditions)
00419 {
00420 mpBoundaryConditions = pBoundaryConditions;
00421 }
00422
00423
00424 #endif //_ABSTRACTASSEMBLER_HPP_