37 #include "BidomainProblem.hpp"
38 #include "BidomainSolver.hpp"
39 #include "HeartConfig.hpp"
41 #include "DistributedVector.hpp"
42 #include "ReplicatableVector.hpp"
44 template <
unsigned DIM>
52 iter != this->mpMesh->GetNodeIteratorEnd();
58 bool any_bath_element_found =
false;
63 it != this->mpMesh->GetElementIteratorEnd();
78 any_bath_element_found =
true;
92 if ( !(bath_identifiers.size()==1 && bath_identifiers.find(1)==bath_identifiers.begin()) )
94 EXCEPTION(
"User has set bath identifiers, but the BidomainProblem isn't expecting a bath. Did you mean to use BidomainProblem(..., true)? Or alternatively, BidomainWithBathProblem(...)?");
100 template<
unsigned DIM>
107 DistributedVector ic = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(init_cond);
116 voltage_stripe[index] = 0.0;
125 template<
unsigned DIM>
128 AnalyseMeshForBath();
130 return mpBidomainTissue;
133 template<
unsigned DIM>
148 this->mpBoundaryConditionsContainer.get());
153 mpSolver->SetRowForAverageOfPhiZeroed(mRowForAverageOfPhiZeroed);
164 template<
unsigned DIM>
168 mpBidomainTissue(NULL),
169 mRowForAverageOfPhiZeroed(INT_MAX),
175 template<
unsigned DIM>
178 mpBidomainTissue(NULL),
179 mRowForAverageOfPhiZeroed(INT_MAX)
186 template<
unsigned DIM>
189 mFixedExtracellularPotentialNodes.resize(nodes.size());
190 for (
unsigned i=0; i<nodes.size(); i++)
194 mFixedExtracellularPotentialNodes[i] = nodes[i];
198 template<
unsigned DIM>
201 mRowForAverageOfPhiZeroed = 2*node+1;
204 template<
unsigned DIM>
207 assert(mpBidomainTissue!=NULL);
208 return mpBidomainTissue;
211 template<
unsigned DIM>
216 std::cout <<
"Solved to time " << time <<
"\n" << std::flush;
219 double v_max, v_min, phi_max, phi_min;
221 VecStrideMax( this->mSolution, 0, PETSC_NULL, &v_max );
222 VecStrideMin( this->mSolution, 0, PETSC_NULL, &v_min );
224 VecStrideMax( this->mSolution, 1, PETSC_NULL, &phi_max );
225 VecStrideMin( this->mSolution, 1, PETSC_NULL, &phi_min );
229 std::cout <<
" V; phi_e = " <<
"[" <<v_min <<
", " << v_max <<
"]" <<
";\t"
230 <<
"[" <<phi_min <<
", " << phi_max <<
"]" <<
"\n"
235 template<
unsigned DIM>
241 mExtracelluarColumnId = this->mpWriter->GetVariableByName(
"Phi_e");
245 mExtracelluarColumnId = this->mpWriter->DefineVariable(
"Phi_e",
"mV");
250 template<
unsigned DIM>
253 this->mpWriter->PutUnlimitedVariable(time);
254 std::vector<int> variable_ids;
255 variable_ids.push_back(this->mVoltageColumnId);
256 variable_ids.push_back(mExtracelluarColumnId);
257 this->mpWriter->PutStripedVector(variable_ids, voltageVec);
261 template<
unsigned DIM>
265 if (mFixedExtracellularPotentialNodes.empty())
268 if (mRowForAverageOfPhiZeroed==INT_MAX)
275 EXCEPTION(
"Bidomain external voltage is not bounded in this simulation - use KSP *absolute* tolerance");
281 template<
unsigned DIM>
290 assert(this->mpMesh!=NULL);
294 mpElectrodes = (boost::shared_ptr<Electrodes<DIM> >)
new Electrodes<DIM>(*(this->mpMesh));
298 template<
unsigned DIM>
301 if ( mpElectrodes && mpElectrodes->SwitchOn(time) )
304 assert(this->mpBoundaryConditionsContainer);
309 mpSolver->ResetBoundaryConditionsContainer(mpElectrodes->GetBoundaryConditionsContainer().get());
313 this->mpBoundaryConditionsContainer = mpElectrodes->GetBoundaryConditionsContainer();
316 this->mpDefaultBoundaryConditionsContainer = this->mpBoundaryConditionsContainer;
320 if ( mpSolver->GetLinearSystem() != NULL )
324 if (mpElectrodes->HasGroundedElectrode())
326 this->mpBoundaryConditionsContainer->ApplyDirichletToLinearProblem( *(mpSolver->GetLinearSystem()),
331 if (mpElectrodes->HasGroundedElectrode())
333 mpSolver->GetLinearSystem()->RemoveNullSpace();
339 template<
unsigned DIM>
342 if ( mpElectrodes && mpElectrodes->SwitchOff(time) )
346 assert(this->mpBoundaryConditionsContainer);
352 for (
unsigned problem_index=0; problem_index<2; problem_index++)
354 this->mpDefaultBoundaryConditionsContainer->DefineZeroNeumannOnMeshBoundary(this->mpMesh, problem_index);
359 if (mpElectrodes->HasGroundedElectrode())
368 mpSolver->ResetBoundaryConditionsContainer(this->mpDefaultBoundaryConditionsContainer.get());
371 this->mpBoundaryConditionsContainer = this->mpDefaultBoundaryConditionsContainer;
377 template<
unsigned DIM>
382 rAdditionalStoppingTimes.push_back( mpElectrodes->GetSwitchOnTime() );
383 rAdditionalStoppingTimes.push_back( mpElectrodes->GetSwitchOffTime() );
387 template<
unsigned DIM>
void AnalyseMeshForBath()
ElementIterator GetElementIteratorBegin(bool skipDeletedElements=true)
static bool IsRegionBath(HeartRegionType regionId)
#define EXCEPTION(message)
static HeartRegionType GetValidBathId()
virtual Vec CreateInitialCondition()
BidomainTissue< DIM > * GetBidomainTissue()
void SetUpAdditionalStoppingTimes(std::vector< double > &rAdditionalStoppingTimes)
void SetFixedExtracellularPotentialNodes(std::vector< unsigned > nodes)
std::vector< unsigned > mFixedExtracellularPotentialNodes
virtual void PreSolveChecks()
void WriteInfo(double time)
void SetFixedExtracellularPotentialNodes(std::vector< unsigned > fixedExtracellularPotentialNodes)
Node< SPACE_DIM > * GetNode(unsigned localIndex) const
virtual void DefineWriterColumns(bool extending)
bool GetUseStateVariableInterpolation() const
#define EXPORT_TEMPLATE_CLASS_SAME_DIMS(CLASS)
Vec CreateInitialCondition()
unsigned GetNumNodes() const
void OnEndOfTimestep(double time)
virtual void WriteOneStep(double time, Vec voltageVec)
NodeIterator GetNodeIteratorBegin(bool skipDeletedNodes=true)
virtual void DefineWriterColumns(bool extending)
unsigned GetUnsignedAttribute()
const std::set< unsigned > & rGetBathIdentifiers()
void SetNodeForAverageOfPhiZeroed(unsigned node)
void AtBeginningOfTimestep(double time)
static HeartRegionType GetValidTissueId()
void WriteExtraVariablesOneStep()
static HeartConfig * Instance()
virtual AbstractCardiacTissue< DIM > * CreateCardiacTissue()
bool GetUseRelativeTolerance() const
virtual AbstractDynamicLinearPdeSolver< DIM, DIM, 2 > * CreateSolver()
void DefineExtraVariablesWriterColumns(bool extending)
static bool IsRegionTissue(HeartRegionType regionId)