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 "MonodomainDg0Assembler.hpp"
00030 #include "GaussianQuadratureRule.hpp"
00031 #include "HeartConfig.hpp"
00032
00033
00034 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00035 c_matrix<double,1*(ELEMENT_DIM+1),1*(ELEMENT_DIM+1)>
00036 MonodomainDg0Assembler<ELEMENT_DIM,SPACE_DIM>::ComputeMatrixTerm(
00037 c_vector<double, ELEMENT_DIM+1> &rPhi,
00038 c_matrix<double, SPACE_DIM, ELEMENT_DIM+1> &rGradPhi,
00039 ChastePoint<SPACE_DIM> &rX,
00040 c_vector<double,1> &rU,
00041 c_matrix<double, 1, SPACE_DIM> &rGradU ,
00042 Element<ELEMENT_DIM,SPACE_DIM>* pElement)
00043 {
00044
00045 double Am = mpConfig->GetSurfaceAreaToVolumeRatio();
00046 double Cm = mpConfig->GetCapacitance();
00047
00048 const c_matrix<double, SPACE_DIM, SPACE_DIM>& sigma_i = mpMonodomainPde->rGetIntracellularConductivityTensor(pElement->GetIndex());
00049
00050 c_matrix<double, SPACE_DIM, ELEMENT_DIM+1> temp = prod(sigma_i, rGradPhi);
00051 c_matrix<double, ELEMENT_DIM+1, ELEMENT_DIM+1> grad_phi_sigma_i_grad_phi =
00052 prod(trans(rGradPhi), temp);
00053
00054 c_matrix<double, ELEMENT_DIM+1, ELEMENT_DIM+1> basis_outer_prod =
00055 outer_prod(rPhi, rPhi);
00056
00057 return (Am*Cm/this->mDt)*basis_outer_prod + grad_phi_sigma_i_grad_phi;
00058 }
00059
00060
00061 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00062 c_vector<double,1*(ELEMENT_DIM+1)> MonodomainDg0Assembler<ELEMENT_DIM,SPACE_DIM>::ComputeVectorTerm(
00063 c_vector<double, ELEMENT_DIM+1> &rPhi,
00064 c_matrix<double, SPACE_DIM, ELEMENT_DIM+1> &rGradPhi ,
00065 ChastePoint<SPACE_DIM> &rX ,
00066 c_vector<double,1> &rU,
00067 c_matrix<double, 1, SPACE_DIM> &rGradU ,
00068 Element<ELEMENT_DIM,SPACE_DIM>* pElement )
00069 {
00070 double Am = mpConfig->GetSurfaceAreaToVolumeRatio();
00071 double Cm = mpConfig->GetCapacitance();
00072
00073 return rPhi * (this->mDtInverse * Am * Cm * rU(0) - Am*mIionic - mIIntracellularStimulus);
00074 }
00075
00076
00077 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00078 c_vector<double, 1*ELEMENT_DIM> MonodomainDg0Assembler<ELEMENT_DIM,SPACE_DIM>::ComputeVectorSurfaceTerm(
00079 const BoundaryElement<ELEMENT_DIM-1,SPACE_DIM> &rSurfaceElement,
00080 c_vector<double,ELEMENT_DIM> &rPhi,
00081 ChastePoint<SPACE_DIM> &rX)
00082 {
00083
00084 double sigma_i_times_grad_phi_i_dot_n = this->mpBoundaryConditions->GetNeumannBCValue(&rSurfaceElement, rX, 0);
00085
00086 return rPhi*sigma_i_times_grad_phi_i_dot_n;
00087 }
00088
00089
00090
00091 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00092 void MonodomainDg0Assembler<ELEMENT_DIM,SPACE_DIM>::ResetInterpolatedQuantities( void )
00093 {
00094 mIionic=0;
00095 mIIntracellularStimulus=0;
00096 }
00097
00098
00099 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00100 void MonodomainDg0Assembler<ELEMENT_DIM,SPACE_DIM>::IncrementInterpolatedQuantities(
00101 double phiI, const Node<SPACE_DIM>* pNode)
00102 {
00103 unsigned node_global_index = pNode->GetIndex();
00104
00105 mIionic += phiI * mpMonodomainPde->rGetIionicCacheReplicated()[ node_global_index ];
00106 mIIntracellularStimulus += phiI * mpMonodomainPde->rGetIntracellularStimulusCacheReplicated()[ node_global_index ];
00107 }
00108
00109
00110 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00111 void MonodomainDg0Assembler<ELEMENT_DIM,SPACE_DIM>::PrepareForAssembleSystem(
00112 Vec existingSolution, double time)
00113 {
00114 mpMonodomainPde->SolveCellSystems(existingSolution, time, time+this->mDt);
00115 }
00116
00117
00118 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00119 void MonodomainDg0Assembler<ELEMENT_DIM,SPACE_DIM>::InitialiseForSolve(Vec initialSolution)
00120 {
00121 if (this->mpLinearSystem != NULL)
00122 {
00123 return;
00124 }
00125
00126
00127 BaseClassType::InitialiseForSolve(initialSolution);
00128
00129 if(HeartConfig::Instance()->GetUseAbsoluteTolerance())
00130 {
00131 this->mpLinearSystem->SetAbsoluteTolerance(HeartConfig::Instance()->GetAbsoluteTolerance());
00132 }
00133 else
00134 {
00135 this->mpLinearSystem->SetRelativeTolerance(HeartConfig::Instance()->GetRelativeTolerance());
00136 }
00137
00138 this->mpLinearSystem->SetKspType(HeartConfig::Instance()->GetKSPSolver());
00139 this->mpLinearSystem->SetPcType(HeartConfig::Instance()->GetKSPPreconditioner());
00140 this->mpLinearSystem->SetMatrixIsSymmetric(true);
00141 }
00142
00143
00144 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00145 MonodomainDg0Assembler<ELEMENT_DIM,SPACE_DIM>::MonodomainDg0Assembler(
00146 AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>* pMesh,
00147 MonodomainPde<ELEMENT_DIM, SPACE_DIM>* pPde,
00148 BoundaryConditionsContainer<ELEMENT_DIM, SPACE_DIM, 1>* pBcc,
00149 unsigned numQuadPoints)
00150 : AbstractAssembler<ELEMENT_DIM,SPACE_DIM,1>(),
00151 BaseClassType(numQuadPoints),
00152 AbstractDynamicAssemblerMixin<ELEMENT_DIM,SPACE_DIM,1>()
00153 {
00154 mpMonodomainPde = pPde;
00155
00156 this->mpBoundaryConditions = pBcc;
00157
00158 this->SetMesh(pMesh);
00159
00160 this->SetMatrixIsConstant();
00161
00162 mpConfig = HeartConfig::Instance();
00163 }
00164
00165 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00166 MonodomainDg0Assembler<ELEMENT_DIM,SPACE_DIM>::~MonodomainDg0Assembler()
00167 {
00168 }
00169
00170
00172
00174
00175 template class MonodomainDg0Assembler<1,1>;
00176 template class MonodomainDg0Assembler<1,2>;
00177 template class MonodomainDg0Assembler<1,3>;
00178 template class MonodomainDg0Assembler<2,2>;
00179 template class MonodomainDg0Assembler<3,3>;
00180