MonodomainMatrixBasedAssembler.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2010
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 
00029 #include "MonodomainMatrixBasedAssembler.hpp"
00030 
00031 
00033 //
00034 //
00035 //
00036 //
00037 //   NOTE: The main class in this file, MonodomainMatrixBasedAssembler, is defined at the
00038 //   bottom, after MonodomainRhsMatrixAssembler
00039 //
00040 //
00041 //
00042 //
00043 //
00045 
00046 
00047 
00049 // MonodomainRhsMatrixAssembler
00051 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00052 c_matrix<double,1*(ELEMENT_DIM+1),1*(ELEMENT_DIM+1)> MonodomainRhsMatrixAssembler<ELEMENT_DIM,SPACE_DIM>::ComputeMatrixTerm(
00053     c_vector<double, ELEMENT_DIM+1> &rPhi,
00054     c_matrix<double, SPACE_DIM, ELEMENT_DIM+1> &rGradPhi,
00055     ChastePoint<SPACE_DIM> &rX,
00056     c_vector<double,1> &u,
00057     c_matrix<double,1,SPACE_DIM> &rGradU /* not used */,
00058     Element<ELEMENT_DIM,SPACE_DIM>* pElement)
00059 {
00060     return outer_prod(rPhi, rPhi);
00061 }
00062 
00063 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00064 c_vector<double,1*(ELEMENT_DIM+1)> MonodomainRhsMatrixAssembler<ELEMENT_DIM,SPACE_DIM>::ComputeVectorTerm(
00065     c_vector<double, ELEMENT_DIM+1> &rPhi,
00066     c_matrix<double, SPACE_DIM, ELEMENT_DIM+1> &rGradPhi,
00067     ChastePoint<SPACE_DIM> &rX,
00068     c_vector<double,1> &u,
00069     c_matrix<double, 1, SPACE_DIM> &rGradU /* not used */,
00070     Element<ELEMENT_DIM,SPACE_DIM>* pElement)
00071 {
00072     #define COVERAGE_IGNORE
00073     NEVER_REACHED;
00074     return zero_vector<double>(SPACE_DIM+1);
00075     #undef COVERAGE_IGNORE
00076 }
00077 
00078 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00079 c_vector<double, ELEMENT_DIM> MonodomainRhsMatrixAssembler<ELEMENT_DIM, SPACE_DIM>::ComputeVectorSurfaceTerm(
00080     const BoundaryElement<ELEMENT_DIM-1,SPACE_DIM> &rSurfaceElement,
00081     c_vector<double, ELEMENT_DIM> &rPhi,
00082     ChastePoint<SPACE_DIM> &rX )
00083 {
00084     #define COVERAGE_IGNORE
00085     NEVER_REACHED;
00086     return zero_vector<double>(SPACE_DIM);
00087     #undef COVERAGE_IGNORE
00088 }
00089 
00090 
00091 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00092 MonodomainRhsMatrixAssembler<ELEMENT_DIM,SPACE_DIM>::MonodomainRhsMatrixAssembler(AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>* pMesh)
00093     : AbstractLinearAssembler<ELEMENT_DIM,SPACE_DIM,1,false,MonodomainRhsMatrixAssembler<ELEMENT_DIM,SPACE_DIM> >()
00094 {
00095     this->mpMesh = pMesh;
00096 
00097     // this needs to be set up, though no boundary condition values are used in the matrix
00098     this->mpBoundaryConditions = new BoundaryConditionsContainer<ELEMENT_DIM,SPACE_DIM,1>;
00099     this->mpBoundaryConditions->DefineZeroNeumannOnMeshBoundary(pMesh);
00100 
00101     //This linear system needs a distribution from the DistributedVector class
00102     Vec temp_vec = pMesh->GetDistributedVectorFactory()->CreateVec();
00103     this->mpLinearSystem = new LinearSystem(temp_vec);
00104     VecDestroy(temp_vec);
00105     this->AssembleSystem(false,true);
00106 }
00107 
00108 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00109 MonodomainRhsMatrixAssembler<ELEMENT_DIM, SPACE_DIM>::~MonodomainRhsMatrixAssembler()
00110 {
00111     delete this->mpBoundaryConditions;
00112 }
00113 
00114 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00115 Mat* MonodomainRhsMatrixAssembler<ELEMENT_DIM,SPACE_DIM>::GetMatrix()
00116 {
00117     return &(this->mpLinearSystem->rGetLhsMatrix());
00118 }
00119 
00120 
00121 
00122 
00123 
00125 // MonodomainMatrixBasedAssembler
00127 
00128 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00129 MonodomainMatrixBasedAssembler<ELEMENT_DIM,SPACE_DIM>::MonodomainMatrixBasedAssembler(
00130             AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>* pMesh,
00131             MonodomainPde<ELEMENT_DIM,SPACE_DIM>* pPde,
00132             BoundaryConditionsContainer<ELEMENT_DIM, SPACE_DIM, 1>* pBcc,
00133             unsigned numQuadPoints)
00134     : MonodomainDg0Assembler<ELEMENT_DIM,SPACE_DIM>(pMesh, pPde, pBcc, numQuadPoints)
00135 {
00136     // construct matrix using the helper class
00137     mpMonodomainRhsMatrixAssembler = new MonodomainRhsMatrixAssembler<ELEMENT_DIM,SPACE_DIM>(pMesh);
00138     this->mpMatrixForMatrixBasedRhsAssembly = mpMonodomainRhsMatrixAssembler->GetMatrix();
00139 
00140     // set variables on parent class so that we do matrix-based assembly, and allocate
00141     // memory for the vector 'z'
00142     this->mUseMatrixBasedRhsAssembly = true;
00143     this->mVectorForMatrixBasedRhsAssembly = pMesh->GetDistributedVectorFactory()->CreateVec();
00144 
00145     // Tell pde there's no need to replicate ionic caches
00146     pPde->SetCacheReplication(false);
00147 }
00148 
00149 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00150 MonodomainMatrixBasedAssembler<ELEMENT_DIM,SPACE_DIM>::~MonodomainMatrixBasedAssembler()
00151 {
00152     delete mpMonodomainRhsMatrixAssembler;
00153     VecDestroy(this->mVectorForMatrixBasedRhsAssembly);
00154 }
00155 
00156 //template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00157 //void MonodomainMatrixBasedAssembler<ELEMENT_DIM,SPACE_DIM>::ConstructVectorForMatrixBasedRhsAssembly(Vec existingSolution)
00158 //{
00159 //    // copy V to z
00160 //    VecCopy(existingSolution, this->mVectorForMatrixBasedRhsAssembly);
00161 //
00162 //    // set up a vector which has the nodewise force term (ie A*I_ionic+I_stim)
00163 //    Vec force_term_at_nodes = this->mpMesh->GetDistributedVectorFactory()->CreateVec();
00164 //    PetscInt lo, hi;
00165 //    VecGetOwnershipRange(force_term_at_nodes, &lo, &hi);
00166 //    double* p_force_term;
00167 //    VecGetArray(force_term_at_nodes, &p_force_term);
00168 //    for (int global_index=lo; global_index<hi; global_index++)
00169 //    {
00170 //        unsigned local_index = global_index - lo;
00171 //        const Node<SPACE_DIM>* p_node = this->mpMesh->GetNode(global_index);
00172 //        p_force_term[local_index] = this->mpMonodomainPde->ComputeNonlinearSourceTermAtNode(*p_node, 0.0);
00173 //    }
00174 //    VecRestoreArray(force_term_at_nodes, &p_force_term);
00175 //    VecAssemblyBegin(force_term_at_nodes);
00176 //    VecAssemblyEnd(force_term_at_nodes);
00177 //
00178 //    double one=1.0;
00179 //    double scaling=  this->mpMonodomainPde->ComputeDuDtCoefficientFunction(ChastePoint<SPACE_DIM>())
00180 //                    *this->mDtInverse;
00181 //
00182 //#if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00183 //    // VecAXPBY(a,b,x,y) does y = ax + by
00184 //    VecAXPBY(&one,
00185 //             &scaling,
00186 //             force_term_at_nodes,
00187 //             this->mVectorForMatrixBasedRhsAssembly);
00188 //#else
00189 //
00190 //    // VecAXPBY(y,a,b,x) does y = ax + by
00191 //    VecAXPBY(this->mVectorForMatrixBasedRhsAssembly,
00192 //             one,
00193 //             scaling,
00194 //             force_term_at_nodes);
00195 //#endif
00196 //
00197 //    VecAssemblyBegin(this->mVectorForMatrixBasedRhsAssembly);
00198 //    VecAssemblyEnd(this->mVectorForMatrixBasedRhsAssembly);
00199 //    VecDestroy(force_term_at_nodes);
00200 //}
00201 
00202 
00203 
00204 
00205 
00206 
00207 
00208 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00209 void MonodomainMatrixBasedAssembler<ELEMENT_DIM,SPACE_DIM>::ConstructVectorForMatrixBasedRhsAssembly(
00210         Vec existingSolution)
00211 {
00212     DistributedVectorFactory* p_factory = this->mpMesh->GetDistributedVectorFactory();
00213 
00214     // dist stripe for the current Voltage
00215     DistributedVector distributed_current_solution = p_factory->CreateDistributedVector(existingSolution);
00216 
00217     // dist stripe for z (return value)
00218     DistributedVector dist_vec_matrix_based = p_factory->CreateDistributedVector(this->mVectorForMatrixBasedRhsAssembly);
00219 
00220     double Am = HeartConfig::Instance()->GetSurfaceAreaToVolumeRatio();
00221     double Cm  = HeartConfig::Instance()->GetCapacitance();
00222 
00223     for (DistributedVector::Iterator index = dist_vec_matrix_based.Begin();
00224          index!= dist_vec_matrix_based.End();
00225          ++index)
00226     {
00227         double V = distributed_current_solution[index];
00228         double F = - Am*this->mpMonodomainPde->rGetIionicCacheReplicated()[index.Global]
00229                    - this->mpMonodomainPde->rGetIntracellularStimulusCacheReplicated()[index.Global];
00230 
00231         dist_vec_matrix_based[index] = Am*Cm*V*this->mDtInverse + F;
00232     }
00233 
00234     dist_vec_matrix_based.Restore();
00235 
00236     VecAssemblyBegin(this->mVectorForMatrixBasedRhsAssembly);
00237     VecAssemblyEnd(this->mVectorForMatrixBasedRhsAssembly);
00238 }
00239 
00240 
00241 
00243 // Explicit instantiation
00245 
00246 template class MonodomainMatrixBasedAssembler<1,1>;
00247 template class MonodomainMatrixBasedAssembler<1,2>;
00248 template class MonodomainMatrixBasedAssembler<1,3>;
00249 template class MonodomainMatrixBasedAssembler<2,2>;
00250 template class MonodomainMatrixBasedAssembler<3,3>;
00251 
00252 template class MonodomainRhsMatrixAssembler<1,1>;
00253 template class MonodomainRhsMatrixAssembler<1,2>;
00254 template class MonodomainRhsMatrixAssembler<1,3>;
00255 template class MonodomainRhsMatrixAssembler<2,2>;
00256 template class MonodomainRhsMatrixAssembler<3,3>;

Generated by  doxygen 1.6.2