36 #include "AbstractExtendedBidomainSolver.hpp"
38 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
41 if (this->mpLinearSystem != NULL)
52 std::cout <<
"Using absolute tolerance: " << mpConfig->GetAbsoluteTolerance() <<
"\n";
54 this->mpLinearSystem->SetAbsoluteTolerance(mpConfig->GetAbsoluteTolerance());
59 std::cout <<
"Using relative tolerance: " << mpConfig->GetRelativeTolerance() <<
"\n";
61 this->mpLinearSystem->SetRelativeTolerance(mpConfig->GetRelativeTolerance());
67 if (mRowForAverageOfPhiZeroed==INT_MAX)
70 this->mpLinearSystem->SetMatrixIsSymmetric(
true);
77 this->mpLinearSystem->SetMatrixIsSymmetric(
false);
82 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
88 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
91 double sqrrt_num_nodes = sqrt( this->mpMesh->GetNumNodes());
92 double normalised_basis_value = 1.0 / sqrrt_num_nodes;
102 index != dist_null_basis.
End();
105 null_basis_stripe_0[index] = 0.0;
106 null_basis_stripe_1[index] = 0.0;
107 null_basis_stripe_2[index] = normalised_basis_value;
114 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
117 if (!(this->mpBoundaryConditions->HasDirichletBoundaryConditions()))
120 if (mRowForAverageOfPhiZeroed==INT_MAX)
123 if (!mNullSpaceCreated)
126 Vec nullbasis[] = {GenerateNullBasis()};
128 this->mpLinearSystem->SetNullBasis(nullbasis, 1);
131 mNullSpaceCreated =
true;
137 this->mpLinearSystem->SetKspType(
"gmres");
138 mpConfig->SetKSPSolver(
"gmres",
true);
142 unsigned matrix_size = this->mpLinearSystem->GetSize();
143 if (!this->mMatrixIsAssembled)
147 std::vector<unsigned> row_for_average;
148 row_for_average.push_back(mRowForAverageOfPhiZeroed);
149 this->mpLinearSystem->ZeroMatrixRowsWithValueOnDiagonal(row_for_average, 0.0);
150 for (
unsigned col_index=0; col_index<matrix_size; col_index++)
152 if (((col_index-2)%3 == 0) && (col_index>1))
154 this->mpLinearSystem->SetMatrixElement(mRowForAverageOfPhiZeroed, col_index, 1);
158 this->mpLinearSystem->FinaliseLhsMatrix();
161 this->mpLinearSystem->SetRhsVectorElement(mRowForAverageOfPhiZeroed, 0);
163 this->mpLinearSystem->FinaliseRhsVector();
166 CheckCompatibilityCondition();
169 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
172 if (this->mpBoundaryConditions->HasDirichletBoundaryConditions() || mRowForAverageOfPhiZeroed!=INT_MAX )
179 DistributedVector distributed_rhs=this->mpMesh->GetDistributedVectorFactory()->CreateDistributedVector(this->mpLinearSystem->rGetRhsVector());
184 index!= distributed_rhs.
End();
187 local_sum += distributed_rhs_phi_entries[index];
191 int mpi_ret = MPI_Allreduce(&local_sum, &global_sum, 1, MPI_DOUBLE, MPI_SUM, PETSC_COMM_WORLD);
192 assert(mpi_ret == MPI_SUCCESS);
194 if(fabs(global_sum)>1e-6)
196 #define COVERAGE_IGNORE
198 std::cout <<
"Sum of b_{every 3 items} = " << global_sum <<
" (should be zero for compatibility)\n";
199 EXCEPTION(
"Linear system does not satisfy compatibility constraint!");
200 #undef COVERAGE_IGNORE
205 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
212 mBathSimulation(bathSimulation),
213 mpExtendedBidomainTissue(pTissue),
214 mpBoundaryConditions(pBcc)
216 assert(pTissue != NULL);
217 assert(pBcc != NULL);
230 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
235 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
237 std::vector<unsigned> fixedExtracellularPotentialNodes)
239 for (
unsigned i=0; i<fixedExtracellularPotentialNodes.size(); i++)
241 if (fixedExtracellularPotentialNodes[i] >= this->mpMesh->GetNumNodes() )
243 EXCEPTION(
"Fixed node number must be less than total number nodes");
247 mFixedExtracellularPotentialNodes = fixedExtracellularPotentialNodes;
250 this->mpBoundaryConditions->ResetDirichletCommunication();
252 for (
unsigned i=0; i<mFixedExtracellularPotentialNodes.size(); i++)
254 if (this->mpMesh->GetDistributedVectorFactory()->IsGlobalIndexLocal(mFixedExtracellularPotentialNodes[i]))
259 Node<SPACE_DIM>* p_node = this->mpMesh->GetNode(mFixedExtracellularPotentialNodes[i]);
262 GetBoundaryConditions()->AddDirichletBoundaryCondition(p_node, p_boundary_condition, 2,
false);
267 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
271 if ( ((row-2)%3 != 0) && row!=INT_MAX)
273 EXCEPTION(
"Row for applying the constraint 'Average of phi_e = zero' should be every 3 rows");
276 mRowForAverageOfPhiZeroed = row;
virtual void CheckCompatibilityCondition()
ExtendedBidomainAssembler< ELEMENT_DIM, SPACE_DIM > * mpExtendedBidomainAssembler
virtual void InitialiseForSolve(Vec initialSolution=NULL)
virtual ~AbstractExtendedBidomainSolver()
void SetFixedExtracellularPotentialNodes(std::vector< unsigned > fixedExtracellularPotentialNodes)
void SetRowForAverageOfPhiZeroed(unsigned rowMeanPhiEZero)
DistributedVector CreateDistributedVector(Vec vec, bool readOnly=false)
virtual Vec GenerateNullBasis() const
#define EXCEPTION(message)
virtual void FinaliseLinearSystem(Vec existingSolution)
void PrepareForSetupLinearSystem(Vec existingSolution)
unsigned mRowForAverageOfPhiZeroed
static double GetNextTime()
AbstractExtendedBidomainSolver(bool bathSimulation, AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > *pMesh, ExtendedBidomainTissue< SPACE_DIM > *pTissue, BoundaryConditionsContainer< ELEMENT_DIM, SPACE_DIM, 3 > *pBcc)
void InitialiseForSolve(Vec initialSolution)
static HeartConfig * Instance()