Chaste Release::3.1
ExtendedBidomainProblem.hpp
00001 /*
00002 
00003 Copyright (c) 2005-2012, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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;//for testing
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         //archive & mIntracellularConductivitiesSecondCell; not allowed in some versions of boost
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         //archive & mpSolver;
00127 
00128         //archive the values for the conductivies of the second cell
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             std::string filename = ArchiveLocationInfo::GetArchiveDirectory() + "AbstractCardiacProblem_mSolution.vec";
00140 
00141             Hdf5DataWriter writer(*this->mpMesh->GetDistributedVectorFactory(), ArchiveLocationInfo::GetArchiveRelativePath(), "AbstractCardiacProblem_mSolution", false);
00142             writer.DefineFixedDimension(this->mpMesh->GetDistributedVectorFactory()->GetProblemSize());
00143             writer.DefineUnlimitedDimension("Time", "msec", 1);
00144 
00145             // Make sure the file does not take more disc space than really needed (#1200)
00146             writer.SetFixedChunkSize(1);
00147 
00149             assert(HeartConfig::Instance()->GetOutputUsingOriginalNodeOrdering() == false );
00150 
00151             int V = writer.DefineVariable("V","mV");
00152             int V_2 = writer.DefineVariable("V_2","mV");
00153             int phie = writer.DefineVariable("Phi_e","mV");
00154             std::vector<int> variable_ids;
00155             variable_ids.push_back(V);
00156             variable_ids.push_back(V_2);
00157             variable_ids.push_back(phie);
00158             writer.EndDefineMode();
00159             writer.PutUnlimitedVariable(0.0);
00160 
00161             //re-arrange to write out voltages...
00162             Vec voltages_to_be_written =  this->mpMesh->GetDistributedVectorFactory()->CreateVec(3);
00163             DistributedVector wrapped_voltages_to_be_written = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(voltages_to_be_written);
00164 
00165             DistributedVector distr_solution = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(this->mSolution);
00166             DistributedVector::Stripe phi_i_first_cell_stripe(distr_solution,0);
00167             DistributedVector::Stripe phi_i_second_cell_stripe(distr_solution,1);
00168             DistributedVector::Stripe phi_e_stripe(distr_solution,2);
00169 
00170 
00171             DistributedVector::Stripe wrapped_voltages_to_be_written_first_stripe(wrapped_voltages_to_be_written,0);
00172             DistributedVector::Stripe wrapped_voltages_to_be_written_second_stripe(wrapped_voltages_to_be_written,1);
00173             DistributedVector::Stripe wrapped_voltages_to_be_written_third_stripe(wrapped_voltages_to_be_written,2);
00174 
00175             for (DistributedVector::Iterator index = distr_solution.Begin();
00176                  index != distr_solution.End();
00177                  ++index)
00178             {
00179                 wrapped_voltages_to_be_written_first_stripe[index] = phi_i_first_cell_stripe[index] - phi_e_stripe[index];
00180                 wrapped_voltages_to_be_written_second_stripe[index] = phi_i_second_cell_stripe[index] - phi_e_stripe[index];
00181                 wrapped_voltages_to_be_written_third_stripe[index] = phi_e_stripe[index];
00182             }
00183             distr_solution.Restore();
00184             wrapped_voltages_to_be_written.Restore();
00185 
00186             writer.PutStripedVector(variable_ids, voltages_to_be_written);
00187             PetscTools::Destroy(voltages_to_be_written);
00188         }
00189     }
00190 
00197     template<class Archive>
00198     void load(Archive & archive, const unsigned int version)
00199     {
00200         archive & boost::serialization::base_object<AbstractCardiacProblem<DIM, DIM, 3> >(*this);
00201         archive & mpExtendedBidomainTissue;
00202         archive & mFixedExtracellularPotentialNodes;
00203         //archive & mIntracellularConductivitiesSecondCell; not allowed in some versions of boost
00204         archive & mVariablesIDs;
00205         archive & mUserSpecifiedSecondCellConductivities;
00206         archive & mUserHasSetBidomainValuesExplicitly;
00207         archive & mAmFirstCell;
00208         archive & mAmSecondCell;
00209         archive & mAmGap;
00210         archive & mCmFirstCell;
00211         archive & mCmSecondCell;
00212         archive & mGGap;
00213         archive & mGgapHeterogeneityRegions;
00214         archive & mGgapHeterogenousValues;
00215         archive & mRowForAverageOfPhiZeroed;
00216         archive & mApplyAveragePhieZeroConstraintAfterSolving;
00217         archive & mUserSuppliedExtracellularStimulus;
00218         archive & mHasBath;
00219         //archive & mpSolver;
00220 
00221         //load the values for the conductivies of the second cell
00222         for (unsigned i = 0; i < DIM; i++)
00223         {
00224             double conductivity;
00225             archive & conductivity;
00226             mIntracellularConductivitiesSecondCell(i) = conductivity;
00227         }
00228 
00229         bool has_solution;
00230         archive & has_solution;
00231 
00232         if (has_solution)
00233         {
00234             std::string filename = ArchiveLocationInfo::GetArchiveDirectory() + "AbstractCardiacProblem_mSolution.vec";
00235 
00236             this->mSolution = this->mpMesh->GetDistributedVectorFactory()->CreateVec(3);
00237             DistributedVector mSolution_distri = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(this->mSolution);
00238 
00239             std::string archive_dir = ArchiveLocationInfo::GetArchiveRelativePath();
00240             Hdf5DataReader reader(archive_dir, "AbstractCardiacProblem_mSolution", !FileFinder::IsAbsolutePath(archive_dir));
00241 
00242             Vec V = this->mpMesh->GetDistributedVectorFactory()->CreateVec();
00243             Vec V_2 = this->mpMesh->GetDistributedVectorFactory()->CreateVec();
00244             Vec phie = this->mpMesh->GetDistributedVectorFactory()->CreateVec();
00245 
00246             reader.GetVariableOverNodes(V, "V", 0);
00247             reader.GetVariableOverNodes(V_2, "V_2", 0);
00248             reader.GetVariableOverNodes(phie, "Phi_e", 0);
00249 
00250             //from transmembrane voltages back to phi_i now...
00251             DistributedVector vm_first_cell_distri = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(V);
00252             DistributedVector vm_second_cell_distri = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(V_2);
00253             DistributedVector phie_distri = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(phie);
00254 
00255             DistributedVector::Stripe mSolution_phi_1(mSolution_distri,0);
00256             DistributedVector::Stripe mSolution_phi_2(mSolution_distri,1);
00257             DistributedVector::Stripe mSolution_phie(mSolution_distri,2);
00258 
00259             for (DistributedVector::Iterator index = mSolution_distri.Begin();
00260                  index != mSolution_distri.End();
00261                  ++index)
00262             {
00263                 mSolution_phi_1[index] = vm_first_cell_distri[index] + phie_distri[index];//phi_i = Vm + phi_e
00264                 mSolution_phi_2[index] = vm_second_cell_distri[index] + phie_distri[index];
00265                 mSolution_phie[index] = phie_distri[index];
00266             }
00267             PetscTools::Destroy(V);
00268             PetscTools::Destroy(V_2);
00269             PetscTools::Destroy(phie);
00270 
00271             mSolution_distri.Restore();
00272         }
00273     }
00274     BOOST_SERIALIZATION_SPLIT_MEMBER()
00275 
00276 
00277 protected:
00278 
00280     AbstractCardiacCellFactory<DIM,DIM>* mpSecondCellFactory;
00281 
00283     ExtendedBidomainTissue<DIM>* mpExtendedBidomainTissue;
00284 
00286     std::vector<unsigned> mFixedExtracellularPotentialNodes;
00287 
00289     c_vector<double, DIM>  mIntracellularConductivitiesSecondCell;
00290 
00292     unsigned mVoltageColumnId_Vm1;
00294     unsigned mVoltageColumnId_Vm2;
00296     unsigned mVoltageColumnId_Phie;
00298     std::vector<signed int> mVariablesIDs;
00299 
00301     bool mUserSpecifiedSecondCellConductivities;
00302 
00304     bool mUserHasSetBidomainValuesExplicitly;
00305 
00307     double mAmFirstCell;
00309     double mAmSecondCell;
00311     double mAmGap;
00313     double mCmFirstCell;
00315     double mCmSecondCell;
00317     double mGGap;
00318 
00324     std::vector<boost::shared_ptr<AbstractChasteRegion<DIM> > > mGgapHeterogeneityRegions;
00325 
00327     std::vector<double> mGgapHeterogenousValues;
00328 
00329 
00331     AbstractStimulusFactory<DIM>* mpExtracellularStimulusFactory;
00332 
00337     int mRowForAverageOfPhiZeroed;
00338 
00346     unsigned mApplyAveragePhieZeroConstraintAfterSolving;
00347 
00349     bool mUserSuppliedExtracellularStimulus;
00350 
00352     bool mHasBath;
00353 
00358     Vec CreateInitialCondition();
00359 
00364     void AnalyseMeshForBath();
00365 
00375     void ProcessExtracellularStimulus();
00376 
00382     AbstractExtendedBidomainSolver<DIM,DIM>* mpSolver;
00383 
00385     virtual AbstractCardiacTissue<DIM> *CreateCardiacTissue();
00386 
00388     virtual AbstractDynamicLinearPdeSolver<DIM,DIM,3>* CreateSolver();
00389 
00390 public:
00401     ExtendedBidomainProblem(AbstractCardiacCellFactory<DIM>* pCellFactory, AbstractCardiacCellFactory<DIM>* pSecondCellFactory, bool hasBath = false);
00402 
00406     ExtendedBidomainProblem();
00407 
00411     ~ExtendedBidomainProblem();
00412 
00423     void SetFixedExtracellularPotentialNodes(std::vector<unsigned> nodes);
00424 
00430     void SetIntracellularConductivitiesForSecondCell(c_vector<double, DIM> conductivities);
00431 
00444     void SetExtendedBidomainParameters(double Am1, double Am2, double AmGap, double Cm1, double Cm2, double Ggap);
00445 
00454     void SetGgapHeterogeneities ( std::vector<boost::shared_ptr<AbstractChasteRegion<DIM> > >& rGgapHeterogeneityRegions, std::vector<double>& rGgapValues);
00455 
00461     void SetExtracellularStimulusFactory( AbstractStimulusFactory<DIM>* pFactory);
00462 
00463 
00471     void SetNodeForAverageOfPhiZeroed(unsigned node);
00472 
00473 
00477     ExtendedBidomainTissue<DIM>* GetExtendedBidomainTissue();
00478 
00484     void WriteInfo(double time);
00485 
00494     virtual void DefineWriterColumns(bool extending);
00495 
00513     virtual void WriteOneStep(double time, Vec voltageVec);
00514 
00519     void PreSolveChecks();
00520 
00521 
00525     bool GetHasBath();
00526 
00533     void SetHasBath(bool hasBath);
00534 
00535 };
00536 
00537 #include "SerializationExportWrapper.hpp" // Must be last
00538 EXPORT_TEMPLATE_CLASS_SAME_DIMS(ExtendedBidomainProblem)
00539 
00540 #endif /*EXTENDEDBIDOMAINPROBLEM_HPP_*/