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
00086 virtual void SetMatrixIsConst(bool matrixIsConstant = true)
00087 {
00088 }
00089 #undef COVERAGE_IGNORE
00090
00091
00111 virtual c_matrix<double,PROBLEM_DIM*(ELEMENT_DIM+1),PROBLEM_DIM*(ELEMENT_DIM+1)> ComputeMatrixTerm(
00112 c_vector<double, ELEMENT_DIM+1> &rPhi,
00113 c_matrix<double, ELEMENT_DIM, ELEMENT_DIM+1> &rGradPhi,
00114 ChastePoint<SPACE_DIM> &rX,
00115 c_vector<double,PROBLEM_DIM> &u,
00116 c_matrix<double, PROBLEM_DIM, SPACE_DIM> &rGradU,
00117 Element<ELEMENT_DIM,SPACE_DIM>* pElement)=0;
00118
00119
00138 virtual c_vector<double,PROBLEM_DIM*(ELEMENT_DIM+1)> ComputeVectorTerm(
00139 c_vector<double, ELEMENT_DIM+1> &rPhi,
00140 c_matrix<double, ELEMENT_DIM, ELEMENT_DIM+1> &rGradPhi,
00141 ChastePoint<SPACE_DIM> &rX,
00142 c_vector<double,PROBLEM_DIM> &u,
00143 c_matrix<double, PROBLEM_DIM, SPACE_DIM> &rGradU,
00144 Element<ELEMENT_DIM,SPACE_DIM>* pElement)=0;
00145
00146
00147
00161 virtual c_vector<double, PROBLEM_DIM*ELEMENT_DIM> ComputeVectorSurfaceTerm(
00162 const BoundaryElement<ELEMENT_DIM-1,SPACE_DIM> &rSurfaceElement,
00163 c_vector<double, ELEMENT_DIM> &rPhi,
00164 ChastePoint<SPACE_DIM> &rX)=0;
00165
00166
00190 virtual void AssembleOnElement( Element<ELEMENT_DIM,SPACE_DIM> &rElement,
00191 c_matrix<double, PROBLEM_DIM*(ELEMENT_DIM+1), PROBLEM_DIM*(ELEMENT_DIM+1) > &rAElem,
00192 c_vector<double, PROBLEM_DIM*(ELEMENT_DIM+1)> &rBElem,
00193 bool assembleVector,
00194 bool assembleMatrix)=0;
00195
00196
00197
00209 virtual void AssembleOnSurfaceElement(const BoundaryElement<ELEMENT_DIM-1,SPACE_DIM> &rSurfaceElement,
00210 c_vector<double, PROBLEM_DIM*ELEMENT_DIM> &rBSurfElem)=0;
00211
00212
00213
00214 virtual void AssembleSystem(bool assembleVector, bool assembleMatrix,
00215 Vec currentSolutionOrGuess=NULL, double currentTime=0.0)=0;
00216
00217
00222 virtual void PrepareForSolve()=0;
00223
00224
00231 virtual void PrepareForAssembleSystem(Vec currentSolutionOrGuess, double currentTime)
00232 {}
00233
00238 virtual void FinaliseAssembleSystem(Vec currentSolutionOrGuess, double currentTime)
00239 {}
00240
00245 virtual void FinaliseLinearSystem(Vec currentSolutionOrGuess, double currentTime, bool assembleVector, bool assembleMatrix)
00246 {}
00247
00248
00252 virtual void ApplyDirichletConditions(Vec currentSolutionOrGuess, bool applyToMatrix)=0;
00253
00257 virtual bool ProblemIsNonlinear() =0;
00258
00259
00271 virtual Vec StaticSolve(Vec currentSolutionOrGuess=NULL,
00272 double currentTime=0.0,
00273 bool assembleMatrix=true)=0;
00274
00278 virtual void InitialiseForSolve(Vec initialGuess)=0;
00279
00283 virtual LinearSystem** GetLinearSystem()=0;
00284 virtual ReplicatableVector& rGetCurrentSolutionOrGuess()=0;
00285
00286
00299 void ApplyNeummanBoundaryConditions()
00300 {
00301 assert(mpBoundaryConditions!=NULL);
00302 HeartEventHandler::BeginEvent(HeartEventHandler::NEUMANN_BCS);
00303 if (mpBoundaryConditions->AnyNonZeroNeumannConditions())
00304 {
00305 typename BoundaryConditionsContainer<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>::NeumannMapIterator
00306 neumann_iterator = mpBoundaryConditions->BeginNeumann();
00307 c_vector<double, PROBLEM_DIM*ELEMENT_DIM> b_surf_elem;
00308
00309
00310 while (neumann_iterator != mpBoundaryConditions->EndNeumann())
00311 {
00312 const BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>& surf_element = *(neumann_iterator->first);
00313 AssembleOnSurfaceElement(surf_element, b_surf_elem);
00314
00315 const size_t STENCIL_SIZE=PROBLEM_DIM*ELEMENT_DIM;
00316 unsigned p_indices[STENCIL_SIZE];
00317 surf_element.GetStiffnessMatrixGlobalIndices(PROBLEM_DIM, p_indices);
00318 (*(this->GetLinearSystem()))->AddRhsMultipleValues(p_indices, b_surf_elem);
00319 ++neumann_iterator;
00320 }
00321 }
00322 HeartEventHandler::EndEvent(HeartEventHandler::NEUMANN_BCS);
00323 }
00324
00325 public:
00326
00330 AbstractAssembler()
00331 {
00332 mpBoundaryConditions = NULL;
00333 }
00334
00335
00339 void SetBoundaryConditionsContainer(BoundaryConditionsContainer<ELEMENT_DIM,SPACE_DIM,PROBLEM_DIM>* pBoundaryConditions)
00340 {
00341 mpBoundaryConditions = pBoundaryConditions;
00342 }
00343
00344
00348 virtual ~AbstractAssembler()
00349 {
00350 }
00351
00352
00353
00354
00355
00361 virtual void ResetInterpolatedQuantities( void )
00362 {}
00363
00369 virtual void IncrementInterpolatedQuantities(double phi_i, const Node<SPACE_DIM> *pNode)
00370 {}
00371
00372
00373 };
00374
00375 #endif //_ABSTRACTASSEMBLER_HPP_