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 EXTENDEDBIDOMAINPROBLEM_HPP_
00038 #define EXTENDEDBIDOMAINPROBLEM_HPP_
00039
00040 #include "ChasteSerialization.hpp"
00041 #include <boost/serialization/base_object.hpp>
00042
00043 #include <vector>
00044 #include <boost/shared_ptr.hpp>
00045 #include <boost/serialization/shared_ptr.hpp>
00046
00047 #include "AbstractCardiacProblem.hpp"
00048 #include "AbstractCardiacTissue.hpp"
00049 #include "AbstractExtendedBidomainSolver.hpp"
00050 #include "AbstractCardiacCellFactory.hpp"
00051 #include "Electrodes.hpp"
00052 #include "ExtendedBidomainTissue.hpp"
00053
00054 #include "HeartRegionCodes.hpp"
00055 #include "DistributedTetrahedralMesh.hpp"
00056 #include "AbstractStimulusFactory.hpp"
00057 #include "ElectrodesStimulusFactory.hpp"
00058
00090 template<unsigned DIM>
00091 class ExtendedBidomainProblem : public AbstractCardiacProblem<DIM,DIM, 3>
00092 {
00094 friend class boost::serialization::access;
00095
00096 friend class TestArchivingExtendedBidomain;
00097
00104 template<class Archive>
00105 void save(Archive & archive, const unsigned int version) const
00106 {
00107 archive & boost::serialization::base_object<AbstractCardiacProblem<DIM, DIM, 3> >(*this);
00108 archive & mpExtendedBidomainTissue;
00109 archive & mFixedExtracellularPotentialNodes;
00110
00111 archive & mVariablesIDs;
00112 archive & mUserSpecifiedSecondCellConductivities;
00113 archive & mUserHasSetBidomainValuesExplicitly;
00114 archive & mAmFirstCell;
00115 archive & mAmSecondCell;
00116 archive & mAmGap;
00117 archive & mCmFirstCell;
00118 archive & mCmSecondCell;
00119 archive & mGGap;
00120 archive & mGgapHeterogeneityRegions;
00121 archive & mGgapHeterogenousValues;
00122 archive & mRowForAverageOfPhiZeroed;
00123 archive & mApplyAveragePhieZeroConstraintAfterSolving;
00124 archive & mUserSuppliedExtracellularStimulus;
00125 archive & mHasBath;
00126
00127
00128
00129 for (unsigned i = 0; i < DIM; i++)
00130 {
00131 double conductivity = mIntracellularConductivitiesSecondCell(i);
00132 archive & conductivity;
00133 }
00134
00135 bool has_solution = (this->mSolution != NULL);
00136 archive & has_solution;
00137 if (has_solution)
00138 {
00139 Hdf5DataWriter writer(*this->mpMesh->GetDistributedVectorFactory(), ArchiveLocationInfo::GetArchiveRelativePath(), "AbstractCardiacProblem_mSolution", false);
00140 writer.DefineFixedDimension(this->mpMesh->GetDistributedVectorFactory()->GetProblemSize());
00141 writer.DefineUnlimitedDimension("Time", "msec", 1);
00142
00143 int V = writer.DefineVariable("V","mV");
00144 int V_2 = writer.DefineVariable("V_2","mV");
00145 int phie = writer.DefineVariable("Phi_e","mV");
00146 std::vector<int> variable_ids;
00147 variable_ids.push_back(V);
00148 variable_ids.push_back(V_2);
00149 variable_ids.push_back(phie);
00150 writer.EndDefineMode();
00151 writer.PutUnlimitedVariable(0.0);
00152
00153
00154 Vec voltages_to_be_written = this->mpMesh->GetDistributedVectorFactory()->CreateVec(3);
00155 DistributedVector wrapped_voltages_to_be_written = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(voltages_to_be_written);
00156
00157 DistributedVector distr_solution = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(this->mSolution);
00158 DistributedVector::Stripe phi_i_first_cell_stripe(distr_solution,0);
00159 DistributedVector::Stripe phi_i_second_cell_stripe(distr_solution,1);
00160 DistributedVector::Stripe phi_e_stripe(distr_solution,2);
00161
00162
00163 DistributedVector::Stripe wrapped_voltages_to_be_written_first_stripe(wrapped_voltages_to_be_written,0);
00164 DistributedVector::Stripe wrapped_voltages_to_be_written_second_stripe(wrapped_voltages_to_be_written,1);
00165 DistributedVector::Stripe wrapped_voltages_to_be_written_third_stripe(wrapped_voltages_to_be_written,2);
00166
00167 for (DistributedVector::Iterator index = distr_solution.Begin();
00168 index != distr_solution.End();
00169 ++index)
00170 {
00171 wrapped_voltages_to_be_written_first_stripe[index] = phi_i_first_cell_stripe[index] - phi_e_stripe[index];
00172 wrapped_voltages_to_be_written_second_stripe[index] = phi_i_second_cell_stripe[index] - phi_e_stripe[index];
00173 wrapped_voltages_to_be_written_third_stripe[index] = phi_e_stripe[index];
00174 }
00175 distr_solution.Restore();
00176 wrapped_voltages_to_be_written.Restore();
00177
00178 writer.PutStripedVector(variable_ids, voltages_to_be_written);
00179 PetscTools::Destroy(voltages_to_be_written);
00180 }
00181 }
00182
00189 template<class Archive>
00190 void load(Archive & archive, const unsigned int version)
00191 {
00192 archive & boost::serialization::base_object<AbstractCardiacProblem<DIM, DIM, 3> >(*this);
00193 archive & mpExtendedBidomainTissue;
00194 archive & mFixedExtracellularPotentialNodes;
00195
00196 archive & mVariablesIDs;
00197 archive & mUserSpecifiedSecondCellConductivities;
00198 archive & mUserHasSetBidomainValuesExplicitly;
00199 archive & mAmFirstCell;
00200 archive & mAmSecondCell;
00201 archive & mAmGap;
00202 archive & mCmFirstCell;
00203 archive & mCmSecondCell;
00204 archive & mGGap;
00205 archive & mGgapHeterogeneityRegions;
00206 archive & mGgapHeterogenousValues;
00207 archive & mRowForAverageOfPhiZeroed;
00208 archive & mApplyAveragePhieZeroConstraintAfterSolving;
00209 archive & mUserSuppliedExtracellularStimulus;
00210 archive & mHasBath;
00211
00212
00213
00214 for (unsigned i = 0; i < DIM; i++)
00215 {
00216 double conductivity;
00217 archive & conductivity;
00218 mIntracellularConductivitiesSecondCell(i) = conductivity;
00219 }
00220
00221 bool has_solution;
00222 archive & has_solution;
00223
00224 if (has_solution)
00225 {
00226 this->mSolution = this->mpMesh->GetDistributedVectorFactory()->CreateVec(3);
00227 DistributedVector mSolution_distri = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(this->mSolution);
00228
00229 std::string archive_dir = ArchiveLocationInfo::GetArchiveRelativePath();
00230 Hdf5DataReader reader(archive_dir, "AbstractCardiacProblem_mSolution", !FileFinder::IsAbsolutePath(archive_dir));
00231
00232 Vec V = this->mpMesh->GetDistributedVectorFactory()->CreateVec();
00233 Vec V_2 = this->mpMesh->GetDistributedVectorFactory()->CreateVec();
00234 Vec phie = this->mpMesh->GetDistributedVectorFactory()->CreateVec();
00235
00236 reader.GetVariableOverNodes(V, "V", 0);
00237 reader.GetVariableOverNodes(V_2, "V_2", 0);
00238 reader.GetVariableOverNodes(phie, "Phi_e", 0);
00239
00240
00241 DistributedVector vm_first_cell_distri = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(V);
00242 DistributedVector vm_second_cell_distri = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(V_2);
00243 DistributedVector phie_distri = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(phie);
00244
00245 DistributedVector::Stripe mSolution_phi_1(mSolution_distri,0);
00246 DistributedVector::Stripe mSolution_phi_2(mSolution_distri,1);
00247 DistributedVector::Stripe mSolution_phie(mSolution_distri,2);
00248
00249 for (DistributedVector::Iterator index = mSolution_distri.Begin();
00250 index != mSolution_distri.End();
00251 ++index)
00252 {
00253 mSolution_phi_1[index] = vm_first_cell_distri[index] + phie_distri[index];
00254 mSolution_phi_2[index] = vm_second_cell_distri[index] + phie_distri[index];
00255 mSolution_phie[index] = phie_distri[index];
00256 }
00257 PetscTools::Destroy(V);
00258 PetscTools::Destroy(V_2);
00259 PetscTools::Destroy(phie);
00260
00261 mSolution_distri.Restore();
00262 }
00263 }
00264 BOOST_SERIALIZATION_SPLIT_MEMBER()
00265
00266
00267 protected:
00268
00270 AbstractCardiacCellFactory<DIM,DIM>* mpSecondCellFactory;
00271
00273 ExtendedBidomainTissue<DIM>* mpExtendedBidomainTissue;
00274
00276 std::vector<unsigned> mFixedExtracellularPotentialNodes;
00277
00279 c_vector<double, DIM> mIntracellularConductivitiesSecondCell;
00280
00282 unsigned mVoltageColumnId_Vm1;
00284 unsigned mVoltageColumnId_Vm2;
00286 unsigned mVoltageColumnId_Phie;
00288 std::vector<signed int> mVariablesIDs;
00289
00292 bool mUserSpecifiedSecondCellConductivities;
00293
00295 bool mUserHasSetBidomainValuesExplicitly;
00296
00298 double mAmFirstCell;
00300 double mAmSecondCell;
00302 double mAmGap;
00304 double mCmFirstCell;
00306 double mCmSecondCell;
00309 double mGGap;
00310
00316 std::vector<boost::shared_ptr<AbstractChasteRegion<DIM> > > mGgapHeterogeneityRegions;
00317
00319 std::vector<double> mGgapHeterogenousValues;
00320
00321
00323 AbstractStimulusFactory<DIM>* mpExtracellularStimulusFactory;
00324
00329 int mRowForAverageOfPhiZeroed;
00330
00338 unsigned mApplyAveragePhieZeroConstraintAfterSolving;
00339
00341 bool mUserSuppliedExtracellularStimulus;
00342
00344 bool mHasBath;
00345
00351 Vec CreateInitialCondition();
00352
00357 void AnalyseMeshForBath();
00358
00368 void ProcessExtracellularStimulus();
00369
00375 AbstractExtendedBidomainSolver<DIM,DIM>* mpSolver;
00376
00378 virtual AbstractCardiacTissue<DIM> *CreateCardiacTissue();
00379
00381 virtual AbstractDynamicLinearPdeSolver<DIM,DIM,3>* CreateSolver();
00382
00383 public:
00394 ExtendedBidomainProblem(AbstractCardiacCellFactory<DIM>* pCellFactory, AbstractCardiacCellFactory<DIM>* pSecondCellFactory, bool hasBath = false);
00395
00399 ExtendedBidomainProblem();
00400
00404 virtual ~ExtendedBidomainProblem();
00405
00416 void SetFixedExtracellularPotentialNodes(std::vector<unsigned> nodes);
00417
00423 void SetIntracellularConductivitiesForSecondCell(c_vector<double, DIM> conductivities);
00424
00437 void SetExtendedBidomainParameters(double Am1, double Am2, double AmGap, double Cm1, double Cm2, double Ggap);
00438
00447 void SetGgapHeterogeneities ( std::vector<boost::shared_ptr<AbstractChasteRegion<DIM> > >& rGgapHeterogeneityRegions, std::vector<double>& rGgapValues);
00448
00454 void SetExtracellularStimulusFactory( AbstractStimulusFactory<DIM>* pFactory);
00455
00456
00464 void SetNodeForAverageOfPhiZeroed(unsigned node);
00465
00466
00470 ExtendedBidomainTissue<DIM>* GetExtendedBidomainTissue();
00471
00477 void WriteInfo(double time);
00478
00487 virtual void DefineWriterColumns(bool extending);
00488
00506 virtual void WriteOneStep(double time, Vec voltageVec);
00507
00512 void PreSolveChecks();
00513
00514
00518 bool GetHasBath();
00519
00526 void SetHasBath(bool hasBath);
00527
00528 };
00529
00530 #include "SerializationExportWrapper.hpp" // Must be last
00531 EXPORT_TEMPLATE_CLASS_SAME_DIMS(ExtendedBidomainProblem)
00532
00533 #endif