37 #include "ExtendedBidomainProblem.hpp"
38 #include "ExtendedBidomainSolver.hpp"
39 #include "AbstractDynamicLinearPdeSolver.hpp"
40 #include "HeartConfig.hpp"
42 #include "DistributedVector.hpp"
43 #include "ReplicatableVector.hpp"
47 template<
unsigned DIM>
51 mpSecondCellFactory(pSecondCellFactory),
52 mpExtendedBidomainTissue(NULL),
53 mUserSpecifiedSecondCellConductivities(false),
54 mUserHasSetBidomainValuesExplicitly(false),
55 mpExtracellularStimulusFactory(NULL),
56 mRowForAverageOfPhiZeroed(INT_MAX),
57 mApplyAveragePhieZeroConstraintAfterSolving(false),
58 mUserSuppliedExtracellularStimulus(false),
64 template<
unsigned DIM>
67 mpSecondCellFactory(NULL),
68 mpExtendedBidomainTissue(NULL),
69 mUserSpecifiedSecondCellConductivities(false),
70 mUserHasSetBidomainValuesExplicitly(false),
71 mpExtracellularStimulusFactory(NULL),
72 mRowForAverageOfPhiZeroed(INT_MAX),
73 mApplyAveragePhieZeroConstraintAfterSolving(false),
74 mUserSuppliedExtracellularStimulus(false)
80 template<
unsigned DIM>
87 std::vector<DistributedVector::Stripe> stripe;
98 stripe[0][index] = mpExtendedBidomainTissue->GetCardiacCell(index.Global)->GetVoltage();
99 stripe[1][index] = mpExtendedBidomainTissue->GetCardiacSecondCell(index.Global)->GetVoltage();
100 stripe[2][index] = 0.0;
104 return initial_condition;
107 template<
unsigned DIM>
110 if ( mpExtracellularStimulusFactory == NULL )
116 assert(mpExtracellularStimulusFactory);
117 mpExtracellularStimulusFactory->SetMesh(this->mpMesh);
118 mpExtracellularStimulusFactory->SetCompatibleExtracellularStimulus();
120 std::vector<AbstractChasteRegion<DIM>* > grounded_regions = mpExtracellularStimulusFactory->GetRegionsToBeGrounded();
122 if ( (mUserSuppliedExtracellularStimulus) && grounded_regions.size() > 0 )
124 std::vector<unsigned> grounded_indices;
125 for (
unsigned global_node_index = 0; global_node_index < this->mpMesh->GetNumNodes(); global_node_index++)
127 if (this->mpMesh->GetDistributedVectorFactory()->IsGlobalIndexLocal(global_node_index))
129 for (
unsigned region_index = 0; region_index <grounded_regions.size(); region_index++)
131 if ( grounded_regions[region_index]->DoesContain( this->mpMesh->GetNode(global_node_index)->GetPoint() ) )
133 grounded_indices.push_back( this->mpMesh->GetNode(global_node_index)->GetIndex() );
139 SetFixedExtracellularPotentialNodes(grounded_indices);
143 template<
unsigned DIM>
147 mpSecondCellFactory->SetMesh(this->mpMesh);
150 ProcessExtracellularStimulus();
153 mpExtendedBidomainTissue =
new ExtendedBidomainTissue<DIM>(this->mpCellFactory, mpSecondCellFactory,mpExtracellularStimulusFactory);
159 if (mUserSpecifiedSecondCellConductivities)
161 mpExtendedBidomainTissue->SetIntracellularConductivitiesSecondCell(mIntracellularConductivitiesSecondCell);
165 c_vector<double, DIM> intra_conductivities;
167 mpExtendedBidomainTissue->SetIntracellularConductivitiesSecondCell(intra_conductivities);
172 mpExtendedBidomainTissue->CreateIntracellularConductivityTensorSecondCell();
174 if (mUserHasSetBidomainValuesExplicitly)
176 mpExtendedBidomainTissue->SetAmFirstCell(mAmFirstCell);
177 mpExtendedBidomainTissue->SetAmSecondCell(mAmSecondCell);
178 mpExtendedBidomainTissue->SetAmGap(mAmGap);
179 mpExtendedBidomainTissue->SetGGap(mGGap);
180 mpExtendedBidomainTissue->SetCmFirstCell(mCmFirstCell);
181 mpExtendedBidomainTissue->SetCmSecondCell(mCmSecondCell);
188 mpExtendedBidomainTissue->SetGGap(0.0);
193 mpExtendedBidomainTissue->SetGgapHeterogeneities(mGgapHeterogeneityRegions, mGgapHeterogenousValues);
194 mpExtendedBidomainTissue->CreateGGapConductivities();
196 return mpExtendedBidomainTissue;
199 template<
unsigned DIM>
209 mUserHasSetBidomainValuesExplicitly =
true;
212 template <
unsigned DIM>
215 if (rGgapHeterogeneityRegions.size() != rGgapValues.size() )
217 EXCEPTION (
"Gap junction heterogeneity areas must be of the same number as the heterogeneity values");
219 mGgapHeterogeneityRegions = rGgapHeterogeneityRegions;
220 mGgapHeterogenousValues =rGgapValues;
223 template <
unsigned DIM>
226 mpExtracellularStimulusFactory = pFactory;
227 mUserSuppliedExtracellularStimulus =
true;
230 template<
unsigned DIM>
245 mpExtendedBidomainTissue,
246 this->mpBoundaryConditionsContainer.get());
251 mpSolver->SetRowForAverageOfPhiZeroed(mRowForAverageOfPhiZeroed);
262 template<
unsigned DIM>
265 if (!mUserSuppliedExtracellularStimulus)
267 delete mpExtracellularStimulusFactory;
271 template<
unsigned DIM>
274 for (
unsigned i = 0; i < DIM; i++)
276 mIntracellularConductivitiesSecondCell[i] = conductivities[i];
278 mUserSpecifiedSecondCellConductivities =
true;
281 template<
unsigned DIM>
284 assert(mFixedExtracellularPotentialNodes.size() == 0);
285 mFixedExtracellularPotentialNodes.resize(nodes.size());
286 for (
unsigned i=0; i<nodes.size(); i++)
290 mFixedExtracellularPotentialNodes[i] = nodes[i];
294 template<
unsigned DIM>
299 mRowForAverageOfPhiZeroed = 2;
304 mRowForAverageOfPhiZeroed = 3*node - 1;
308 template<
unsigned DIM>
311 assert(mpExtendedBidomainTissue!=NULL);
312 return mpExtendedBidomainTissue;
315 template<
unsigned DIM>
320 std::cout <<
"Solved to time " << time <<
"\n" << std::flush;
323 double V_max_first_cell, V_min_first_cell, V_max_second_cell, V_min_second_cell, phi_e_min, phi_e_max;
325 VecStrideMax( this->mSolution, 0, PETSC_NULL, &V_max_first_cell );
326 VecStrideMin( this->mSolution, 0, PETSC_NULL, &V_min_first_cell );
328 VecStrideMax( this->mSolution, 1, PETSC_NULL, &V_max_second_cell );
329 VecStrideMin( this->mSolution, 1, PETSC_NULL, &V_min_second_cell );
331 VecStrideMax( this->mSolution, 2, PETSC_NULL, &phi_e_max );
332 VecStrideMin( this->mSolution, 2, PETSC_NULL, &phi_e_min );
336 std::cout <<
" V first cell = " <<
"[" <<V_min_first_cell <<
", " << V_max_first_cell <<
"]" <<
";\n"
337 <<
" V second cell = " <<
"[" <<V_min_second_cell <<
", " << V_max_second_cell <<
"]" <<
";\n"
338 <<
" Phi_e = " <<
"[" <<phi_e_min <<
", " << phi_e_max <<
"]" <<
";\n"
343 template<
unsigned DIM>
348 if ( this->mNodesToOutput.empty() )
351 this->mpWriter->DefineFixedDimension( this->mpMesh->GetNumNodes() );
359 mVoltageColumnId_Vm1 = this->mpWriter->DefineVariable(
"V",
"mV");
360 mVoltageColumnId_Vm2 = this->mpWriter->DefineVariable(
"V_2",
"mV");
361 mVoltageColumnId_Phie = this->mpWriter->DefineVariable(
"Phi_e",
"mV");
362 mVariablesIDs.push_back(mVoltageColumnId_Vm1);
363 mVariablesIDs.push_back(mVoltageColumnId_Vm2);
364 mVariablesIDs.push_back(mVoltageColumnId_Phie);
370 this->mpWriter->DefineUnlimitedDimension(
"Time",
"msecs", stepper.
EstimateTimeSteps()+1);
374 mVoltageColumnId_Vm1 = this->mpWriter->GetVariableByName(
"V");
375 mVoltageColumnId_Vm2 = this->mpWriter->GetVariableByName(
"V_2");
376 mVoltageColumnId_Phie = this->mpWriter->GetVariableByName(
"Phi_e");
383 template<
unsigned DIM>
386 this->mpWriter->PutUnlimitedVariable(time);
389 Vec ordered_voltages = this->mpMesh->GetDistributedVectorFactory()->CreateVec(3);
390 DistributedVector wrapped_ordered_solution = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(ordered_voltages);
391 DistributedVector wrapped_solution = this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(voltageVec);
402 index != wrapped_solution.
End();
405 wrapped_ordered_solution_first_stripe[index] = V_first_cell_stripe[index];
406 wrapped_ordered_solution_second_stripe[index] = V_second_cell_stripe[index];
407 wrapped_ordered_solution_third_stripe[index] = phi_e_stripe[index];
410 wrapped_ordered_solution.
Restore();
412 this->mpWriter->PutStripedVector(mVariablesIDs, ordered_voltages);
420 template<
unsigned DIM>
424 if (mFixedExtracellularPotentialNodes.empty())
427 if (mRowForAverageOfPhiZeroed==INT_MAX)
434 EXCEPTION(
"Bidomain external voltage is not bounded in this simulation - use KSP *absolute* tolerance");
440 template<
unsigned DIM>
447 template<
unsigned DIM>
void SetExtendedBidomainParameters(double Am1, double Am2, double AmGap, double Cm1, double Cm2, double Ggap)
virtual AbstractDynamicLinearPdeSolver< DIM, DIM, 3 > * CreateSolver()
void SetHasBath(bool hasBath)
virtual AbstractCardiacTissue< DIM > * CreateCardiacTissue()
ExtendedBidomainTissue< DIM > * GetExtendedBidomainTissue()
void SetExtracellularStimulusFactory(AbstractStimulusFactory< DIM > *pFactory)
void SetFixedExtracellularPotentialNodes(std::vector< unsigned > fixedExtracellularPotentialNodes)
void ProcessExtracellularStimulus()
void GetIntracellularConductivities(c_vector< double, 3 > &rIntraConductivities) const
DistributedVector CreateDistributedVector(Vec vec, bool readOnly=false)
#define EXCEPTION(message)
virtual void WriteOneStep(double time, Vec voltageVec)
void SetIntracellularConductivitiesForSecondCell(c_vector< double, DIM > conductivities)
virtual void PreSolveChecks()
Vec CreateInitialCondition()
void SetGgapHeterogeneities(std::vector< boost::shared_ptr< AbstractChasteRegion< DIM > > > &rGgapHeterogeneityRegions, std::vector< double > &rGgapValues)
void SetNodeForAverageOfPhiZeroed(unsigned node)
virtual void DefineWriterColumns(bool extending)
#define EXPORT_TEMPLATE_CLASS_SAME_DIMS(CLASS)
ExtendedBidomainProblem()
virtual ~ExtendedBidomainProblem()
void SetFixedExtracellularPotentialNodes(std::vector< unsigned > nodes)
unsigned EstimateTimeSteps() const
void WriteInfo(double time)
void SetUserSuppliedExtracellularStimulus(bool flag)
void WriteExtraVariablesOneStep()
static HeartConfig * Instance()
bool GetUseRelativeTolerance() const
std::vector< unsigned > mFixedExtracellularPotentialNodes
void DefineExtraVariablesWriterColumns(bool extending)