ExtendedBidomainTissue.cpp

00001 /*
00002 
00003 Copyright (c) 2005-2015, 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 #include "ExtendedBidomainTissue.hpp"
00037 
00038 #include "DistributedVector.hpp"
00039 #include "OrthotropicConductivityTensors.hpp"
00040 #include "AxisymmetricConductivityTensors.hpp"
00041 #include "AbstractStimulusFunction.hpp"
00042 #include "ChastePoint.hpp"
00043 #include "AbstractChasteRegion.hpp"
00044 #include "HeartEventHandler.hpp"
00045 
00046 template <unsigned SPACE_DIM>
00047 ExtendedBidomainTissue<SPACE_DIM>::ExtendedBidomainTissue(AbstractCardiacCellFactory<SPACE_DIM>* pCellFactory,
00048                                                           AbstractCardiacCellFactory<SPACE_DIM>* pCellFactorySecondCell,
00049                                                           AbstractStimulusFactory<SPACE_DIM>* pExtracellularStimulusFactory)
00050     : AbstractCardiacTissue<SPACE_DIM>(pCellFactory),
00051       mpIntracellularConductivityTensorsSecondCell(NULL),
00052       mUserSuppliedExtracellularStimulus(false)
00053 {
00054     //First, do the same that the abstract constructor does, but applied to the second cell
00055 
00056     assert(pCellFactorySecondCell != NULL);
00057     assert(pCellFactorySecondCell->GetMesh() != NULL);
00058     assert(pCellFactorySecondCell->GetNumberOfCells() == pCellFactory->GetNumberOfCells() );
00059     assert(pExtracellularStimulusFactory != NULL);
00060     assert(pExtracellularStimulusFactory->GetMesh() != NULL);
00061     assert(pExtracellularStimulusFactory->GetNumberOfCells() == pCellFactorySecondCell->GetNumberOfCells() );
00062 
00063     unsigned num_local_nodes = this->mpDistributedVectorFactory->GetLocalOwnership();
00064     unsigned ownership_range_low = this->mpDistributedVectorFactory->GetLow();
00065     mCellsDistributedSecondCell.resize(num_local_nodes);
00066     mGgapDistributed.resize(num_local_nodes);
00067     mExtracellularStimuliDistributed.resize(num_local_nodes);
00068 
00069     try
00070     {
00071         for (unsigned local_index = 0; local_index < num_local_nodes; local_index++)
00072         {
00073             unsigned global_index = local_index + ownership_range_low;
00074             Node<SPACE_DIM>* p_node = this->mpMesh->GetNode(global_index);
00075             mCellsDistributedSecondCell[local_index] = pCellFactorySecondCell->CreateCardiacCellForNode(p_node);
00076             mCellsDistributedSecondCell[local_index]->SetUsedInTissueSimulation();
00077             mGgapDistributed[local_index] = 0.0;//default. It will be changed by specific method later when user input will be obtained
00078             mExtracellularStimuliDistributed[local_index] = pExtracellularStimulusFactory->CreateStimulusForNode(p_node);
00079         }
00080 
00081         pCellFactorySecondCell->FinaliseCellCreation(&mCellsDistributedSecondCell,
00082                                                      this->mpDistributedVectorFactory->GetLow(),
00083                                                      this->mpDistributedVectorFactory->GetHigh());
00084     }
00085     catch (const Exception& e)
00086     {
00087 #define COVERAGE_IGNORE //don't really know how to cover this...
00088         // Errors thrown creating cells will often be process-specific
00089         PetscTools::ReplicateException(true);
00090         // Should really do this for other processes too, but this is all we need
00091         // to get memory testing to pass, and leaking when we're about to die isn't
00092         // that bad! Delete second cells
00093         for (std::vector<AbstractCardiacCellInterface*>::iterator cell_iterator = mCellsDistributedSecondCell.begin();
00094              cell_iterator != mCellsDistributedSecondCell.end();
00095              ++cell_iterator)
00096         {
00097             delete (*cell_iterator);
00098         }
00099         throw e;
00100 #undef COVERAGE_IGNORE
00101     }
00102     PetscTools::ReplicateException(false);
00103 
00104     HeartEventHandler::BeginEvent(HeartEventHandler::COMMUNICATION);
00105     mIionicCacheReplicatedSecondCell.Resize( pCellFactory->GetNumberOfCells() );
00106     mIntracellularStimulusCacheReplicatedSecondCell.Resize( pCellFactorySecondCell->GetNumberOfCells() );
00107     mGgapCacheReplicated.Resize(pCellFactorySecondCell->GetNumberOfCells());//this is a bit of a hack...
00108     mExtracellularStimulusCacheReplicated.Resize(pExtracellularStimulusFactory->GetNumberOfCells());
00109     HeartEventHandler::EndEvent(HeartEventHandler::COMMUNICATION);
00110 
00111     //Create the extracellular conductivity tensor
00112     CreateExtracellularConductivityTensors();
00113 }
00114 
00115 //archiving constructor
00116 template <unsigned SPACE_DIM>
00117 ExtendedBidomainTissue<SPACE_DIM>::ExtendedBidomainTissue(std::vector<AbstractCardiacCellInterface*> & rCellsDistributed,
00118                                                           std::vector<AbstractCardiacCellInterface*> & rSecondCellsDistributed,
00119                                                           std::vector<boost::shared_ptr<AbstractStimulusFunction> > & rExtraStimuliDistributed,
00120                                                           std::vector<double> & rGgapsDistributed,
00121                                                           AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>* pMesh,
00122                                                           c_vector<double, SPACE_DIM>  intracellularConductivitiesSecondCell)
00123         :   AbstractCardiacTissue<SPACE_DIM>(pMesh),
00124             mpIntracellularConductivityTensorsSecondCell(NULL),
00125             mIntracellularConductivitiesSecondCell(intracellularConductivitiesSecondCell),
00126             mCellsDistributedSecondCell(rSecondCellsDistributed),
00127             mExtracellularStimuliDistributed(rExtraStimuliDistributed),
00128             mGgapDistributed(rGgapsDistributed),
00129             mUserSuppliedExtracellularStimulus(false)
00130 {
00131     //segfault guards in case we failed to load anything from the archive
00132     assert(mCellsDistributedSecondCell.size() > 0);
00133     assert(mExtracellularStimuliDistributed.size() > 0);
00134     assert(mGgapDistributed.size() > 0);
00135     //allocate memory for the caches
00136     mIionicCacheReplicatedSecondCell.Resize( this->mpDistributedVectorFactory->GetProblemSize());
00137     mIntracellularStimulusCacheReplicatedSecondCell.Resize( this->mpDistributedVectorFactory->GetProblemSize() );
00138     mGgapCacheReplicated.Resize(this->mpDistributedVectorFactory->GetProblemSize());
00139     mExtracellularStimulusCacheReplicated.Resize(this->mpDistributedVectorFactory->GetProblemSize());
00140 
00141     CreateIntracellularConductivityTensorSecondCell();
00142     CreateExtracellularConductivityTensors();
00143 }
00144 
00145 
00146 template <unsigned SPACE_DIM>
00147 void ExtendedBidomainTissue<SPACE_DIM>::SetGgapHeterogeneities(std::vector<boost::shared_ptr<AbstractChasteRegion<SPACE_DIM> > >& rGgapHeterogeneityRegions,
00148                                                                std::vector<double> rGgapValues)
00149 {
00150     assert( rGgapHeterogeneityRegions.size() == rGgapValues.size() );//problem class (which calls this method should have thrown otherwise)
00151     mGgapHeterogeneityRegions = rGgapHeterogeneityRegions;
00152     mGgapValues =rGgapValues;
00153 }
00154 
00155 template <unsigned SPACE_DIM>
00156 void ExtendedBidomainTissue<SPACE_DIM>::CreateGGapConductivities()
00157 {
00158     assert(mGgapHeterogeneityRegions.size() == mGgapValues.size());
00159     assert(this->mpMesh != NULL);
00160 
00161     unsigned ownership_range_low = this->mpDistributedVectorFactory->GetLow();
00162     unsigned num_local_nodes = this->mpDistributedVectorFactory->GetLocalOwnership();
00163     assert(mGgapDistributed.size() == num_local_nodes);//the constructor should have allocated memory.
00164     try
00165     {
00166         for (unsigned local_index = 0; local_index < num_local_nodes; local_index++)
00167         {
00168             unsigned global_index = ownership_range_low + local_index;
00169             Node<SPACE_DIM>* p_node = this->mpMesh->GetNode(global_index);
00170             mGgapDistributed[local_index] = mGGap;//assign default uniform value everywhere first
00171 
00172             //then change where and if necessary
00173             for (unsigned het_index = 0; het_index < mGgapHeterogeneityRegions.size(); het_index++)
00174             {
00175                 if ( mGgapHeterogeneityRegions[het_index]->DoesContain ( p_node->GetPoint() ) )
00176                 {
00177                     mGgapDistributed[local_index] = mGgapValues[het_index];
00178                 }
00179             }
00180         }
00181     }
00182     catch (const Exception& e)
00183     {
00184 #define COVERAGE_IGNORE
00185         PetscTools::ReplicateException(true);
00186         throw e;
00187 #undef COVERAGE_IGNORE
00188     }
00189     PetscTools::ReplicateException(false);
00190 }
00191 
00192 template <unsigned SPACE_DIM>
00193 void ExtendedBidomainTissue<SPACE_DIM>::CreateIntracellularConductivityTensorSecondCell()
00194 {
00195     HeartEventHandler::BeginEvent(HeartEventHandler::READ_MESH);
00196     this->mpConfig = HeartConfig::Instance();
00197 
00198     if (this->mpConfig->IsMeshProvided() && this->mpConfig->GetLoadMesh())
00199     {
00200         assert(this->mFibreFilePathNoExtension != "");
00201 
00202         switch (this->mpConfig->GetConductivityMedia())
00203         {
00204             case cp::media_type::Orthotropic:
00205             {
00206                 mpIntracellularConductivityTensorsSecondCell =  new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
00207                 FileFinder ortho_file(this->mFibreFilePathNoExtension + ".ortho", RelativeTo::AbsoluteOrCwd);
00208                 assert(ortho_file.Exists());
00209                 mpIntracellularConductivityTensorsSecondCell->SetFibreOrientationFile(ortho_file);
00210                 break;
00211             }
00212 
00213             case cp::media_type::Axisymmetric:
00214             {
00215                 mpIntracellularConductivityTensorsSecondCell =  new AxisymmetricConductivityTensors<SPACE_DIM,SPACE_DIM>;
00216                 FileFinder axi_file(this->mFibreFilePathNoExtension + ".axi", RelativeTo::AbsoluteOrCwd);
00217                 assert(axi_file.Exists());
00218                 mpIntracellularConductivityTensorsSecondCell->SetFibreOrientationFile(axi_file);
00219                 break;
00220             }
00221 
00222             case cp::media_type::NoFibreOrientation:
00223                 mpIntracellularConductivityTensorsSecondCell =  new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
00224                 break;
00225 
00226             default :
00227                 NEVER_REACHED;
00228         }
00229     }
00230     else // Slab defined in config file or SetMesh() called; no fibre orientation assumed
00231     {
00232         mpIntracellularConductivityTensorsSecondCell =  new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
00233     }
00234 
00235     // this definition must be here (and not inside the if statement) because SetNonConstantConductivities() will keep
00236     // a pointer to it and we don't want it to go out of scope before Init() is called
00237     unsigned num_elements = this->mpMesh->GetNumElements();
00238     std::vector<c_vector<double, SPACE_DIM> > hetero_intra_conductivities;
00239 
00240     c_vector<double, SPACE_DIM> intra_conductivities;
00241     this->mpConfig->GetIntracellularConductivities(intra_conductivities);//this one is used just for resizing
00242 
00243     if (this->mpConfig->GetConductivityHeterogeneitiesProvided())
00244     {
00245         try
00246         {
00247             assert(hetero_intra_conductivities.size()==0);
00248             hetero_intra_conductivities.resize(num_elements, intra_conductivities);
00249         }
00250         catch(std::bad_alloc &badAlloc)
00251         {
00252 #define COVERAGE_IGNORE
00253             std::cout << "Failed to allocate std::vector of size " << num_elements << std::endl;
00254             PetscTools::ReplicateException(true);
00255             throw badAlloc;
00256 #undef COVERAGE_IGNORE
00257         }
00258         PetscTools::ReplicateException(false);
00259 
00260         std::vector<boost::shared_ptr<AbstractChasteRegion<SPACE_DIM> > > conductivities_heterogeneity_areas;
00261         std::vector< c_vector<double,3> > intra_h_conductivities;
00262         std::vector< c_vector<double,3> > extra_h_conductivities;
00263         HeartConfig::Instance()->GetConductivityHeterogeneities(conductivities_heterogeneity_areas,
00264                                                                 intra_h_conductivities,
00265                                                                 extra_h_conductivities);
00266         unsigned local_element_index = 0;
00267         for (typename AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>::ElementIterator it = this->mpMesh->GetElementIteratorBegin();
00268              it != this->mpMesh->GetElementIteratorEnd();
00269              ++it)
00270         {
00271             //unsigned element_index = it->GetIndex();
00272             // if element centroid is contained in the region
00273             ChastePoint<SPACE_DIM> element_centroid(it->CalculateCentroid());
00274             for (unsigned region_index=0; region_index< conductivities_heterogeneity_areas.size(); region_index++)
00275             {
00276                 if ( conductivities_heterogeneity_areas[region_index]->DoesContain(element_centroid) )
00277                 {
00278                     //We don't use ublas vector assignment here, because we might be getting a subvector of a 3-vector
00279                     for (unsigned i=0; i<SPACE_DIM; i++)
00280                     {
00281                         hetero_intra_conductivities[local_element_index][i] = intra_h_conductivities[region_index][i];
00282                     }
00283                 }
00284             }
00285             local_element_index++;
00286         }
00287 
00288         mpIntracellularConductivityTensorsSecondCell->SetNonConstantConductivities(&hetero_intra_conductivities);
00289     }
00290     else
00291     {
00292         mpIntracellularConductivityTensorsSecondCell->SetConstantConductivities(mIntracellularConductivitiesSecondCell);
00293     }
00294 
00295     mpIntracellularConductivityTensorsSecondCell->Init(this->mpMesh);
00296     HeartEventHandler::EndEvent(HeartEventHandler::READ_MESH);
00297 }
00298 
00299 template <unsigned SPACE_DIM>
00300 bool ExtendedBidomainTissue<SPACE_DIM>::HasTheUserSuppliedExtracellularStimulus()
00301 {
00302     return mUserSuppliedExtracellularStimulus;
00303 }
00304 
00305 template <unsigned SPACE_DIM>
00306 void ExtendedBidomainTissue<SPACE_DIM>::SetUserSuppliedExtracellularStimulus(bool flag)
00307 {
00308     mUserSuppliedExtracellularStimulus = flag;
00309 }
00310 
00311 template <unsigned SPACE_DIM>
00312 const std::vector<AbstractCardiacCellInterface*>& ExtendedBidomainTissue<SPACE_DIM>::rGetSecondCellsDistributed() const
00313 {
00314     return mCellsDistributedSecondCell;
00315 }
00316 
00317 template <unsigned SPACE_DIM>
00318 const std::vector<double>& ExtendedBidomainTissue<SPACE_DIM>::rGetGapsDistributed() const
00319 {
00320     return mGgapDistributed;
00321 }
00322 
00323 template <unsigned SPACE_DIM>
00324 const std::vector<boost::shared_ptr<AbstractStimulusFunction> >& ExtendedBidomainTissue<SPACE_DIM>::rGetExtracellularStimulusDistributed() const
00325 {
00326     return mExtracellularStimuliDistributed;
00327 }
00328 
00329 
00330 template <unsigned SPACE_DIM>
00331 void ExtendedBidomainTissue<SPACE_DIM>::CreateExtracellularConductivityTensors()
00332 {
00333     if (this->mpConfig->IsMeshProvided() && this->mpConfig->GetLoadMesh())
00334     {
00335         assert(this->mFibreFilePathNoExtension != "");
00336         switch (this->mpConfig->GetConductivityMedia())
00337         {
00338             case cp::media_type::Orthotropic:
00339             {
00340                 mpExtracellularConductivityTensors =  new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
00341                 FileFinder ortho_file(this->mFibreFilePathNoExtension + ".ortho", RelativeTo::AbsoluteOrCwd);
00342                 assert(ortho_file.Exists());
00343                 mpExtracellularConductivityTensors->SetFibreOrientationFile(ortho_file);
00344                 break;
00345             }
00346 
00347             case cp::media_type::Axisymmetric:
00348             {
00349                 mpExtracellularConductivityTensors =  new AxisymmetricConductivityTensors<SPACE_DIM,SPACE_DIM>;
00350                 FileFinder axi_file(this->mFibreFilePathNoExtension + ".axi", RelativeTo::AbsoluteOrCwd);
00351                 assert(axi_file.Exists());
00352                 mpExtracellularConductivityTensors->SetFibreOrientationFile(axi_file);
00353                 break;
00354             }
00355 
00356             case cp::media_type::NoFibreOrientation:
00357                 mpExtracellularConductivityTensors =  new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
00358                 break;
00359 
00360             default :
00361                 NEVER_REACHED;
00362         }
00363     }
00364     else // no fibre orientation assumed
00365     {
00366         mpExtracellularConductivityTensors =  new OrthotropicConductivityTensors<SPACE_DIM,SPACE_DIM>;
00367     }
00368 
00369     c_vector<double, SPACE_DIM> extra_conductivities;
00370     this->mpConfig->GetExtracellularConductivities(extra_conductivities);
00371 
00372     // this definition must be here (and not inside the if statement) because SetNonConstantConductivities() will keep
00373     // a pointer to it and we don't want it to go out of scope before Init() is called
00374     unsigned num_elements = this->mpMesh->GetNumElements();
00375     std::vector<c_vector<double, SPACE_DIM> > hetero_extra_conductivities;
00376 
00377     if (this->mpConfig->GetConductivityHeterogeneitiesProvided())
00378     {
00379         try
00380         {
00381             assert(hetero_extra_conductivities.size()==0);
00382             //initialise with the values of teh default conductivity tensor
00383             hetero_extra_conductivities.resize(num_elements, extra_conductivities);
00384         }
00385         catch(std::bad_alloc &badAlloc)
00386         {
00387 #define COVERAGE_IGNORE
00388             std::cout << "Failed to allocate std::vector of size " << num_elements << std::endl;
00389             PetscTools::ReplicateException(true);
00390             throw badAlloc;
00391 #undef COVERAGE_IGNORE
00392         }
00393         PetscTools::ReplicateException(false);
00394 
00395         std::vector<boost::shared_ptr<AbstractChasteRegion<SPACE_DIM> > > conductivities_heterogeneity_areas;
00396         std::vector< c_vector<double,3> > intra_h_conductivities;
00397         std::vector< c_vector<double,3> > extra_h_conductivities;
00398         HeartConfig::Instance()->GetConductivityHeterogeneities(conductivities_heterogeneity_areas,
00399                                                                 intra_h_conductivities,
00400                                                                 extra_h_conductivities);
00401         unsigned local_element_index = 0;
00402         for (typename AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>::ElementIterator iter = (this->mpMesh)->GetElementIteratorBegin();
00403              iter != (this->mpMesh)->GetElementIteratorEnd();
00404              ++iter)
00405         {
00406             //unsigned element_index = iter->GetIndex();
00407             // if element centroid is contained in the region
00408             ChastePoint<SPACE_DIM> element_centroid(iter->CalculateCentroid());
00409             for (unsigned region_index=0; region_index< conductivities_heterogeneity_areas.size(); region_index++)
00410             {
00411                 // if element centroid is contained in the region
00412                 if ( conductivities_heterogeneity_areas[region_index]->DoesContain( element_centroid ) )
00413                 {
00414                     //We don't use ublas vector assignment here, because we might be getting a subvector of a 3-vector
00415                     for (unsigned i=0; i<SPACE_DIM; i++)
00416                     {
00417                         hetero_extra_conductivities[local_element_index][i] = extra_h_conductivities[region_index][i];
00418                     }
00419                 }
00420             }
00421             local_element_index++;
00422         }
00423 
00424         mpExtracellularConductivityTensors->SetNonConstantConductivities(&hetero_extra_conductivities);
00425     }
00426     else
00427     {
00428         mpExtracellularConductivityTensors->SetConstantConductivities(extra_conductivities);
00429     }
00430     mpExtracellularConductivityTensors->Init(this->mpMesh);
00431 }
00432 
00433 template <unsigned SPACE_DIM>
00434 ExtendedBidomainTissue<SPACE_DIM>::~ExtendedBidomainTissue()
00435 {
00436     // Delete (second) cells
00437     for (std::vector<AbstractCardiacCellInterface*>::iterator cell_iterator = mCellsDistributedSecondCell.begin();
00438          cell_iterator != mCellsDistributedSecondCell.end();
00439          ++cell_iterator)
00440     {
00441         delete (*cell_iterator);
00442     }
00443 
00444     if (mpExtracellularConductivityTensors)
00445     {
00446         delete mpExtracellularConductivityTensors;
00447     }
00448 
00449     if (mpIntracellularConductivityTensorsSecondCell)
00450     {
00451         delete mpIntracellularConductivityTensorsSecondCell;
00452     }
00453 }
00454 
00455 template <unsigned SPACE_DIM>
00456 void ExtendedBidomainTissue<SPACE_DIM>::SetIntracellularConductivitiesSecondCell(c_vector<double, SPACE_DIM> conductivities)
00457 {
00458     for (unsigned i = 0; i < SPACE_DIM; i++)
00459     {
00460         mIntracellularConductivitiesSecondCell[i] = conductivities[i];
00461     }
00462 }
00463 
00464 template <unsigned SPACE_DIM>
00465 c_vector<double, SPACE_DIM>  ExtendedBidomainTissue<SPACE_DIM>::GetIntracellularConductivitiesSecondCell() const
00466 {
00467     return mIntracellularConductivitiesSecondCell;
00468 }
00469 
00470 template <unsigned SPACE_DIM>
00471 const c_matrix<double, SPACE_DIM, SPACE_DIM>& ExtendedBidomainTissue<SPACE_DIM>::rGetExtracellularConductivityTensor(unsigned elementIndex)
00472 {
00473     assert(mpExtracellularConductivityTensors);
00474     if (this->mpConductivityModifier==NULL)
00475     {
00476         return (*mpExtracellularConductivityTensors)[elementIndex];
00477     }
00478     else
00479     {
00480         return this->mpConductivityModifier->rGetModifiedConductivityTensor(elementIndex, (*mpExtracellularConductivityTensors)[elementIndex], 1u);
00481     }
00482 }
00483 
00484 template <unsigned SPACE_DIM>
00485 const c_matrix<double, SPACE_DIM, SPACE_DIM>& ExtendedBidomainTissue<SPACE_DIM>::rGetIntracellularConductivityTensorSecondCell(unsigned elementIndex)
00486 {
00487     assert(mpIntracellularConductivityTensorsSecondCell);
00488     if (this->mpConductivityModifier==NULL)
00489     {
00490         return (*mpIntracellularConductivityTensorsSecondCell)[elementIndex];
00491     }
00492     else
00493     {
00494         return this->mpConductivityModifier->rGetModifiedConductivityTensor(elementIndex, (*mpIntracellularConductivityTensorsSecondCell)[elementIndex], 2u);
00495     }
00496 }
00497 
00498 template <unsigned SPACE_DIM>
00499 AbstractCardiacCellInterface* ExtendedBidomainTissue<SPACE_DIM>::GetCardiacSecondCell( unsigned globalIndex )
00500 {
00501     return mCellsDistributedSecondCell[globalIndex - this->mpDistributedVectorFactory->GetLow()];
00502 }
00503 
00504 template <unsigned SPACE_DIM>
00505 boost::shared_ptr<AbstractStimulusFunction> ExtendedBidomainTissue<SPACE_DIM>::GetExtracellularStimulus( unsigned globalIndex )
00506 {
00507     return mExtracellularStimuliDistributed[globalIndex - this->mpDistributedVectorFactory->GetLow()];
00508 }
00509 
00510 template <unsigned SPACE_DIM>
00511 void ExtendedBidomainTissue<SPACE_DIM>::SolveCellSystems(Vec existingSolution, double time, double nextTime, bool updateVoltage)
00512 {
00513     HeartEventHandler::BeginEvent(HeartEventHandler::SOLVE_ODES);
00514 
00515     DistributedVector dist_solution = this->mpDistributedVectorFactory->CreateDistributedVector(existingSolution);
00516     DistributedVector::Stripe V_first_cell(dist_solution, 0);
00517     DistributedVector::Stripe V_second_cell(dist_solution, 1);
00518     DistributedVector::Stripe phi_e(dist_solution, 2);
00519 
00520     for (DistributedVector::Iterator index = dist_solution.Begin();
00521          index != dist_solution.End();
00522          ++index)
00523     {
00524         // overwrite the voltage with the input value
00525         this->mCellsDistributed[index.Local]->SetVoltage( V_first_cell[index] );
00526         mCellsDistributedSecondCell[index.Local]->SetVoltage( V_second_cell[index] );
00527         try
00528         {
00529             // solve
00530             // Note: Voltage should not be updated. GetIIonic will be called later
00531             // and needs the old voltage. The voltage will be updated from the pde.
00532             this->mCellsDistributed[index.Local]->ComputeExceptVoltage(time, nextTime);
00533             mCellsDistributedSecondCell[index.Local]->ComputeExceptVoltage(time, nextTime);
00534         }
00535         catch (Exception &e)
00536         {
00537 #define COVERAGE_IGNORE
00538             PetscTools::ReplicateException(true);
00539             throw e;
00540 #undef COVERAGE_IGNORE
00541         }
00542 
00543         // update the Iionic and stimulus caches
00544         this->UpdateCaches(index.Global, index.Local, nextTime);//in parent class
00545         UpdateAdditionalCaches(index.Global, index.Local, nextTime);//extended bidomain specific caches
00546     }
00547     PetscTools::ReplicateException(false);
00548     HeartEventHandler::EndEvent(HeartEventHandler::SOLVE_ODES);
00549 
00550     HeartEventHandler::BeginEvent(HeartEventHandler::COMMUNICATION);
00551     if ( this->mDoCacheReplication )
00552     {
00553         this->ReplicateCaches();
00554         ReplicateAdditionalCaches();//extended bidomain specific caches
00555     }
00556     HeartEventHandler::EndEvent(HeartEventHandler::COMMUNICATION);
00557 }
00558 
00559 template <unsigned SPACE_DIM>
00560 void ExtendedBidomainTissue<SPACE_DIM>::UpdateAdditionalCaches(unsigned globalIndex, unsigned localIndex, double nextTime)
00561 {
00562     mIionicCacheReplicatedSecondCell[globalIndex] = mCellsDistributedSecondCell[localIndex]->GetIIonic();
00563     mIntracellularStimulusCacheReplicatedSecondCell[globalIndex] = mCellsDistributedSecondCell[localIndex]->GetIntracellularStimulus(nextTime);
00564     mExtracellularStimulusCacheReplicated[globalIndex] = mExtracellularStimuliDistributed[localIndex]->GetStimulus(nextTime);
00565     mGgapCacheReplicated[globalIndex] = mGgapDistributed[localIndex];
00566 }
00567 
00568 template <unsigned SPACE_DIM>
00569 void ExtendedBidomainTissue<SPACE_DIM>::ReplicateAdditionalCaches()
00570 {
00571     mIionicCacheReplicatedSecondCell.Replicate(this->mpDistributedVectorFactory->GetLow(), this->mpDistributedVectorFactory->GetHigh());
00572     mIntracellularStimulusCacheReplicatedSecondCell.Replicate(this->mpDistributedVectorFactory->GetLow(), this->mpDistributedVectorFactory->GetHigh());
00573     mExtracellularStimulusCacheReplicated.Replicate(this->mpDistributedVectorFactory->GetLow(), this->mpDistributedVectorFactory->GetHigh());
00574     mGgapCacheReplicated.Replicate(this->mpDistributedVectorFactory->GetLow(), this->mpDistributedVectorFactory->GetHigh());
00575 }
00576 
00577 template <unsigned SPACE_DIM>
00578 ReplicatableVector& ExtendedBidomainTissue<SPACE_DIM>::rGetIionicCacheReplicatedSecondCell()
00579 {
00580     return mIionicCacheReplicatedSecondCell;
00581 }
00582 
00583 template <unsigned SPACE_DIM>
00584 ReplicatableVector& ExtendedBidomainTissue<SPACE_DIM>::rGetIntracellularStimulusCacheReplicatedSecondCell()
00585 {
00586     return mIntracellularStimulusCacheReplicatedSecondCell;
00587 }
00588 
00589 template <unsigned SPACE_DIM>
00590 ReplicatableVector& ExtendedBidomainTissue<SPACE_DIM>::rGetExtracellularStimulusCacheReplicated()
00591 {
00592     return mExtracellularStimulusCacheReplicated;
00593 }
00594 
00595 template <unsigned SPACE_DIM>
00596 ReplicatableVector& ExtendedBidomainTissue<SPACE_DIM>::rGetGgapCacheReplicated()
00597 {
00598     return mGgapCacheReplicated;
00599 }
00600 
00601 template <unsigned SPACE_DIM>
00602 double ExtendedBidomainTissue<SPACE_DIM>::GetAmFirstCell()
00603 {
00604     return mAmFirstCell;
00605 }
00606 
00607 template <unsigned SPACE_DIM>
00608 double ExtendedBidomainTissue<SPACE_DIM>::GetAmSecondCell()
00609 {
00610     return mAmSecondCell;
00611 }
00612 
00613 template <unsigned SPACE_DIM>
00614 double ExtendedBidomainTissue<SPACE_DIM>::GetAmGap()
00615 {
00616     return mAmGap;
00617 }
00618 
00619 template <unsigned SPACE_DIM>
00620 double ExtendedBidomainTissue<SPACE_DIM>::GetCmFirstCell()
00621 {
00622     return mCmFirstCell;
00623 }
00624 
00625 template <unsigned SPACE_DIM>
00626 double ExtendedBidomainTissue<SPACE_DIM>::GetCmSecondCell()
00627 {
00628     return mCmSecondCell;
00629 }
00630 
00631 template <unsigned SPACE_DIM>
00632 double ExtendedBidomainTissue<SPACE_DIM>::GetGGap()
00633 {
00634     return mGGap;
00635 }
00636 
00637 template <unsigned SPACE_DIM>
00638 void ExtendedBidomainTissue<SPACE_DIM>::SetAmFirstCell(double value)
00639 {
00640     mAmFirstCell = value;
00641 }
00642 
00643 template <unsigned SPACE_DIM>
00644 void ExtendedBidomainTissue<SPACE_DIM>::SetAmSecondCell(double value)
00645 {
00646     mAmSecondCell = value;
00647 }
00648 
00649 template <unsigned SPACE_DIM>
00650 void ExtendedBidomainTissue<SPACE_DIM>::SetAmGap(double value)
00651 {
00652     mAmGap = value;
00653 }
00654 
00655 template <unsigned SPACE_DIM>
00656 void ExtendedBidomainTissue<SPACE_DIM>::SetGGap(double value)
00657 {
00658     mGGap = value;
00659 }
00660 
00661 template <unsigned SPACE_DIM>
00662 void ExtendedBidomainTissue<SPACE_DIM>::SetCmFirstCell(double value)
00663 {
00664     mCmFirstCell = value;
00665 }
00666 
00667 template <unsigned SPACE_DIM>
00668 void ExtendedBidomainTissue<SPACE_DIM>::SetCmSecondCell(double value)
00669 {
00670     mCmSecondCell = value;
00671 }
00672 
00674 // Explicit instantiation
00676 
00677 template class ExtendedBidomainTissue<1>;
00678 template class ExtendedBidomainTissue<2>;
00679 template class ExtendedBidomainTissue<3>;
00680 
00681 // Serialization for Boost >= 1.36
00682 #include "SerializationExportWrapperForCpp.hpp"
00683 EXPORT_TEMPLATE_CLASS_SAME_DIMS(ExtendedBidomainTissue)

Generated by  doxygen 1.6.2