AbstractCardiacPde.hpp
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 #ifndef ABSTRACTCARDIACPDE_HPP_
00029 #define ABSTRACTCARDIACPDE_HPP_
00030
00031 #include <set>
00032 #include <vector>
00033 #include "ChasteSerialization.hpp"
00034 #include "ClassIsAbstract.hpp"
00035 #include <boost/serialization/base_object.hpp>
00036 #include <boost/shared_ptr.hpp>
00037 #include <boost/serialization/shared_ptr.hpp>
00038 #include <boost/serialization/vector.hpp>
00039 #include <boost/serialization/string.hpp>
00040
00041 #include <boost/numeric/ublas/matrix.hpp>
00042
00043 #include "AbstractCardiacCell.hpp"
00044 #include "AbstractCardiacCellFactory.hpp"
00045 #include "AbstractConductivityTensors.hpp"
00046
00047 #include "ReplicatableVector.hpp"
00048 #include "HeartConfig.hpp"
00049 #include "ArchiveLocationInfo.hpp"
00050 #include "AbstractDynamicallyLoadableEntity.hpp"
00051 #include "DynamicModelLoaderRegistry.hpp"
00052
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00075 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM = ELEMENT_DIM>
00076 class AbstractCardiacPde
00077 {
00078 private:
00079
00081 friend class boost::serialization::access;
00088 template<class Archive>
00089 void serialize(Archive & archive, const unsigned int version)
00090 {
00091
00092
00093
00094
00095
00096
00097 archive & mDoCacheReplication;
00098 archive & mDoOneCacheReplication;
00099 (*ProcessSpecificArchive<Archive>::Get()) & mpDistributedVectorFactory;
00100
00101
00102 assert(mpDistributedVectorFactory->GetLow()==mpMesh->GetDistributedVectorFactory()->GetLow());
00103 assert(mpDistributedVectorFactory->GetLocalOwnership()==mpMesh->GetDistributedVectorFactory()->GetLocalOwnership());
00104
00105 }
00106
00110 void CreateIntracellularConductivityTensor();
00111
00112 protected:
00113
00115 AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>* mpMesh;
00116
00118 AbstractConductivityTensors<SPACE_DIM> *mpIntracellularConductivityTensors;
00119
00121 std::vector< AbstractCardiacCell* > mCellsDistributed;
00122
00127 ReplicatableVector mIionicCacheReplicated;
00128
00133 ReplicatableVector mIntracellularStimulusCacheReplicated;
00134
00141 const unsigned mStride;
00142
00144 HeartConfig* mpConfig;
00145
00155 bool mDoCacheReplication;
00156
00162 bool mDoOneCacheReplication;
00163
00172 DistributedVectorFactory* mpDistributedVectorFactory;
00173
00177 bool mMeshUnarchived;
00178
00183 void DeleteCells(bool deleteFakeCells);
00184
00185 public:
00193 AbstractCardiacPde(AbstractCardiacCellFactory<ELEMENT_DIM,SPACE_DIM>* pCellFactory,
00194 const unsigned stride=1);
00195
00203 AbstractCardiacPde(std::vector<AbstractCardiacCell*>& rCellsDistributed,
00204 AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>* pMesh,
00205 const unsigned stride);
00206
00208 virtual ~AbstractCardiacPde();
00209
00220 void MergeCells(const std::vector<AbstractCardiacCell*>& rOtherCells);
00221
00228 void SetCacheReplication(bool doCacheReplication);
00229
00235 bool GetDoCacheReplication();
00236
00240 const c_matrix<double, SPACE_DIM, SPACE_DIM>& rGetIntracellularConductivityTensor(unsigned elementIndex);
00241
00250 AbstractCardiacCell* GetCardiacCell( unsigned globalIndex );
00251
00266 virtual void SolveCellSystems(Vec existingSolution, double time, double nextTime);
00267
00269 ReplicatableVector& rGetIionicCacheReplicated();
00270
00272 ReplicatableVector& rGetIntracellularStimulusCacheReplicated();
00273
00274
00282 void UpdateCaches(unsigned globalIndex, unsigned localIndex, double nextTime);
00283
00287 void ReplicateCaches();
00288
00292 const std::vector<AbstractCardiacCell*>& rGetCellsDistributed() const;
00293
00299 const AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>* pGetMesh() const;
00300
00312 template<class Archive>
00313 void SaveCardiacCells(Archive & archive, const unsigned int version) const
00314 {
00315 Archive& r_archive = *ProcessSpecificArchive<Archive>::Get();
00316 const std::vector<AbstractCardiacCell*> & r_cells_distributed = rGetCellsDistributed();
00317 r_archive & mpDistributedVectorFactory;
00318 const unsigned num_cells = r_cells_distributed.size();
00319 r_archive & num_cells;
00320 for (unsigned i=0; i<num_cells; i++)
00321 {
00322 AbstractDynamicallyLoadableEntity* p_entity = dynamic_cast<AbstractDynamicallyLoadableEntity*>(r_cells_distributed[i]);
00323 bool is_dynamic = (p_entity != NULL);
00324 r_archive & is_dynamic;
00325 if (is_dynamic)
00326 {
00327 #ifdef CHASTE_CAN_CHECKPOINT_DLLS
00328 r_archive & p_entity->GetLoader()->GetLoadableModulePath();
00329 #else
00330
00331 NEVER_REACHED;
00332 #endif // CHASTE_CAN_CHECKPOINT_DLLS
00333 }
00334 r_archive & r_cells_distributed[i];
00335 }
00336 }
00337
00349 template<class Archive>
00350 static void LoadCardiacCells(Archive & archive, const unsigned int version,
00351 std::vector<AbstractCardiacCell*>& rCells,
00352 AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>* pMesh)
00353 {
00354 DistributedVectorFactory* p_factory;
00355 archive & p_factory;
00356 unsigned num_cells;
00357 archive & num_cells;
00358 rCells.resize(p_factory->GetLocalOwnership());
00359 #ifndef NDEBUG
00360
00361 for (unsigned i=0; i<rCells.size(); i++)
00362 {
00363 assert(rCells[i] == NULL);
00364 }
00365 #endif
00366
00367
00368
00369
00370
00371 unsigned index_low = p_factory->GetOriginalFactory() ? p_factory->GetOriginalFactory()->GetLow() : p_factory->GetLow();
00372
00373
00374 std::set<FakeBathCell*> fake_bath_cells_non_local, fake_bath_cells_local;
00375
00376 for (unsigned local_index=0; local_index<num_cells; local_index++)
00377 {
00378
00379 unsigned original_global_index = index_low + local_index;
00380 const std::vector<unsigned>& r_permutation = pMesh->rGetNodePermutation();
00381 unsigned new_global_index;
00382 if (r_permutation.empty())
00383 {
00384 new_global_index = original_global_index;
00385 }
00386 else
00387 {
00389
00390 NEVER_REACHED;
00391 }
00392 unsigned new_local_index = new_global_index - p_factory->GetLow();
00393 bool local = p_factory->IsGlobalIndexLocal(new_global_index);
00394
00395 bool is_dynamic;
00396 archive & is_dynamic;
00397 if (is_dynamic)
00398 {
00399 #ifdef CHASTE_CAN_CHECKPOINT_DLLS
00400
00401
00402
00403 std::string shared_object_path;
00404 archive & shared_object_path;
00405 DynamicModelLoaderRegistry::Instance()->GetLoader(shared_object_path);
00406 #else
00407
00408
00409
00410 NEVER_REACHED;
00411 #endif // CHASTE_CAN_CHECKPOINT_DLLS
00412 }
00413 AbstractCardiacCell* p_cell;
00414 archive & p_cell;
00415
00416 FakeBathCell* p_fake = dynamic_cast<FakeBathCell*>(p_cell);
00417 if (local)
00418 {
00419 rCells[new_local_index] = p_cell;
00420 if (p_fake)
00421 {
00422 fake_bath_cells_local.insert(p_fake);
00423 }
00424 }
00425 else
00426 {
00427 if (p_fake)
00428 {
00429 fake_bath_cells_non_local.insert(p_fake);
00430 }
00431 else
00432 {
00433
00434 delete p_cell;
00435 }
00436 }
00437 }
00438
00439
00440 if (!fake_bath_cells_non_local.empty())
00441 {
00442 for (std::set<FakeBathCell*>::iterator it = fake_bath_cells_non_local.begin();
00443 it != fake_bath_cells_non_local.end();
00444 ++it)
00445 {
00446 if (fake_bath_cells_local.find(*it) == fake_bath_cells_local.end())
00447 {
00448 delete (*it);
00449 }
00450 }
00451 }
00452 }
00453 };
00454
00455 TEMPLATED_CLASS_IS_ABSTRACT_2_UNSIGNED(AbstractCardiacPde);
00456
00457 #endif
00458