ExtendedBidomainProblem.hpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2011
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
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;//for testing
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         //archive & mIntracellularConductivitiesSecondCell; not allowed in some versions of boost
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         //archive & mpSolver;
00120 
00121         //archive the values for the conductivies of the second cell
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             // Make sure the file does not take more disc space than really needed (#1200)
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             //re-arrange to write out voltages...
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         //archive & mIntracellularConductivitiesSecondCell; not allowed in some versions of boost
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         //archive & mpSolver;
00213 
00214         //load the values for the conductivies of the second cell
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             //from transmembrane voltages back to phi_i now...
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];//phi_i = Vm + phi_e
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 /*EXTENDEDBIDOMAINPROBLEM_HPP_*/
Generated on Thu Dec 22 13:00:06 2011 for Chaste by  doxygen 1.6.3