Chaste Release::3.1
|
00001 /* 00002 00003 Copyright (c) 2005-2012, University of Oxford. 00004 All rights reserved. 00005 00006 University of Oxford means the Chancellor, Masters and Scholars of the 00007 University of Oxford, having an administrative office at Wellington 00008 Square, Oxford OX1 2JD, UK. 00009 00010 This file is part of Chaste. 00011 00012 Redistribution and use in source and binary forms, with or without 00013 modification, are permitted provided that the following conditions are met: 00014 * Redistributions of source code must retain the above copyright notice, 00015 this list of conditions and the following disclaimer. 00016 * Redistributions in binary form must reproduce the above copyright notice, 00017 this list of conditions and the following disclaimer in the documentation 00018 and/or other materials provided with the distribution. 00019 * Neither the name of the University of Oxford nor the names of its 00020 contributors may be used to endorse or promote products derived from this 00021 software without specific prior written permission. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 00034 */ 00035 00036 00037 #include "ExtendedBidomainSolver.hpp" 00038 #include "ExtendedBidomainMassMatrixAssembler.hpp" 00039 #include "ExtendedBidomainAssembler.hpp" 00040 00041 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00042 void ExtendedBidomainSolver<ELEMENT_DIM,SPACE_DIM>::InitialiseForSolve(Vec initialSolution) 00043 { 00044 if (this->mpLinearSystem != NULL) 00045 { 00046 return; 00047 } 00048 AbstractExtendedBidomainSolver<ELEMENT_DIM,SPACE_DIM>::InitialiseForSolve(initialSolution); 00049 00050 // initialise matrix-based RHS vector and matrix, and use the linear 00051 // system rhs as a template 00052 Vec& r_template = this->mpLinearSystem->rGetRhsVector(); 00053 VecDuplicate(r_template, &mVecForConstructingRhs); 00054 PetscInt ownership_range_lo; 00055 PetscInt ownership_range_hi; 00056 VecGetOwnershipRange(r_template, &ownership_range_lo, &ownership_range_hi); 00057 PetscInt local_size = ownership_range_hi - ownership_range_lo; 00058 PetscTools::SetupMat(mMassMatrix, 3*this->mpMesh->GetNumNodes(), 3*this->mpMesh->GetNumNodes(), 00059 3*this->mpMesh->CalculateMaximumNodeConnectivityPerProcess(), 00060 local_size, local_size); 00061 } 00062 00063 00064 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00065 void ExtendedBidomainSolver<ELEMENT_DIM,SPACE_DIM>::SetupLinearSystem( 00066 Vec currentSolution, 00067 bool computeMatrix) 00068 { 00069 assert(this->mpLinearSystem->rGetLhsMatrix() != NULL); 00070 assert(this->mpLinearSystem->rGetRhsVector() != NULL); 00071 assert(currentSolution != NULL); 00072 00073 00075 // set up LHS matrix (and mass matrix) 00077 if(computeMatrix) 00078 { 00079 mpExtendedBidomainAssembler->SetMatrixToAssemble(this->mpLinearSystem->rGetLhsMatrix()); 00080 mpExtendedBidomainAssembler->AssembleMatrix(); 00081 00082 // the ExtendedBidomainMassMatrixAssembler deals with the mass matrix 00083 // for both bath and nonbath problems 00084 assert(SPACE_DIM==ELEMENT_DIM); 00085 ExtendedBidomainMassMatrixAssembler<SPACE_DIM> mass_matrix_assembler(this->mpMesh); 00086 mass_matrix_assembler.SetMatrixToAssemble(mMassMatrix); 00087 mass_matrix_assembler.Assemble(); 00088 00089 this->mpLinearSystem->SwitchWriteModeLhsMatrix(); 00090 PetscMatTools::Finalise(mMassMatrix); 00091 } 00092 00093 00094 HeartEventHandler::BeginEvent(HeartEventHandler::ASSEMBLE_RHS); 00095 00097 // Set up z in b=Mz 00099 DistributedVectorFactory* p_factory = this->mpMesh->GetDistributedVectorFactory(); 00100 00101 // get bidomain parameters 00102 double Am1 = this->mpExtendedBidomainTissue->GetAmFirstCell(); 00103 double Am2 = this->mpExtendedBidomainTissue->GetAmSecondCell(); 00104 double AmGap = this->mpExtendedBidomainTissue->GetAmGap(); 00105 double Cm1 = this->mpExtendedBidomainTissue->GetCmFirstCell(); 00106 double Cm2 = this->mpExtendedBidomainTissue->GetCmSecondCell(); 00107 00108 // dist stripe for the current Voltage 00109 DistributedVector distributed_current_solution = p_factory->CreateDistributedVector(currentSolution); 00110 DistributedVector::Stripe distributed_current_solution_v_first_cell(distributed_current_solution, 0); 00111 DistributedVector::Stripe distributed_current_solution_v_second_cell(distributed_current_solution, 1); 00112 DistributedVector::Stripe distributed_current_solution_phi_e(distributed_current_solution, 2); 00113 00114 // dist stripe for z 00115 DistributedVector dist_vec_matrix_based = p_factory->CreateDistributedVector(mVecForConstructingRhs); 00116 DistributedVector::Stripe dist_vec_matrix_based_v_first_cell(dist_vec_matrix_based, 0); 00117 DistributedVector::Stripe dist_vec_matrix_based_v_second_cell(dist_vec_matrix_based, 1); 00118 DistributedVector::Stripe dist_vec_matrix_based_phi_e(dist_vec_matrix_based, 2); 00119 00120 for (DistributedVector::Iterator index = dist_vec_matrix_based.Begin(); 00121 index!= dist_vec_matrix_based.End(); 00122 ++index) 00123 { 00124 double V_first_cell = distributed_current_solution_v_first_cell[index]; 00125 double V_second_Cell = distributed_current_solution_v_second_cell[index]; 00126 double Phi_e = distributed_current_solution_phi_e[index]; 00127 00128 double i_ionic_first_cell = this->mpExtendedBidomainTissue->rGetIionicCacheReplicated()[index.Global]; 00129 double i_ionic_second_cell = this->mpExtendedBidomainTissue->rGetIionicCacheReplicatedSecondCell()[index.Global]; 00130 double intracellular_stimulus_first_cell = this->mpExtendedBidomainTissue->rGetIntracellularStimulusCacheReplicated()[index.Global]; 00131 double intracellular_stimulus_second_cell = this->mpExtendedBidomainTissue->rGetIntracellularStimulusCacheReplicatedSecondCell()[index.Global]; 00132 double extracellular_stimulus = this->mpExtendedBidomainTissue->rGetExtracellularStimulusCacheReplicated()[index.Global]; 00133 double g_gap = this->mpExtendedBidomainTissue->rGetGgapCacheReplicated()[index.Global]; 00134 double delta_t = PdeSimulationTime::GetPdeTimeStep(); 00135 dist_vec_matrix_based_v_first_cell[index] = Am1*Cm1*V_first_cell/delta_t - Am1*Cm1*Phi_e/delta_t - Am1*i_ionic_first_cell + AmGap*g_gap*(V_second_Cell - V_first_cell) - intracellular_stimulus_first_cell; 00136 dist_vec_matrix_based_v_second_cell[index] = Am2*Cm2*V_second_Cell/delta_t- Am2*Cm2*Phi_e/delta_t - Am2*i_ionic_second_cell + AmGap*g_gap*(V_first_cell - V_second_Cell) - intracellular_stimulus_second_cell; 00137 00138 if (this->mpExtendedBidomainTissue->HasTheUserSuppliedExtracellularStimulus() ) 00139 { 00140 assert((fabs(intracellular_stimulus_first_cell) < 1e-12) 00141 && (fabs(intracellular_stimulus_second_cell) < 1e-12)); 00142 00147 dist_vec_matrix_based_phi_e[index] = -extracellular_stimulus; 00148 } 00149 else 00150 { 00151 dist_vec_matrix_based_phi_e[index] = 0.0; 00152 } 00153 } 00154 00155 00156 dist_vec_matrix_based.Restore(); 00157 00159 // b = Mz 00161 00162 MatMult(mMassMatrix, mVecForConstructingRhs, this->mpLinearSystem->rGetRhsVector()); 00163 00164 // assembling RHS is not finished yet, as Neumann bcs are added below, but 00165 // the event will be begun again inside mpExtendedBidomainAssembler->AssembleVector(); 00166 HeartEventHandler::EndEvent(HeartEventHandler::ASSEMBLE_RHS); 00167 00169 // apply Neumann boundary conditions 00171 mpExtendedBidomainNeumannSurfaceTermAssembler->ResetBoundaryConditionsContainer(this->mpBoundaryConditions); // as the BCC can change 00172 mpExtendedBidomainNeumannSurfaceTermAssembler->SetVectorToAssemble(this->mpLinearSystem->rGetRhsVector(), false/*don't zero vector!*/); 00173 mpExtendedBidomainNeumannSurfaceTermAssembler->AssembleVector(); 00174 00175 this->mpLinearSystem->FinaliseRhsVector(); 00176 00177 this->mpBoundaryConditions->ApplyDirichletToLinearProblem(*(this->mpLinearSystem), computeMatrix); 00178 00179 if(computeMatrix) 00180 { 00181 this->mpLinearSystem->FinaliseLhsMatrix(); 00182 } 00183 this->mpLinearSystem->FinaliseRhsVector(); 00184 } 00185 00186 00187 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00188 ExtendedBidomainSolver<ELEMENT_DIM,SPACE_DIM>::ExtendedBidomainSolver( 00189 bool bathSimulation, 00190 AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>* pMesh, 00191 ExtendedBidomainTissue<SPACE_DIM>* pTissue, 00192 BoundaryConditionsContainer<ELEMENT_DIM,SPACE_DIM,3>* pBoundaryConditions, 00193 unsigned numQuadPoints) 00194 : AbstractExtendedBidomainSolver<ELEMENT_DIM,SPACE_DIM>(bathSimulation,pMesh,pTissue,pBoundaryConditions) 00195 { 00196 // Tell Tissue there's no need to replicate ionic caches 00197 pTissue->SetCacheReplication(false); 00198 mVecForConstructingRhs = NULL; 00199 00200 // create assembler 00201 if(this->mBathSimulation) 00202 { 00203 //this->mpExtendedExtendedBidomainAssembler = new ExtendedExtendedBidomainWithBathAssembler<ELEMENT_DIM,SPACE_DIM>(this->mpMesh,this->mpExtendedExtendedBidomainTissue,this->mDt,this->mNumQuadPoints); 00204 EXCEPTION("Bath simulations are not yet supported for extended bidomain problems"); 00205 } 00206 else 00207 { 00208 mpExtendedBidomainAssembler = new ExtendedBidomainAssembler<ELEMENT_DIM,SPACE_DIM>(this->mpMesh,this->mpExtendedBidomainTissue,this->mNumQuadPoints); 00209 } 00210 00211 mpExtendedBidomainNeumannSurfaceTermAssembler = new ExtendedBidomainNeumannSurfaceTermAssembler<ELEMENT_DIM,SPACE_DIM>(pMesh,pBoundaryConditions); 00212 00213 } 00214 00215 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM> 00216 ExtendedBidomainSolver<ELEMENT_DIM,SPACE_DIM>::~ExtendedBidomainSolver() 00217 { 00218 delete mpExtendedBidomainAssembler; 00219 delete mpExtendedBidomainNeumannSurfaceTermAssembler; 00220 00221 if(mVecForConstructingRhs) 00222 { 00223 PetscTools::Destroy(mVecForConstructingRhs); 00224 PetscTools::Destroy(mMassMatrix); 00225 } 00226 } 00227 00229 // explicit instantiation 00231 00232 template class ExtendedBidomainSolver<1,1>; 00233 template class ExtendedBidomainSolver<2,2>; 00234 template class ExtendedBidomainSolver<3,3>; 00235