ExtendedBidomainTissue.cpp

00001 /*
00002 
00003 Copyright (c) 2005-2014, 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 phi_i_first_cell(dist_solution, 0);
00517     DistributedVector::Stripe phi_i_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         double voltage_first_cell = phi_i_first_cell[index] - phi_e[index];
00525         double voltage_second_cell = phi_i_second_cell[index] - phi_e[index];
00526 
00527         // overwrite the voltage with the input value
00528         this->mCellsDistributed[index.Local]->SetVoltage( voltage_first_cell );
00529         mCellsDistributedSecondCell[index.Local]->SetVoltage( voltage_second_cell );
00530         try
00531         {
00532             // solve
00533             // Note: Voltage should not be updated. GetIIonic will be called later
00534             // and needs the old voltage. The voltage will be updated from the pde.
00535             this->mCellsDistributed[index.Local]->ComputeExceptVoltage(time, nextTime);
00536             mCellsDistributedSecondCell[index.Local]->ComputeExceptVoltage(time, nextTime);
00537         }
00538         catch (Exception &e)
00539         {
00540 #define COVERAGE_IGNORE
00541             PetscTools::ReplicateException(true);
00542             throw e;
00543 #undef COVERAGE_IGNORE
00544         }
00545 
00546         // update the Iionic and stimulus caches
00547         this->UpdateCaches(index.Global, index.Local, nextTime);//in parent class
00548         UpdateAdditionalCaches(index.Global, index.Local, nextTime);//extended bidomain specific caches
00549     }
00550     PetscTools::ReplicateException(false);
00551     HeartEventHandler::EndEvent(HeartEventHandler::SOLVE_ODES);
00552 
00553     HeartEventHandler::BeginEvent(HeartEventHandler::COMMUNICATION);
00554     if ( this->mDoCacheReplication )
00555     {
00556         this->ReplicateCaches();
00557         ReplicateAdditionalCaches();//extended bidomain specific caches
00558     }
00559     HeartEventHandler::EndEvent(HeartEventHandler::COMMUNICATION);
00560 }
00561 
00562 template <unsigned SPACE_DIM>
00563 void ExtendedBidomainTissue<SPACE_DIM>::UpdateAdditionalCaches(unsigned globalIndex, unsigned localIndex, double nextTime)
00564 {
00565     mIionicCacheReplicatedSecondCell[globalIndex] = mCellsDistributedSecondCell[localIndex]->GetIIonic();
00566     mIntracellularStimulusCacheReplicatedSecondCell[globalIndex] = mCellsDistributedSecondCell[localIndex]->GetIntracellularStimulus(nextTime);
00567     mExtracellularStimulusCacheReplicated[globalIndex] = mExtracellularStimuliDistributed[localIndex]->GetStimulus(nextTime);
00568     mGgapCacheReplicated[globalIndex] = mGgapDistributed[localIndex];
00569 }
00570 
00571 template <unsigned SPACE_DIM>
00572 void ExtendedBidomainTissue<SPACE_DIM>::ReplicateAdditionalCaches()
00573 {
00574     mIionicCacheReplicatedSecondCell.Replicate(this->mpDistributedVectorFactory->GetLow(), this->mpDistributedVectorFactory->GetHigh());
00575     mIntracellularStimulusCacheReplicatedSecondCell.Replicate(this->mpDistributedVectorFactory->GetLow(), this->mpDistributedVectorFactory->GetHigh());
00576     mExtracellularStimulusCacheReplicated.Replicate(this->mpDistributedVectorFactory->GetLow(), this->mpDistributedVectorFactory->GetHigh());
00577     mGgapCacheReplicated.Replicate(this->mpDistributedVectorFactory->GetLow(), this->mpDistributedVectorFactory->GetHigh());
00578 }
00579 
00580 template <unsigned SPACE_DIM>
00581 ReplicatableVector& ExtendedBidomainTissue<SPACE_DIM>::rGetIionicCacheReplicatedSecondCell()
00582 {
00583     return mIionicCacheReplicatedSecondCell;
00584 }
00585 
00586 template <unsigned SPACE_DIM>
00587 ReplicatableVector& ExtendedBidomainTissue<SPACE_DIM>::rGetIntracellularStimulusCacheReplicatedSecondCell()
00588 {
00589     return mIntracellularStimulusCacheReplicatedSecondCell;
00590 }
00591 
00592 template <unsigned SPACE_DIM>
00593 ReplicatableVector& ExtendedBidomainTissue<SPACE_DIM>::rGetExtracellularStimulusCacheReplicated()
00594 {
00595     return mExtracellularStimulusCacheReplicated;
00596 }
00597 
00598 template <unsigned SPACE_DIM>
00599 ReplicatableVector& ExtendedBidomainTissue<SPACE_DIM>::rGetGgapCacheReplicated()
00600 {
00601     return mGgapCacheReplicated;
00602 }
00603 
00604 template <unsigned SPACE_DIM>
00605 double ExtendedBidomainTissue<SPACE_DIM>::GetAmFirstCell()
00606 {
00607     return mAmFirstCell;
00608 }
00609 
00610 template <unsigned SPACE_DIM>
00611 double ExtendedBidomainTissue<SPACE_DIM>::GetAmSecondCell()
00612 {
00613     return mAmSecondCell;
00614 }
00615 
00616 template <unsigned SPACE_DIM>
00617 double ExtendedBidomainTissue<SPACE_DIM>::GetAmGap()
00618 {
00619     return mAmGap;
00620 }
00621 
00622 template <unsigned SPACE_DIM>
00623 double ExtendedBidomainTissue<SPACE_DIM>::GetCmFirstCell()
00624 {
00625     return mCmFirstCell;
00626 }
00627 
00628 template <unsigned SPACE_DIM>
00629 double ExtendedBidomainTissue<SPACE_DIM>::GetCmSecondCell()
00630 {
00631     return mCmSecondCell;
00632 }
00633 
00634 template <unsigned SPACE_DIM>
00635 double ExtendedBidomainTissue<SPACE_DIM>::GetGGap()
00636 {
00637     return mGGap;
00638 }
00639 
00640 template <unsigned SPACE_DIM>
00641 void ExtendedBidomainTissue<SPACE_DIM>::SetAmFirstCell(double value)
00642 {
00643     mAmFirstCell = value;
00644 }
00645 
00646 template <unsigned SPACE_DIM>
00647 void ExtendedBidomainTissue<SPACE_DIM>::SetAmSecondCell(double value)
00648 {
00649     mAmSecondCell = value;
00650 }
00651 
00652 template <unsigned SPACE_DIM>
00653 void ExtendedBidomainTissue<SPACE_DIM>::SetAmGap(double value)
00654 {
00655     mAmGap = value;
00656 }
00657 
00658 template <unsigned SPACE_DIM>
00659 void ExtendedBidomainTissue<SPACE_DIM>::SetGGap(double value)
00660 {
00661     mGGap = value;
00662 }
00663 
00664 template <unsigned SPACE_DIM>
00665 void ExtendedBidomainTissue<SPACE_DIM>::SetCmFirstCell(double value)
00666 {
00667     mCmFirstCell = value;
00668 }
00669 
00670 template <unsigned SPACE_DIM>
00671 void ExtendedBidomainTissue<SPACE_DIM>::SetCmSecondCell(double value)
00672 {
00673     mCmSecondCell = value;
00674 }
00675 
00677 // Explicit instantiation
00679 
00680 template class ExtendedBidomainTissue<1>;
00681 template class ExtendedBidomainTissue<2>;
00682 template class ExtendedBidomainTissue<3>;
00683 
00684 // Serialization for Boost >= 1.36
00685 #include "SerializationExportWrapperForCpp.hpp"
00686 EXPORT_TEMPLATE_CLASS_SAME_DIMS(ExtendedBidomainTissue)

Generated by  doxygen 1.6.2