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 EXTENDEDBIDOMAINPROBLEM_HPP_
00031 #define EXTENDEDBIDOMAINPROBLEM_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 "AbstractExtendedBidomainSolver.hpp"
00043 #include "AbstractCardiacCellFactory.hpp"
00044 #include "Electrodes.hpp"
00045 #include "ExtendedBidomainTissue.hpp"
00046
00047 #include "HeartRegionCodes.hpp"
00048 #include "DistributedTetrahedralMesh.hpp"
00049 #include "AbstractStimulusFactory.hpp"
00050 #include "ElectrodesStimulusFactory.hpp"
00051
00083 template<unsigned DIM>
00084 class ExtendedBidomainProblem : public AbstractCardiacProblem<DIM,DIM, 3>
00085 {
00087 friend class boost::serialization::access;
00088
00089 friend class TestArchivingExtendedBidomain;
00090
00097 template<class Archive>
00098 void save(Archive & archive, const unsigned int version) const
00099 {
00100 archive & boost::serialization::base_object<AbstractCardiacProblem<DIM, DIM, 3> >(*this);
00101 archive & mpExtendedBidomainTissue;
00102 archive & mFixedExtracellularPotentialNodes;
00103
00104 archive & mVariablesIDs;
00105 archive & mUserSpecifiedSecondCellConductivities;
00106 archive & mUserHasSetBidomainValuesExplicitly;
00107 archive & mAmFirstCell;
00108 archive & mAmSecondCell;
00109 archive & mAmGap;
00110 archive & mCmFirstCell;
00111 archive & mCmSecondCell;
00112 archive & mGGap;
00113 archive & mGgapHeterogeneityRegions;
00114 archive & mGgapHeterogenousValues;
00115 archive & mRowForAverageOfPhiZeroed;
00116 archive & mApplyAveragePhieZeroConstraintAfterSolving;
00117 archive & mUserSuppliedExtracellularStimulus;
00118 archive & mHasBath;
00119
00120
00121
00122 for (unsigned i = 0; i < DIM; i++)
00123 {
00124 double conductivity = mIntracellularConductivitiesSecondCell(i);
00125 archive & conductivity;
00126 }
00127
00128 bool has_solution = (this->mSolution != NULL);
00129 archive & has_solution;
00130 if (has_solution)
00131 {
00132 std::string filename = ArchiveLocationInfo::GetArchiveDirectory() + "AbstractCardiacProblem_mSolution.vec";
00133
00134 Hdf5DataWriter writer(*this->mpMesh->GetDistributedVectorFactory(), ArchiveLocationInfo::GetArchiveRelativePath(), "AbstractCardiacProblem_mSolution", false);
00135 writer.DefineFixedDimension(this->mpMesh->GetDistributedVectorFactory()->GetProblemSize());
00136 writer.DefineUnlimitedDimension("Time", "msec", 1);
00137
00138
00139 writer.SetFixedChunkSize(1);
00140
00142 assert(HeartConfig::Instance()->GetOutputUsingOriginalNodeOrdering() == false );
00143
00144 int V = writer.DefineVariable("V","mV");
00145 int V_2 = writer.DefineVariable("V_2","mV");
00146 int phie = writer.DefineVariable("Phi_e","mV");
00147 std::vector<int> variable_ids;
00148 variable_ids.push_back(V);
00149 variable_ids.push_back(V_2);
00150 variable_ids.push_back(phie);
00151 writer.EndDefineMode();
00152 writer.PutUnlimitedVariable(0.0);
00153
00154
00155 Vec voltages_to_be_written = this->mpMesh->GetDistributedVectorFactory()->CreateVec(3);
00156 DistributedVector wrapped_voltages_to_be_written = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(voltages_to_be_written);
00157
00158 DistributedVector distr_solution = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(this->mSolution);
00159 DistributedVector::Stripe phi_i_first_cell_stripe(distr_solution,0);
00160 DistributedVector::Stripe phi_i_second_cell_stripe(distr_solution,1);
00161 DistributedVector::Stripe phi_e_stripe(distr_solution,2);
00162
00163
00164 DistributedVector::Stripe wrapped_voltages_to_be_written_first_stripe(wrapped_voltages_to_be_written,0);
00165 DistributedVector::Stripe wrapped_voltages_to_be_written_second_stripe(wrapped_voltages_to_be_written,1);
00166 DistributedVector::Stripe wrapped_voltages_to_be_written_third_stripe(wrapped_voltages_to_be_written,2);
00167
00168 for (DistributedVector::Iterator index = distr_solution.Begin();
00169 index != distr_solution.End();
00170 ++index)
00171 {
00172 wrapped_voltages_to_be_written_first_stripe[index] = phi_i_first_cell_stripe[index] - phi_e_stripe[index];
00173 wrapped_voltages_to_be_written_second_stripe[index] = phi_i_second_cell_stripe[index] - phi_e_stripe[index];
00174 wrapped_voltages_to_be_written_third_stripe[index] = phi_e_stripe[index];
00175 }
00176 distr_solution.Restore();
00177 wrapped_voltages_to_be_written.Restore();
00178
00179 writer.PutStripedVector(variable_ids, voltages_to_be_written);
00180 VecDestroy(voltages_to_be_written);
00181 }
00182 }
00183
00190 template<class Archive>
00191 void load(Archive & archive, const unsigned int version)
00192 {
00193 archive & boost::serialization::base_object<AbstractCardiacProblem<DIM, DIM, 3> >(*this);
00194 archive & mpExtendedBidomainTissue;
00195 archive & mFixedExtracellularPotentialNodes;
00196
00197 archive & mVariablesIDs;
00198 archive & mUserSpecifiedSecondCellConductivities;
00199 archive & mUserHasSetBidomainValuesExplicitly;
00200 archive & mAmFirstCell;
00201 archive & mAmSecondCell;
00202 archive & mAmGap;
00203 archive & mCmFirstCell;
00204 archive & mCmSecondCell;
00205 archive & mGGap;
00206 archive & mGgapHeterogeneityRegions;
00207 archive & mGgapHeterogenousValues;
00208 archive & mRowForAverageOfPhiZeroed;
00209 archive & mApplyAveragePhieZeroConstraintAfterSolving;
00210 archive & mUserSuppliedExtracellularStimulus;
00211 archive & mHasBath;
00212
00213
00214
00215 for (unsigned i = 0; i < DIM; i++)
00216 {
00217 double conductivity;
00218 archive & conductivity;
00219 mIntracellularConductivitiesSecondCell(i) = conductivity;
00220 }
00221
00222 bool has_solution;
00223 archive & has_solution;
00224
00225 if (has_solution)
00226 {
00227 std::string filename = ArchiveLocationInfo::GetArchiveDirectory() + "AbstractCardiacProblem_mSolution.vec";
00228
00229 this->mSolution = this->mpMesh->GetDistributedVectorFactory()->CreateVec(3);
00230 DistributedVector mSolution_distri = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(this->mSolution);
00231
00232 std::string archive_dir = ArchiveLocationInfo::GetArchiveRelativePath();
00233 Hdf5DataReader reader(archive_dir, "AbstractCardiacProblem_mSolution", !FileFinder::IsAbsolutePath(archive_dir));
00234
00235 Vec V = this->mpMesh->GetDistributedVectorFactory()->CreateVec();
00236 Vec V_2 = this->mpMesh->GetDistributedVectorFactory()->CreateVec();
00237 Vec phie = this->mpMesh->GetDistributedVectorFactory()->CreateVec();
00238
00239 reader.GetVariableOverNodes(V, "V", 0);
00240 reader.GetVariableOverNodes(V_2, "V_2", 0);
00241 reader.GetVariableOverNodes(phie, "Phi_e", 0);
00242
00243
00244 DistributedVector vm_first_cell_distri = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(V);
00245 DistributedVector vm_second_cell_distri = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(V_2);
00246 DistributedVector phie_distri = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(phie);
00247
00248 DistributedVector::Stripe mSolution_phi_1(mSolution_distri,0);
00249 DistributedVector::Stripe mSolution_phi_2(mSolution_distri,1);
00250 DistributedVector::Stripe mSolution_phie(mSolution_distri,2);
00251
00252 for (DistributedVector::Iterator index = mSolution_distri.Begin();
00253 index != mSolution_distri.End();
00254 ++index)
00255 {
00256 mSolution_phi_1[index] = vm_first_cell_distri[index] + phie_distri[index];
00257 mSolution_phi_2[index] = vm_second_cell_distri[index] + phie_distri[index];
00258 mSolution_phie[index] = phie_distri[index];
00259 }
00260 VecDestroy(V);
00261 VecDestroy(V_2);
00262 VecDestroy(phie);
00263
00264 mSolution_distri.Restore();
00265 }
00266 }
00267 BOOST_SERIALIZATION_SPLIT_MEMBER()
00268
00269
00270 protected:
00271
00273 AbstractCardiacCellFactory<DIM,DIM>* mpSecondCellFactory;
00274
00276 ExtendedBidomainTissue<DIM>* mpExtendedBidomainTissue;
00277
00279 std::vector<unsigned> mFixedExtracellularPotentialNodes;
00280
00282 c_vector<double, DIM> mIntracellularConductivitiesSecondCell;
00283
00285 unsigned mVoltageColumnId_Vm1;
00287 unsigned mVoltageColumnId_Vm2;
00289 unsigned mVoltageColumnId_Phie;
00291 std::vector<signed int> mVariablesIDs;
00292
00294 bool mUserSpecifiedSecondCellConductivities;
00295
00297 bool mUserHasSetBidomainValuesExplicitly;
00298
00300 double mAmFirstCell;
00302 double mAmSecondCell;
00304 double mAmGap;
00306 double mCmFirstCell;
00308 double mCmSecondCell;
00310 double mGGap;
00311
00317 std::vector<boost::shared_ptr<AbstractChasteRegion<DIM> > > mGgapHeterogeneityRegions;
00318
00320 std::vector<double> mGgapHeterogenousValues;
00321
00322
00324 AbstractStimulusFactory<DIM>* mpExtracellularStimulusFactory;
00325
00330 int mRowForAverageOfPhiZeroed;
00331
00339 unsigned mApplyAveragePhieZeroConstraintAfterSolving;
00340
00342 bool mUserSuppliedExtracellularStimulus;
00343
00345 bool mHasBath;
00346
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 ~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