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 #include "MonodomainMatrixBasedAssembler.hpp"
00030
00031
00032
00033
00035
00037
00038 template<unsigned DIM>
00039 c_matrix<double,1*(DIM+1),1*(DIM+1)> MonodomainRhsMatrixAssembler<DIM>::ComputeMatrixTerm(
00040 c_vector<double, DIM+1> &rPhi,
00041 c_matrix<double, DIM, DIM+1> &rGradPhi,
00042 ChastePoint<DIM> &rX,
00043 c_vector<double,1> &u,
00044 c_matrix<double,1,DIM> &rGradU ,
00045 Element<DIM,DIM>* pElement)
00046 {
00047 return outer_prod(rPhi, rPhi);
00048 }
00049
00050 template<unsigned DIM>
00051 c_vector<double,1*(DIM+1)> MonodomainRhsMatrixAssembler<DIM>::ComputeVectorTerm(
00052 c_vector<double, DIM+1> &rPhi,
00053 c_matrix<double, DIM, DIM+1> &rGradPhi,
00054 ChastePoint<DIM> &rX,
00055 c_vector<double,1> &u,
00056 c_matrix<double, 1, DIM> &rGradU ,
00057 Element<DIM,DIM>* pElement)
00058
00059 {
00060 #define COVERAGE_IGNORE
00061 NEVER_REACHED;
00062 return zero_vector<double>(DIM+1);
00063 #undef COVERAGE_IGNORE
00064 }
00065
00066 template<unsigned DIM>
00067 c_vector<double, DIM> MonodomainRhsMatrixAssembler<DIM>::ComputeVectorSurfaceTerm(
00068 const BoundaryElement<DIM-1,DIM> &rSurfaceElement,
00069 c_vector<double, DIM> &rPhi,
00070 ChastePoint<DIM> &rX )
00071 {
00072 #define COVERAGE_IGNORE
00073 NEVER_REACHED;
00074 return zero_vector<double>(DIM);
00075 #undef COVERAGE_IGNORE
00076 }
00077
00078
00079 template<unsigned DIM>
00080 MonodomainRhsMatrixAssembler<DIM>::MonodomainRhsMatrixAssembler(AbstractMesh<DIM,DIM>* pMesh)
00081 : AbstractLinearAssembler<DIM,DIM,1,false,MonodomainRhsMatrixAssembler<DIM> >()
00082 {
00083 this->mpMesh = pMesh;
00084
00085
00086 this->mpBoundaryConditions = new BoundaryConditionsContainer<DIM,DIM,1>;
00087 this->mpBoundaryConditions->DefineZeroNeumannOnMeshBoundary(pMesh);
00088
00089
00090 Vec temp_vec=DistributedVector::CreateVec();
00091 this->mpLinearSystem = new LinearSystem(temp_vec);
00092 VecDestroy(temp_vec);
00093 this->AssembleSystem(false,true);
00094 }
00095
00096 template<unsigned DIM>
00097 MonodomainRhsMatrixAssembler<DIM>::~MonodomainRhsMatrixAssembler()
00098 {
00099 delete this->mpBoundaryConditions;
00100 }
00101
00102 template<unsigned DIM>
00103 Mat* MonodomainRhsMatrixAssembler<DIM>::GetMatrix()
00104 {
00105 return &(this->mpLinearSystem->rGetLhsMatrix());
00106 }
00107
00108
00109
00110
00111
00113
00115
00116 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00117 MonodomainMatrixBasedAssembler<ELEMENT_DIM,SPACE_DIM>::MonodomainMatrixBasedAssembler(
00118 AbstractMesh<ELEMENT_DIM,SPACE_DIM>* pMesh,
00119 MonodomainPde<SPACE_DIM>* pPde,
00120 BoundaryConditionsContainer<ELEMENT_DIM, SPACE_DIM, 1>* pBcc,
00121 unsigned numQuadPoints)
00122 : MonodomainDg0Assembler<ELEMENT_DIM,SPACE_DIM>(pMesh, pPde, pBcc, numQuadPoints)
00123 {
00124
00125 mpMonodomainRhsMatrixAssembler = new MonodomainRhsMatrixAssembler<SPACE_DIM>(pMesh);
00126 this->mpMatrixForMatrixBasedRhsAssembly = mpMonodomainRhsMatrixAssembler->GetMatrix();
00127
00128
00129
00130 this->mUseMatrixBasedRhsAssembly = true;
00131 this->mVectorForMatrixBasedRhsAssembly = DistributedVector::CreateVec();
00132
00133
00134 pPde->SetCacheReplication(false);
00135 }
00136
00137 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00138 MonodomainMatrixBasedAssembler<ELEMENT_DIM,SPACE_DIM>::~MonodomainMatrixBasedAssembler()
00139 {
00140 delete mpMonodomainRhsMatrixAssembler;
00141 VecDestroy(this->mVectorForMatrixBasedRhsAssembly);
00142 }
00143
00144 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00145 void MonodomainMatrixBasedAssembler<ELEMENT_DIM,SPACE_DIM>::ConstructVectorForMatrixBasedRhsAssembly(Vec currentSolution)
00146 {
00147
00148 VecCopy(currentSolution, this->mVectorForMatrixBasedRhsAssembly);
00149
00150
00151 Vec force_term_at_nodes = DistributedVector::CreateVec();
00152 PetscInt lo, hi;
00153 VecGetOwnershipRange(force_term_at_nodes, &lo, &hi);
00154 double *p_force_term;
00155 VecGetArray(force_term_at_nodes, &p_force_term);
00156 for (int global_index=lo; global_index<hi; global_index++)
00157 {
00158 unsigned local_index = global_index - lo;
00159 const Node<SPACE_DIM>* p_node = this->mpMesh->GetNode(global_index);
00160 p_force_term[local_index] = this->mpMonodomainPde->ComputeNonlinearSourceTermAtNode(*p_node, 0.0);
00161 }
00162 VecRestoreArray(force_term_at_nodes, &p_force_term);
00163 VecAssemblyBegin(force_term_at_nodes);
00164 VecAssemblyEnd(force_term_at_nodes);
00165
00166 double one=1.0;
00167 double scaling= this->mpMonodomainPde->ComputeDuDtCoefficientFunction(ChastePoint<SPACE_DIM>())
00168 *this->mDtInverse;
00169
00170 #if (PETSC_VERSION_MINOR == 2) //Old API
00171
00172 VecAXPBY(&one, &scaling, force_term_at_nodes, this->mVectorForMatrixBasedRhsAssembly);
00173 #else
00174
00175 VecAXPBY(this->mVectorForMatrixBasedRhsAssembly,
00176 one,
00177 scaling,
00178 force_term_at_nodes);
00179 #endif
00180
00181 VecAssemblyBegin(this->mVectorForMatrixBasedRhsAssembly);
00182 VecAssemblyEnd(this->mVectorForMatrixBasedRhsAssembly);
00183 VecDestroy(force_term_at_nodes);
00184 }
00185
00187
00189
00190 template class MonodomainMatrixBasedAssembler<1,1>;
00191 template class MonodomainMatrixBasedAssembler<2,2>;
00192 template class MonodomainMatrixBasedAssembler<3,3>;
00193
00194 template class MonodomainRhsMatrixAssembler<1>;
00195 template class MonodomainRhsMatrixAssembler<2>;
00196 template class MonodomainRhsMatrixAssembler<3>;