Chaste Release::3.1
|
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_*/