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 BIDOMAINPROBLEM_HPP_
00031 #define BIDOMAINPROBLEM_HPP_
00032
00033 #include "ChasteSerialization.hpp"
00034 #include <boost/serialization/base_object.hpp>
00035
00036 #include <vector>
00037 #include <boost/shared_ptr.hpp>
00038 #include <boost/serialization/shared_ptr.hpp>
00039
00040 #include "AbstractCardiacProblem.hpp"
00041 #include "AbstractCardiacTissue.hpp"
00042 #include "AbstractBidomainSolver.hpp"
00043 #include "AbstractCardiacCellFactory.hpp"
00044 #include "Electrodes.hpp"
00045 #include "BidomainTissue.hpp"
00046 #include "HeartRegionCodes.hpp"
00047 #include "DistributedTetrahedralMesh.hpp"
00048
00057 template<unsigned DIM>
00058 class BidomainProblem : public AbstractCardiacProblem<DIM,DIM, 2>
00059 {
00061 friend class boost::serialization::access;
00062
00063
00064 friend class TestPCTwoLevelsBlockDiagonal;
00065
00072 template<class Archive>
00073 void save(Archive & archive, const unsigned int version) const
00074 {
00075 archive & boost::serialization::base_object<AbstractCardiacProblem<DIM, DIM, 2> >(*this);
00076 archive & mpBidomainTissue;
00077
00078 archive & mRowForAverageOfPhiZeroed;
00079 archive & mHasBath;
00080 archive & mpElectrodes;
00081 }
00082
00089 template<class Archive>
00090 void load(Archive & archive, const unsigned int version)
00091 {
00092 archive & boost::serialization::base_object<AbstractCardiacProblem<DIM, DIM, 2> >(*this);
00093 archive & mpBidomainTissue;
00094
00095 archive & mRowForAverageOfPhiZeroed;
00096 archive & mHasBath;
00097 archive & mpElectrodes;
00098
00099 if (mHasBath)
00100 {
00101
00102 AnalyseMeshForBath();
00103 }
00104 }
00105 BOOST_SERIALIZATION_SPLIT_MEMBER()
00106
00107 friend class TestBidomainWithBathProblem;
00108 friend class TestCardiacSimulationArchiver;
00109
00110 protected:
00112 BidomainTissue<DIM>* mpBidomainTissue;
00113
00115 std::vector<unsigned> mFixedExtracellularPotentialNodes;
00117 unsigned mExtracelluarColumnId;
00122 unsigned mRowForAverageOfPhiZeroed;
00123
00125 bool mHasBath;
00126
00128 boost::shared_ptr<Electrodes<DIM> > mpElectrodes;
00129
00134 Vec CreateInitialCondition();
00135
00140 void AnalyseMeshForBath();
00141
00147 AbstractBidomainSolver<DIM,DIM>* mpSolver;
00148
00150 virtual AbstractCardiacTissue<DIM> *CreateCardiacTissue();
00151
00153 virtual AbstractDynamicLinearPdeSolver<DIM,DIM,2>* CreateSolver();
00154
00159 void SetElectrodes();
00160
00161 public:
00171 BidomainProblem(AbstractCardiacCellFactory<DIM>* pCellFactory, bool hasBath=false);
00172
00176 BidomainProblem();
00177
00188 void SetFixedExtracellularPotentialNodes(std::vector<unsigned> nodes);
00189
00197 void SetNodeForAverageOfPhiZeroed(unsigned node);
00198
00202 BidomainTissue<DIM>* GetBidomainTissue();
00203
00208 void WriteInfo(double time);
00209
00215 virtual void DefineWriterColumns(bool extending);
00216
00224 virtual void WriteOneStep(double time, Vec voltageVec);
00225
00230 void PreSolveChecks();
00231
00232
00233
00241 void AtBeginningOfTimestep(double time);
00242
00250 void OnEndOfTimestep(double time);
00251
00259 void SetUpAdditionalStoppingTimes(std::vector<double>& rAdditionalStoppingTimes);
00260
00278 template<class Archive>
00279 void LoadExtraArchiveForBidomain(Archive & archive, unsigned version);
00280
00284 bool GetHasBath();
00285 };
00286
00287 #include "SerializationExportWrapper.hpp" // Must be last
00288 EXPORT_TEMPLATE_CLASS_SAME_DIMS(BidomainProblem)
00289
00290
00291 template<unsigned DIM>
00292 template<class Archive>
00293 void BidomainProblem<DIM>::LoadExtraArchiveForBidomain(Archive & archive, unsigned version)
00294 {
00295
00296 if (mpElectrodes)
00297 {
00298
00299 assert(mpElectrodes->GetBoundaryConditionsContainer());
00300
00301
00302
00303 boost::shared_ptr<BoundaryConditionsContainer<DIM, DIM, 2> > p_bcc;
00304 archive >> p_bcc;
00305 if (mpElectrodes->GetBoundaryConditionsContainer() != this->mpBoundaryConditionsContainer)
00306 {
00307
00308 DistributedTetrahedralMesh<DIM,DIM>* p_dist_mesh = dynamic_cast<DistributedTetrahedralMesh<DIM,DIM>*>(this->mpMesh);
00309 if (p_dist_mesh)
00310 {
00311 mpElectrodes->GetBoundaryConditionsContainer()->MergeFromArchive(archive, this->mpMesh);
00312 }
00313 else
00314 {
00315
00316 p_bcc->LoadFromArchive(archive, this->mpMesh);
00318 }
00319 }
00320 }
00321 }
00322
00323 #endif