00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef EXTENDEDBIDOMAINTISSUE_HPP_
00031 #define EXTENDEDBIDOMAINTISSUE_HPP_
00032
00033 #include "ChasteSerialization.hpp"
00034 #include <boost/serialization/base_object.hpp>
00035
00036 #include <vector>
00037 #include <boost/numeric/ublas/matrix.hpp>
00038
00039 #include "AbstractStimulusFunction.hpp"
00040 #include "AbstractStimulusFactory.hpp"
00041 #include "AbstractConductivityTensors.hpp"
00042
00043 #include "AbstractCardiacTissue.hpp"
00044
00069 template <unsigned SPACE_DIM>
00070 class ExtendedBidomainTissue : public virtual AbstractCardiacTissue<SPACE_DIM>
00071 {
00072 private:
00073 friend class TestExtendedBidomainTissue;
00074
00076 friend class boost::serialization::access;
00083 template<class Archive>
00084 void serialize(Archive & archive, const unsigned int version)
00085 {
00086 archive & boost::serialization::base_object<AbstractCardiacTissue<SPACE_DIM> >(*this);
00087
00088
00089 archive & mAmFirstCell;
00090 archive & mAmSecondCell;
00091 archive & mAmGap;
00092 archive & mCmFirstCell;
00093 archive & mCmSecondCell;
00094 archive & mGGap;
00095 archive & mUserSuppliedExtracellularStimulus;
00096 }
00097
00099 AbstractConductivityTensors<SPACE_DIM, SPACE_DIM> *mpIntracellularConductivityTensorsSecondCell;
00100
00105 c_vector<double, SPACE_DIM> mIntracellularConductivitiesSecondCell;
00106
00107
00109 AbstractConductivityTensors<SPACE_DIM, SPACE_DIM> *mpExtracellularConductivityTensors;
00110
00115 ReplicatableVector mExtracellularStimulusCacheReplicated;
00116
00121 ReplicatableVector mGgapCacheReplicated;
00122
00127 ReplicatableVector mIionicCacheReplicatedSecondCell;
00128
00133 ReplicatableVector mIntracellularStimulusCacheReplicatedSecondCell;
00134
00136 std::vector< AbstractCardiacCell* > mCellsDistributedSecondCell;
00137
00139 std::vector<boost::shared_ptr<AbstractStimulusFunction> > mExtracellularStimuliDistributed;
00140
00142 std::vector<double> mGgapDistributed;
00143
00145 double mAmFirstCell;
00147 double mAmSecondCell;
00149 double mAmGap;
00151 double mCmFirstCell;
00153 double mCmSecondCell;
00155 double mGGap;
00156
00161 bool mUserSuppliedExtracellularStimulus;
00162
00166 void CreateExtracellularConductivityTensors();
00167
00182 void UpdateAdditionalCaches(unsigned globalIndex, unsigned localIndex, double nextTime);
00183
00194 void ReplicateAdditionalCaches();
00195
00197 std::vector<boost::shared_ptr<AbstractChasteRegion<SPACE_DIM> > > mGgapHeterogeneityRegions;
00199 std::vector<double> mGgapValues;
00200
00201 public:
00202
00209 ExtendedBidomainTissue(AbstractCardiacCellFactory<SPACE_DIM>* pCellFactory, AbstractCardiacCellFactory<SPACE_DIM>* pCellFactorySecondCell, AbstractStimulusFactory<SPACE_DIM>* pExtracellularStimulusFactory);
00210
00220 ExtendedBidomainTissue(std::vector<AbstractCardiacCell*> & rCellsDistributed, std::vector<AbstractCardiacCell*> & rSecondCellsDistributed, std::vector<boost::shared_ptr<AbstractStimulusFunction> > & rExtraStimuliDistributed, std::vector<double>& rGgapsDistributed, AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>* pMesh, c_vector<double, SPACE_DIM> intracellularConductivitiesSecondCell);
00221
00225 ~ExtendedBidomainTissue();
00226
00232 void SetIntracellularConductivitiesSecondCell(c_vector<double, SPACE_DIM> conductivities);
00233
00239 AbstractCardiacCell* GetCardiacSecondCell( unsigned globalIndex );
00240
00241
00247 boost::shared_ptr<AbstractStimulusFunction> GetExtracellularStimulus( unsigned globalIndex );
00248
00252 const std::vector<AbstractCardiacCell*>& rGetSecondCellsDistributed() const;
00253
00257 const std::vector<double>& rGetGapsDistributed() const;
00258
00259
00263 const std::vector<boost::shared_ptr<AbstractStimulusFunction> >& rGetExtracellularStimulusDistributed() const;
00264
00265
00269 c_vector<double, SPACE_DIM> GetIntracellularConductivitiesSecondCell() const;
00270
00280 virtual void SolveCellSystems(Vec existingSolution, double time, double nextTime, bool updateVoltage = false);
00281
00285 void CreateIntracellularConductivityTensorSecondCell();
00286
00293 void SetGgapHeterogeneities ( std::vector<boost::shared_ptr<AbstractChasteRegion<SPACE_DIM> > > & rGgapHeterogeneityRegions, std::vector<double> rGgapValues);
00294
00300 void CreateGGapConductivities();
00301
00306 const c_matrix<double, SPACE_DIM, SPACE_DIM>& rGetExtracellularConductivityTensor(unsigned elementIndex);
00307
00312 const c_matrix<double, SPACE_DIM, SPACE_DIM>& rGetIntracellularConductivityTensorSecondCell(unsigned elementIndex);
00313
00314
00316 ReplicatableVector& rGetIionicCacheReplicatedSecondCell();
00317
00319 ReplicatableVector& rGetIntracellularStimulusCacheReplicatedSecondCell();
00320
00322 ReplicatableVector& rGetExtracellularStimulusCacheReplicated();
00323
00325 ReplicatableVector& rGetGgapCacheReplicated();
00326
00330 double GetAmFirstCell();
00331
00335 double GetAmSecondCell();
00336
00340 double GetAmGap();
00341
00345 double GetCmFirstCell();
00346
00350 double GetCmSecondCell();
00351
00355 double GetGGap();
00356
00360 void SetAmFirstCell(double value);
00361
00365 void SetAmSecondCell(double value);
00366
00370 void SetAmGap(double value);
00371
00375 void SetCmFirstCell(double value);
00376
00380 void SetCmSecondCell(double value);
00381
00385 void SetGGap(double value);
00386
00394 bool HasTheUserSuppliedExtracellularStimulus();
00395
00403 void SetUserSuppliedExtracellularStimulus(bool flag);
00404
00405
00412 template<class Archive>
00413 void SaveExtendedBidomainCells(Archive & archive, const unsigned int version) const
00414 {
00415 Archive& r_archive = *ProcessSpecificArchive<Archive>::Get();
00416 const std::vector<AbstractCardiacCell*> & r_cells_distributed = this->rGetCellsDistributed();
00417 const std::vector<AbstractCardiacCell*> & r_cells_distributed_second_cell = rGetSecondCellsDistributed();
00418 const std::vector<double> & r_ggaps_distributed = rGetGapsDistributed();
00419
00420 r_archive & this->mpDistributedVectorFactory;
00421 const unsigned num_cells = r_cells_distributed.size();
00422 r_archive & num_cells;
00423 for (unsigned i=0; i<num_cells; i++)
00424 {
00425 AbstractDynamicallyLoadableEntity* p_entity = dynamic_cast<AbstractDynamicallyLoadableEntity*>(r_cells_distributed[i]);
00426 bool is_dynamic = (p_entity != NULL);
00427 r_archive & is_dynamic;
00428 if (is_dynamic)
00429 {
00430 #ifdef CHASTE_CAN_CHECKPOINT_DLLS
00431 r_archive & p_entity->GetLoader()->GetLoadableModulePath();
00432 #else
00433
00434 NEVER_REACHED;
00435 #endif // CHASTE_CAN_CHECKPOINT_DLLS
00436 }
00437 r_archive & r_cells_distributed[i];
00438 r_archive & r_cells_distributed_second_cell[i];
00439 r_archive & r_ggaps_distributed[i];
00440 }
00441 }
00442
00457 template<class Archive>
00458 static void LoadExtendedBidomainCells(Archive & archive, const unsigned int version,
00459 std::vector<AbstractCardiacCell*>& rCells,
00460 std::vector<AbstractCardiacCell*>& rSecondCells,
00461 std::vector<double>& rGgaps,
00462 AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>* pMesh)
00463 {
00464 assert(pMesh!=NULL);
00465 DistributedVectorFactory* p_factory;
00466 archive & p_factory;
00467 unsigned num_cells;
00468 archive & num_cells;
00469 rCells.resize(p_factory->GetLocalOwnership());
00470 rSecondCells.resize(p_factory->GetLocalOwnership());
00471 rGgaps.resize(p_factory->GetLocalOwnership());
00472 #ifndef NDEBUG
00473
00474 assert(rCells.size() == rSecondCells.size());
00475 for (unsigned i=0; i<rCells.size(); i++)
00476 {
00477 assert(rCells[i] == NULL);
00478 assert(rSecondCells[i] == NULL);
00479 }
00480 #endif
00481
00482
00483
00484
00485
00486 unsigned index_low = p_factory->GetOriginalFactory() ? p_factory->GetOriginalFactory()->GetLow() : p_factory->GetLow();
00487
00488 for (unsigned local_index=0; local_index<num_cells; local_index++)
00489 {
00490 unsigned global_index = index_low + local_index;
00491 unsigned new_local_index = global_index - p_factory->GetLow();
00492 bool local = p_factory->IsGlobalIndexLocal(global_index);
00493
00494 bool is_dynamic;
00495 archive & is_dynamic;
00496
00497 if (is_dynamic)
00498 {
00499 #ifdef CHASTE_CAN_CHECKPOINT_DLLS
00500
00501
00502
00503 std::string shared_object_path;
00504 archive & shared_object_path;
00505 DynamicModelLoaderRegistry::Instance()->GetLoader(shared_object_path);
00506 #else
00507
00508
00509
00510 NEVER_REACHED;
00511 #endif // CHASTE_CAN_CHECKPOINT_DLLS
00512 }
00513
00514 AbstractCardiacCell* p_cell;
00515 AbstractCardiacCell* p_second_cell;
00516 double g_gap;
00517 archive & p_cell;
00518 archive & p_second_cell;
00519 archive & g_gap;
00520 if (local)
00521 {
00522 rCells[new_local_index] = p_cell;
00523 rSecondCells[new_local_index] = p_second_cell;
00524 rGgaps[new_local_index] = g_gap;
00525 }
00526 else
00527 {
00528
00529 NEVER_REACHED;
00530
00531
00532
00533 }
00534 }
00535 }
00536
00543 template<class Archive>
00544 void SaveExtracellularStimulus(Archive & archive, const unsigned int version) const
00545 {
00546 Archive& r_archive = *ProcessSpecificArchive<Archive>::Get();
00547 const std::vector<boost::shared_ptr<AbstractStimulusFunction> > & r_stimulus_distributed = rGetExtracellularStimulusDistributed();
00548 r_archive & this->mpDistributedVectorFactory;
00549 const unsigned num_cells = r_stimulus_distributed.size();
00550 r_archive & num_cells;
00551 for (unsigned i=0; i<num_cells; i++)
00552 {
00553 r_archive & r_stimulus_distributed[i];
00554 }
00555 }
00556
00565 template<class Archive>
00566 void LoadExtracellularStimulus(Archive & archive, const unsigned int version,
00567 std::vector<boost::shared_ptr<AbstractStimulusFunction> >& rStimuli,
00568 AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>* pMesh)
00569 {
00570
00571 DistributedVectorFactory* p_factory;
00572 archive & p_factory;
00573 unsigned num_cells;
00574 archive & num_cells;
00575 rStimuli.resize(p_factory->GetLocalOwnership());
00576 #ifndef NDEBUG
00577
00578 for (unsigned i=0; i<rStimuli.size(); i++)
00579 {
00580 assert(rStimuli[i] == NULL);
00581 }
00582 #endif
00583
00584
00585
00586
00587
00588 unsigned index_low = p_factory->GetOriginalFactory() ? p_factory->GetOriginalFactory()->GetLow() : p_factory->GetLow();
00589
00590 assert(pMesh!=NULL);
00591
00592 for (unsigned local_index=0; local_index<num_cells; local_index++)
00593 {
00594 unsigned global_index = index_low + local_index;
00595
00596 unsigned new_local_index = global_index - p_factory->GetLow();
00597 bool local = p_factory->IsGlobalIndexLocal(global_index);
00598
00599 boost::shared_ptr<AbstractStimulusFunction> p_stim;
00600 archive & p_stim;
00601
00602 if (local)
00603 {
00604 rStimuli[new_local_index] = p_stim;
00605 }
00606
00607 }
00608 }
00609 };
00610
00611
00612 #include "SerializationExportWrapper.hpp"
00613 EXPORT_TEMPLATE_CLASS_SAME_DIMS(ExtendedBidomainTissue)
00614
00615 namespace boost
00616 {
00617 namespace serialization
00618 {
00619
00620 template<class Archive, unsigned SPACE_DIM>
00621 inline void save_construct_data(
00622 Archive & ar, const ExtendedBidomainTissue<SPACE_DIM> * t, const unsigned int file_version)
00623 {
00624
00625 c_vector<double, SPACE_DIM> intracellular_conductivities_second_cell = t->GetIntracellularConductivitiesSecondCell();
00626
00627 for (unsigned i = 0; i < SPACE_DIM; i++)
00628 {
00629 ar & intracellular_conductivities_second_cell(i);
00630 }
00631
00632 const AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>* p_mesh = t->pGetMesh();
00633 ar & p_mesh;
00634
00635
00636
00637 t->SaveExtendedBidomainCells(ar, file_version);
00638 t->SaveExtracellularStimulus(ar, file_version);
00639
00640
00641
00642 HeartConfig* p_config = HeartConfig::Instance();
00643 ar & *p_config;
00644 ar & p_config;
00645 }
00646
00651 template<class Archive, unsigned SPACE_DIM>
00652 inline void load_construct_data(
00653 Archive & ar, ExtendedBidomainTissue<SPACE_DIM> * t, const unsigned int file_version)
00654 {
00655
00656 c_vector<double, SPACE_DIM> intra_cond_second_cell;
00657
00658 for (unsigned i = 0; i < SPACE_DIM; i++)
00659 {
00660 double cond;
00661 ar & cond;
00662 intra_cond_second_cell(i) = cond;
00663 }
00664
00665
00666 std::vector<AbstractCardiacCell*> cells_distributed;
00667 std::vector<AbstractCardiacCell*> cells_distributed_second_cell;
00668 std::vector<boost::shared_ptr<AbstractStimulusFunction> > extra_stim;
00669 std::vector<double> g_gaps;
00670 AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>* p_mesh;
00671 ar & p_mesh;
00672
00673
00674 t->LoadExtendedBidomainCells(
00675 *ProcessSpecificArchive<Archive>::Get(), file_version, cells_distributed, cells_distributed_second_cell, g_gaps, p_mesh);
00676
00677 t->LoadExtracellularStimulus(
00678 *ProcessSpecificArchive<Archive>::Get(), file_version, extra_stim, p_mesh);
00679
00680
00681
00682
00683 HeartConfig* p_config = HeartConfig::Instance();
00684 ar & *p_config;
00685 ar & p_config;
00686
00687 ::new(t)ExtendedBidomainTissue<SPACE_DIM>(cells_distributed, cells_distributed_second_cell, extra_stim, g_gaps, p_mesh, intra_cond_second_cell);
00688 }
00689 }
00690 }
00691
00692
00693
00694 #endif