MonodomainMatrixBasedAssembler.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2009
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 // NOTE: MonodomainMatrixBasedAssembler is defined after MonodomainRhsMatrixAssembler
00032 
00033 
00035 // MonodomainRhsMatrixAssembler
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 /* not used */,
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 /* not used */,
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     // this needs to be set up, though no boundary condition values are used in the matrix
00086     this->mpBoundaryConditions = new BoundaryConditionsContainer<DIM,DIM,1>;
00087     this->mpBoundaryConditions->DefineZeroNeumannOnMeshBoundary(pMesh);
00088     
00089     //This linear system needs a distribution from the DistributedVector class
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 // MonodomainMatrixBasedAssembler
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     // construct matrix using the helper class
00125     mpMonodomainRhsMatrixAssembler = new MonodomainRhsMatrixAssembler<SPACE_DIM>(pMesh);
00126     this->mpMatrixForMatrixBasedRhsAssembly = mpMonodomainRhsMatrixAssembler->GetMatrix();
00127 
00128     // set variables on parent class so that we do matrix-based assembly, and allocate
00129     // memory for the vector 'z'
00130     this->mUseMatrixBasedRhsAssembly = true;
00131     this->mVectorForMatrixBasedRhsAssembly = DistributedVector::CreateVec();
00132 
00133     // Tell pde there's no need to replicate ionic caches
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     // copy V to z
00148     VecCopy(currentSolution, this->mVectorForMatrixBasedRhsAssembly);  
00149 
00150     // set up a vector which has the nodewise force term (ie A*I_ionic+I_stim)
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     // VecAXPBY(a,b,x,y) does y = ax + by
00172     VecAXPBY(&one, &scaling, force_term_at_nodes, this->mVectorForMatrixBasedRhsAssembly);
00173 #else
00174     // VecAXPBY(y,a,b,x) does y = ax + by
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 // Explicit instantiation
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>;

Generated on Wed Mar 18 12:51:52 2009 for Chaste by  doxygen 1.5.5