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