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
00030
00031
00032 #include "BidomainMatrixBasedAssembler.hpp"
00033
00034
00035
00036
00038
00040
00041 template<unsigned DIM>
00042 c_matrix<double,2*(DIM+1),2*(DIM+1)> BidomainRhsMatrixAssembler<DIM>::ComputeMatrixTerm(
00043 c_vector<double, DIM+1> &rPhi,
00044 c_matrix<double, DIM, DIM+1> &rGradPhi,
00045 ChastePoint<DIM> &rX,
00046 c_vector<double,2> &rU,
00047 c_matrix<double,2,DIM> &rGradU ,
00048 Element<DIM,DIM>* pElement)
00049 {
00050 c_matrix<double, DIM+1, DIM+1> basis_outer_prod =
00051 outer_prod(rPhi, rPhi);
00052
00053 c_matrix<double,2*(DIM+1),2*(DIM+1)> ret = zero_matrix<double>(2*(DIM+1),2*(DIM+1));
00054
00055
00056 matrix_slice<c_matrix<double, 2*DIM+2, 2*DIM+2> >
00057 slice00(ret, slice (0, 2, DIM+1), slice (0, 2, DIM+1));
00058 slice00 = basis_outer_prod;
00059
00060
00061
00062
00063
00064 matrix_slice<c_matrix<double, 2*DIM+2, 2*DIM+2> >
00065 slice11(ret, slice (1, 2, DIM+1), slice (1, 2, DIM+1));
00066 slice11 = basis_outer_prod;
00067
00068 return ret;
00069 }
00070
00071 template<unsigned DIM>
00072 c_vector<double,2*(DIM+1)> BidomainRhsMatrixAssembler<DIM>::ComputeVectorTerm(
00073 c_vector<double, DIM+1> &rPhi,
00074 c_matrix<double, DIM, DIM+1> &rGradPhi,
00075 ChastePoint<DIM> &rX,
00076 c_vector<double,2> &rU,
00077 c_matrix<double, 2, DIM> &rGradU ,
00078 Element<DIM,DIM>* pElement)
00079
00080 {
00081 #define COVERAGE_IGNORE
00082 NEVER_REACHED;
00083 return zero_vector<double>(2*(DIM+1));
00084 #undef COVERAGE_IGNORE
00085 }
00086
00087
00088 template<unsigned DIM>
00089 c_vector<double, 2*DIM> BidomainRhsMatrixAssembler<DIM>::ComputeVectorSurfaceTerm(
00090 const BoundaryElement<DIM-1,DIM> &rSurfaceElement,
00091 c_vector<double, DIM> &rPhi,
00092 ChastePoint<DIM> &rX )
00093 {
00094 #define COVERAGE_IGNORE
00095 NEVER_REACHED;
00096 return zero_vector<double>(2*DIM);
00097 #undef COVERAGE_IGNORE
00098 }
00099
00100
00101 template<unsigned DIM>
00102 BidomainRhsMatrixAssembler<DIM>::BidomainRhsMatrixAssembler(AbstractTetrahedralMesh<DIM,DIM>* pMesh)
00103 : AbstractLinearAssembler<DIM,DIM,2,false,BidomainRhsMatrixAssembler<DIM> >()
00104 {
00105 this->mpMesh = pMesh;
00106
00107
00108 this->mpBoundaryConditions = new BoundaryConditionsContainer<DIM,DIM,2>;
00109 this->mpBoundaryConditions->DefineZeroNeumannOnMeshBoundary(pMesh);
00110
00111
00112 Vec template_vec = this->mpMesh->GetDistributedVectorFactory()->CreateVec(2);
00113 this->mpLinearSystem = new LinearSystem(template_vec);
00114 VecDestroy(template_vec);
00115
00116
00117 this->AssembleSystem(false,true);
00118 }
00119
00120 template<unsigned DIM>
00121 BidomainRhsMatrixAssembler<DIM>::~BidomainRhsMatrixAssembler()
00122 {
00123 delete this->mpBoundaryConditions;
00124 }
00125
00126 template<unsigned DIM>
00127 Mat* BidomainRhsMatrixAssembler<DIM>::GetMatrix()
00128 {
00129 return &(this->mpLinearSystem->rGetLhsMatrix());
00130 }
00131
00132
00133
00134
00136
00138
00139 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00140 BidomainMatrixBasedAssembler<ELEMENT_DIM,SPACE_DIM>::BidomainMatrixBasedAssembler(
00141 AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>* pMesh,
00142 BidomainPde<SPACE_DIM>* pPde,
00143 BoundaryConditionsContainer<ELEMENT_DIM, SPACE_DIM, 2>* pBcc,
00144 unsigned numQuadPoints)
00145 : BidomainDg0Assembler<ELEMENT_DIM,SPACE_DIM>(pMesh, pPde, pBcc, numQuadPoints)
00146 {
00147
00148 mpBidomainRhsMatrixAssembler = new BidomainRhsMatrixAssembler<SPACE_DIM>(pMesh);
00149 this->mpMatrixForMatrixBasedRhsAssembly = mpBidomainRhsMatrixAssembler->GetMatrix();
00150
00151
00152
00153 this->mUseMatrixBasedRhsAssembly = true;
00154 this->mVectorForMatrixBasedRhsAssembly = this->mpMesh->GetDistributedVectorFactory()->CreateVec(2);
00155
00156
00157 pPde->SetCacheReplication(false);
00158 }
00159
00160 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00161 BidomainMatrixBasedAssembler<ELEMENT_DIM,SPACE_DIM>::~BidomainMatrixBasedAssembler()
00162 {
00163 delete mpBidomainRhsMatrixAssembler;
00164 VecDestroy(this->mVectorForMatrixBasedRhsAssembly);
00165 }
00166
00167
00168 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00169 void BidomainMatrixBasedAssembler<ELEMENT_DIM,SPACE_DIM>::ConstructVectorForMatrixBasedRhsAssembly(
00170 Vec existingSolution)
00171 {
00172 DistributedVectorFactory* p_factory = this->mpMesh->GetDistributedVectorFactory();
00173
00174
00175 DistributedVector distributed_current_solution = p_factory->CreateDistributedVector(existingSolution);
00176 DistributedVector::Stripe distributed_current_solution_vm(distributed_current_solution, 0);
00177
00178
00179 DistributedVector dist_vec_matrix_based = p_factory->CreateDistributedVector(this->mVectorForMatrixBasedRhsAssembly);
00180 DistributedVector::Stripe dist_vec_matrix_based_vm(dist_vec_matrix_based, 0);
00181
00182
00183 double Am = HeartConfig::Instance()->GetSurfaceAreaToVolumeRatio();
00184 double Cm = HeartConfig::Instance()->GetCapacitance();
00185
00186 for (DistributedVector::Iterator index = dist_vec_matrix_based.Begin();
00187 index!= dist_vec_matrix_based.End();
00188 ++index)
00189 {
00190 double V = distributed_current_solution_vm[index];
00191 double F = - Am*this->mpBidomainPde->rGetIionicCacheReplicated()[index.Global]
00192 - this->mpBidomainPde->rGetIntracellularStimulusCacheReplicated()[index.Global];
00193
00194
00195 dist_vec_matrix_based_vm[index] = Am*Cm*V*this->mDtInverse + F;
00196
00197 }
00198
00199 dist_vec_matrix_based.Restore();
00200
00201 VecAssemblyBegin(this->mVectorForMatrixBasedRhsAssembly);
00202 VecAssemblyEnd(this->mVectorForMatrixBasedRhsAssembly);
00203 }
00204
00206
00208
00209 template class BidomainMatrixBasedAssembler<1,1>;
00210 template class BidomainMatrixBasedAssembler<2,2>;
00211 template class BidomainMatrixBasedAssembler<3,3>;
00212
00213 template class BidomainRhsMatrixAssembler<1>;
00214 template class BidomainRhsMatrixAssembler<2>;
00215 template class BidomainRhsMatrixAssembler<3>;