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
00031
00032
00033
00034
00035
00036
00037 #ifndef EXTENDEDBIDOMAINTISSUE_HPP_
00038 #define EXTENDEDBIDOMAINTISSUE_HPP_
00039
00040 #include "ChasteSerialization.hpp"
00041 #include <boost/serialization/base_object.hpp>
00042
00043 #include <vector>
00044 #include "UblasMatrixInclude.hpp"
00045
00046 #include "AbstractStimulusFunction.hpp"
00047 #include "AbstractStimulusFactory.hpp"
00048 #include "AbstractConductivityTensors.hpp"
00049
00050 #include "AbstractCardiacTissue.hpp"
00051
00076 template <unsigned SPACE_DIM>
00077 class ExtendedBidomainTissue : public virtual AbstractCardiacTissue<SPACE_DIM>
00078 {
00079 private:
00080 friend class TestExtendedBidomainTissue;
00081
00083 friend class boost::serialization::access;
00090 template<class Archive>
00091 void serialize(Archive & archive, const unsigned int version)
00092 {
00093 archive & boost::serialization::base_object<AbstractCardiacTissue<SPACE_DIM> >(*this);
00094
00095
00096 archive & mAmFirstCell;
00097 archive & mAmSecondCell;
00098 archive & mAmGap;
00099 archive & mCmFirstCell;
00100 archive & mCmSecondCell;
00101 archive & mGGap;
00102 archive & mUserSuppliedExtracellularStimulus;
00103 }
00104
00106 AbstractConductivityTensors<SPACE_DIM, SPACE_DIM> *mpIntracellularConductivityTensorsSecondCell;
00107
00112 c_vector<double, SPACE_DIM> mIntracellularConductivitiesSecondCell;
00113
00114
00116 AbstractConductivityTensors<SPACE_DIM, SPACE_DIM> *mpExtracellularConductivityTensors;
00117
00122 ReplicatableVector mExtracellularStimulusCacheReplicated;
00123
00128 ReplicatableVector mGgapCacheReplicated;
00129
00134 ReplicatableVector mIionicCacheReplicatedSecondCell;
00135
00140 ReplicatableVector mIntracellularStimulusCacheReplicatedSecondCell;
00141
00143 std::vector< AbstractCardiacCellInterface* > mCellsDistributedSecondCell;
00144
00146 std::vector<boost::shared_ptr<AbstractStimulusFunction> > mExtracellularStimuliDistributed;
00147
00149 std::vector<double> mGgapDistributed;
00150
00152 double mAmFirstCell;
00154 double mAmSecondCell;
00156 double mAmGap;
00158 double mCmFirstCell;
00160 double mCmSecondCell;
00162 double mGGap;
00163
00168 bool mUserSuppliedExtracellularStimulus;
00169
00173 void CreateExtracellularConductivityTensors();
00174
00189 void UpdateAdditionalCaches(unsigned globalIndex, unsigned localIndex, double nextTime);
00190
00201 void ReplicateAdditionalCaches();
00202
00204 std::vector<boost::shared_ptr<AbstractChasteRegion<SPACE_DIM> > > mGgapHeterogeneityRegions;
00206 std::vector<double> mGgapValues;
00207
00208 public:
00209
00216 ExtendedBidomainTissue(AbstractCardiacCellFactory<SPACE_DIM>* pCellFactory, AbstractCardiacCellFactory<SPACE_DIM>* pCellFactorySecondCell, AbstractStimulusFactory<SPACE_DIM>* pExtracellularStimulusFactory);
00217
00227 ExtendedBidomainTissue(std::vector<AbstractCardiacCellInterface*> & rCellsDistributed, std::vector<AbstractCardiacCellInterface*> & rSecondCellsDistributed, std::vector<boost::shared_ptr<AbstractStimulusFunction> > & rExtraStimuliDistributed, std::vector<double>& rGgapsDistributed, AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>* pMesh, c_vector<double, SPACE_DIM> intracellularConductivitiesSecondCell);
00228
00232 virtual ~ExtendedBidomainTissue();
00233
00239 void SetIntracellularConductivitiesSecondCell(c_vector<double, SPACE_DIM> conductivities);
00240
00246 AbstractCardiacCellInterface* GetCardiacSecondCell( unsigned globalIndex );
00247
00248
00254 boost::shared_ptr<AbstractStimulusFunction> GetExtracellularStimulus( unsigned globalIndex );
00255
00259 const std::vector<AbstractCardiacCellInterface*>& rGetSecondCellsDistributed() const;
00260
00264 const std::vector<double>& rGetGapsDistributed() const;
00265
00266
00270 const std::vector<boost::shared_ptr<AbstractStimulusFunction> >& rGetExtracellularStimulusDistributed() const;
00271
00272
00276 c_vector<double, SPACE_DIM> GetIntracellularConductivitiesSecondCell() const;
00277
00287 virtual void SolveCellSystems(Vec existingSolution, double time, double nextTime, bool updateVoltage = false);
00288
00292 void CreateIntracellularConductivityTensorSecondCell();
00293
00300 void SetGgapHeterogeneities ( std::vector<boost::shared_ptr<AbstractChasteRegion<SPACE_DIM> > > & rGgapHeterogeneityRegions, std::vector<double> rGgapValues);
00301
00307 void CreateGGapConductivities();
00308
00313 const c_matrix<double, SPACE_DIM, SPACE_DIM>& rGetExtracellularConductivityTensor(unsigned elementIndex);
00314
00319 const c_matrix<double, SPACE_DIM, SPACE_DIM>& rGetIntracellularConductivityTensorSecondCell(unsigned elementIndex);
00320
00321
00323 ReplicatableVector& rGetIionicCacheReplicatedSecondCell();
00324
00326 ReplicatableVector& rGetIntracellularStimulusCacheReplicatedSecondCell();
00327
00329 ReplicatableVector& rGetExtracellularStimulusCacheReplicated();
00330
00332 ReplicatableVector& rGetGgapCacheReplicated();
00333
00337 double GetAmFirstCell();
00338
00342 double GetAmSecondCell();
00343
00347 double GetAmGap();
00348
00352 double GetCmFirstCell();
00353
00357 double GetCmSecondCell();
00358
00362 double GetGGap();
00363
00367 void SetAmFirstCell(double value);
00368
00372 void SetAmSecondCell(double value);
00373
00377 void SetAmGap(double value);
00378
00382 void SetCmFirstCell(double value);
00383
00387 void SetCmSecondCell(double value);
00388
00392 void SetGGap(double value);
00393
00401 bool HasTheUserSuppliedExtracellularStimulus();
00402
00410 void SetUserSuppliedExtracellularStimulus(bool flag);
00411
00412
00419 template<class Archive>
00420 void SaveExtendedBidomainCells(Archive & archive, const unsigned int version) const
00421 {
00422 Archive& r_archive = *ProcessSpecificArchive<Archive>::Get();
00423 const std::vector<AbstractCardiacCellInterface*> & r_cells_distributed = this->rGetCellsDistributed();
00424 const std::vector<AbstractCardiacCellInterface*> & r_cells_distributed_second_cell = rGetSecondCellsDistributed();
00425 const std::vector<double> & r_ggaps_distributed = rGetGapsDistributed();
00426
00427 r_archive & this->mpDistributedVectorFactory;
00428 const unsigned num_cells = r_cells_distributed.size();
00429 r_archive & num_cells;
00430 for (unsigned i=0; i<num_cells; i++)
00431 {
00432 AbstractDynamicallyLoadableEntity* p_entity = dynamic_cast<AbstractDynamicallyLoadableEntity*>(r_cells_distributed[i]);
00433 bool is_dynamic = (p_entity != NULL);
00434 r_archive & is_dynamic;
00435 if (is_dynamic)
00436 {
00437 #ifdef CHASTE_CAN_CHECKPOINT_DLLS
00439 NEVER_REACHED;
00440
00441 #else
00442
00443 NEVER_REACHED;
00444 #endif // CHASTE_CAN_CHECKPOINT_DLLS
00445 }
00446 r_archive & r_cells_distributed[i];
00447 r_archive & r_cells_distributed_second_cell[i];
00448 r_archive & r_ggaps_distributed[i];
00449 }
00450 }
00451
00466 template<class Archive>
00467 static void LoadExtendedBidomainCells(Archive & archive, const unsigned int version,
00468 std::vector<AbstractCardiacCellInterface*>& rCells,
00469 std::vector<AbstractCardiacCellInterface*>& rSecondCells,
00470 std::vector<double>& rGgaps,
00471 AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>* pMesh)
00472 {
00473 assert(pMesh!=NULL);
00474 DistributedVectorFactory* p_factory;
00475 archive & p_factory;
00476 unsigned num_cells;
00477 archive & num_cells;
00478 rCells.resize(p_factory->GetLocalOwnership());
00479 rSecondCells.resize(p_factory->GetLocalOwnership());
00480 rGgaps.resize(p_factory->GetLocalOwnership());
00481 #ifndef NDEBUG
00482
00483 assert(rCells.size() == rSecondCells.size());
00484 for (unsigned i=0; i<rCells.size(); i++)
00485 {
00486 assert(rCells[i] == NULL);
00487 assert(rSecondCells[i] == NULL);
00488 }
00489 #endif
00490
00491
00492
00493
00494
00495 unsigned index_low = p_factory->GetOriginalFactory() ? p_factory->GetOriginalFactory()->GetLow() : p_factory->GetLow();
00496
00497 for (unsigned local_index=0; local_index<num_cells; local_index++)
00498 {
00499 unsigned global_index = index_low + local_index;
00500 unsigned new_local_index = global_index - p_factory->GetLow();
00501 bool local = p_factory->IsGlobalIndexLocal(global_index);
00502
00503 bool is_dynamic;
00504 archive & is_dynamic;
00505
00506 if (is_dynamic)
00507 {
00508 #ifdef CHASTE_CAN_CHECKPOINT_DLLS
00510 NEVER_REACHED;
00511
00512
00513
00514
00515
00516
00517 #else
00518
00519
00520
00521 NEVER_REACHED;
00522 #endif // CHASTE_CAN_CHECKPOINT_DLLS
00523 }
00524
00525 AbstractCardiacCellInterface* p_cell;
00526 AbstractCardiacCellInterface* p_second_cell;
00527 double g_gap;
00528 archive & p_cell;
00529 archive & p_second_cell;
00530 archive & g_gap;
00531 if (local)
00532 {
00533 rCells[new_local_index] = p_cell;
00534 rSecondCells[new_local_index] = p_second_cell;
00535 rGgaps[new_local_index] = g_gap;
00536 }
00537 else
00538 {
00539
00540 NEVER_REACHED;
00541
00542
00543
00544 }
00545 }
00546 }
00547
00554 template<class Archive>
00555 void SaveExtracellularStimulus(Archive & archive, const unsigned int version) const
00556 {
00557 Archive& r_archive = *ProcessSpecificArchive<Archive>::Get();
00558 const std::vector<boost::shared_ptr<AbstractStimulusFunction> > & r_stimulus_distributed = rGetExtracellularStimulusDistributed();
00559 r_archive & this->mpDistributedVectorFactory;
00560 const unsigned num_cells = r_stimulus_distributed.size();
00561 r_archive & num_cells;
00562 for (unsigned i=0; i<num_cells; i++)
00563 {
00564 r_archive & r_stimulus_distributed[i];
00565 }
00566 }
00567
00576 template<class Archive>
00577 void LoadExtracellularStimulus(Archive & archive, const unsigned int version,
00578 std::vector<boost::shared_ptr<AbstractStimulusFunction> >& rStimuli,
00579 AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>* pMesh)
00580 {
00581
00582 DistributedVectorFactory* p_factory;
00583 archive & p_factory;
00584 unsigned num_cells;
00585 archive & num_cells;
00586 rStimuli.resize(p_factory->GetLocalOwnership());
00587 #ifndef NDEBUG
00588
00589 for (unsigned i=0; i<rStimuli.size(); i++)
00590 {
00591 assert(rStimuli[i] == NULL);
00592 }
00593 #endif
00594
00595
00596
00597
00598
00599 unsigned index_low = p_factory->GetOriginalFactory() ? p_factory->GetOriginalFactory()->GetLow() : p_factory->GetLow();
00600
00601 assert(pMesh!=NULL);
00602
00603 for (unsigned local_index=0; local_index<num_cells; local_index++)
00604 {
00605 unsigned global_index = index_low + local_index;
00606
00607 unsigned new_local_index = global_index - p_factory->GetLow();
00608 bool local = p_factory->IsGlobalIndexLocal(global_index);
00609
00610 boost::shared_ptr<AbstractStimulusFunction> p_stim;
00611 archive & p_stim;
00612
00613 if (local)
00614 {
00615 rStimuli[new_local_index] = p_stim;
00616 }
00617
00618 }
00619 }
00620 };
00621
00622
00623 #include "SerializationExportWrapper.hpp"
00624 EXPORT_TEMPLATE_CLASS_SAME_DIMS(ExtendedBidomainTissue)
00625
00626 namespace boost
00627 {
00628 namespace serialization
00629 {
00630
00631 template<class Archive, unsigned SPACE_DIM>
00632 inline void save_construct_data(
00633 Archive & ar, const ExtendedBidomainTissue<SPACE_DIM> * t, const unsigned int file_version)
00634 {
00635
00636 c_vector<double, SPACE_DIM> intracellular_conductivities_second_cell = t->GetIntracellularConductivitiesSecondCell();
00637
00638 for (unsigned i = 0; i < SPACE_DIM; i++)
00639 {
00640 ar & intracellular_conductivities_second_cell(i);
00641 }
00642
00643 const AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>* p_mesh = t->pGetMesh();
00644 ar & p_mesh;
00645
00646
00647
00648 t->SaveExtendedBidomainCells(ar, file_version);
00649 t->SaveExtracellularStimulus(ar, file_version);
00650
00651
00652
00653 HeartConfig* p_config = HeartConfig::Instance();
00654 ar & *p_config;
00655 ar & p_config;
00656 }
00657
00662 template<class Archive, unsigned SPACE_DIM>
00663 inline void load_construct_data(
00664 Archive & ar, ExtendedBidomainTissue<SPACE_DIM> * t, const unsigned int file_version)
00665 {
00666
00667 c_vector<double, SPACE_DIM> intra_cond_second_cell;
00668
00669 for (unsigned i = 0; i < SPACE_DIM; i++)
00670 {
00671 double cond;
00672 ar & cond;
00673 intra_cond_second_cell(i) = cond;
00674 }
00675
00676
00677 std::vector<AbstractCardiacCellInterface*> cells_distributed;
00678 std::vector<AbstractCardiacCellInterface*> cells_distributed_second_cell;
00679 std::vector<boost::shared_ptr<AbstractStimulusFunction> > extra_stim;
00680 std::vector<double> g_gaps;
00681 AbstractTetrahedralMesh<SPACE_DIM,SPACE_DIM>* p_mesh;
00682 ar & p_mesh;
00683
00684
00685 t->LoadExtendedBidomainCells(
00686 *ProcessSpecificArchive<Archive>::Get(), file_version, cells_distributed, cells_distributed_second_cell, g_gaps, p_mesh);
00687
00688 t->LoadExtracellularStimulus(
00689 *ProcessSpecificArchive<Archive>::Get(), file_version, extra_stim, p_mesh);
00690
00691
00692
00693
00694 HeartConfig* p_config = HeartConfig::Instance();
00695 ar & *p_config;
00696 ar & p_config;
00697
00698 ::new(t)ExtendedBidomainTissue<SPACE_DIM>(cells_distributed, cells_distributed_second_cell, extra_stim, g_gaps, p_mesh, intra_cond_second_cell);
00699 }
00700 }
00701 }
00702
00703
00704
00705 #endif