36 #ifndef _BOUNDARYCONDITIONSCONTAINERIMPLEMENTATION_HPP_ 37 #define _BOUNDARYCONDITIONSCONTAINERIMPLEMENTATION_HPP_ 39 #include "BoundaryConditionsContainer.hpp" 40 #include "ConstBoundaryCondition.hpp" 41 #include "DistributedVector.hpp" 43 #include "HeartEventHandler.hpp" 44 #include "PetscMatTools.hpp" 45 #include "PetscVecTools.hpp" 46 #include "ReplicatableVector.hpp" 48 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
54 for (
unsigned index_of_unknown=0; index_of_unknown<PROBLEM_DIM; index_of_unknown++)
68 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
72 std::set<const AbstractBoundaryCondition<SPACE_DIM>*> deleted_conditions;
73 for (
unsigned i=0; i<PROBLEM_DIM; i++)
79 if (deleted_conditions.count(neumann_iterator->second) == 0)
81 deleted_conditions.insert(neumann_iterator->second);
87 delete neumann_iterator->second;
105 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
108 unsigned indexOfUnknown,
109 bool checkIfBoundaryNode)
111 assert(indexOfUnknown < PROBLEM_DIM);
112 if (checkIfBoundaryNode)
117 (*(this->
mpDirichletMap[indexOfUnknown]))[pBoundaryNode] = pBoundaryCondition;
120 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
130 for (
unsigned i=0; i<PROBLEM_DIM; i++)
136 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
139 unsigned indexOfUnknown)
141 assert(indexOfUnknown < PROBLEM_DIM);
150 if (p_const_cond->
GetValue(pBoundaryElement->
GetNode(0)->GetPoint()) != 0.0)
160 for (
unsigned unknown=0; unknown<PROBLEM_DIM; unknown++)
162 if (unknown == indexOfUnknown)
164 (*(
mpNeumannMap[indexOfUnknown]))[pBoundaryElement] = pBoundaryCondition;
178 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
180 unsigned indexOfUnknown)
185 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
188 unsigned indexOfUnknown)
190 assert(indexOfUnknown < PROBLEM_DIM);
205 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
207 unsigned indexOfUnknown)
209 assert(indexOfUnknown < PROBLEM_DIM);
256 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
260 bool applyToRhsVector)
275 if (matrix_is_symmetric)
303 lo = lo_s; hi = hi_s;
306 for (
unsigned i=lo; i<hi; i++)
308 dirichlet_conditions[i] = DBL_MAX;
311 for (
unsigned index_of_unknown=0; index_of_unknown<PROBLEM_DIM; index_of_unknown++)
319 assert(value != DBL_MAX);
321 unsigned row = PROBLEM_DIM*node_index + index_of_unknown;
322 dirichlet_conditions[row] = value;
329 dirichlet_conditions.Replicate(lo, hi);
332 std::vector<unsigned> rows_to_zero;
333 for (
unsigned i=0; i<dirichlet_conditions.GetSize(); i++)
335 if (dirichlet_conditions[i] != DBL_MAX)
337 rows_to_zero.push_back(i);
341 if (matrix_is_symmetric)
344 for (
unsigned i=0; i<rows_to_zero.size(); i++)
346 unsigned col = rows_to_zero[i];
347 double minus_value = -dirichlet_conditions[col];
378 if (matrix_is_symmetric)
388 if (applyToRhsVector)
400 for (
unsigned index_of_unknown=0; index_of_unknown<PROBLEM_DIM; index_of_unknown++)
409 unsigned row = PROBLEM_DIM*node_index + index_of_unknown;
421 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
424 bool applyToRhsVector)
426 bool has_periodic_bcs =
false;
427 for (
unsigned i=0; i<PROBLEM_DIM; i++)
431 has_periodic_bcs =
true;
440 std::vector<unsigned> rows_to_zero;
441 for (
unsigned index_of_unknown=0; index_of_unknown<PROBLEM_DIM; index_of_unknown++)
447 unsigned node_index_1 = iter->first->GetIndex();
448 unsigned row_index_1 = PROBLEM_DIM*node_index_1 + index_of_unknown;
449 rows_to_zero.push_back(row_index_1);
455 for (
unsigned index_of_unknown=0; index_of_unknown<PROBLEM_DIM; index_of_unknown++)
461 unsigned node_index_1 = iter->first->GetIndex();
462 unsigned node_index_2 = iter->second->GetIndex();
464 unsigned mat_index1 = PROBLEM_DIM*node_index_1 + index_of_unknown;
465 unsigned mat_index2 = PROBLEM_DIM*node_index_2 + index_of_unknown;
471 if (applyToRhsVector)
473 for (
unsigned index_of_unknown=0; index_of_unknown<PROBLEM_DIM; index_of_unknown++)
479 unsigned node_index = iter->first->GetIndex();
480 unsigned row_index = PROBLEM_DIM*node_index + index_of_unknown;
487 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
489 const Vec currentSolution,
493 for (
unsigned index_of_unknown=0; index_of_unknown<PROBLEM_DIM; index_of_unknown++)
512 residual_stripe[node_index]=solution_stripe[node_index] - value;
517 residual_distributed.
Restore();
521 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
524 unsigned num_boundary_conditions = 0;
525 for (
unsigned index_of_unknown=0; index_of_unknown<PROBLEM_DIM; index_of_unknown++)
527 num_boundary_conditions += this->
mpDirichletMap[index_of_unknown]->size();
530 std::vector<unsigned> rows_to_zero(num_boundary_conditions);
533 for (
unsigned index_of_unknown=0; index_of_unknown<PROBLEM_DIM; index_of_unknown++)
540 rows_to_zero[counter++] = PROBLEM_DIM*node_index + index_of_unknown;
548 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
553 for (
unsigned index_of_unknown=0; index_of_unknown<PROBLEM_DIM; index_of_unknown++)
563 for (
unsigned i=0; i<(*elt_iter)->GetNumNodes(); i++)
577 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
580 unsigned indexOfUnknown)
582 assert(indexOfUnknown < PROBLEM_DIM);
601 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
603 unsigned indexOfUnknown)
605 assert(indexOfUnknown < PROBLEM_DIM);
612 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
616 for (
unsigned index_of_unknown=0; index_of_unknown<PROBLEM_DIM; index_of_unknown++)
626 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
633 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
640 #endif // _BOUNDARYCONDITIONSCONTAINERIMPLEMENTATION_HPP_ void AssembleFinalLinearSystem()
DirichletIteratorType mDirichIterator
virtual unsigned GetNumBoundaryElements() const
void AddPeriodicBoundaryCondition(const Node< SPACE_DIM > *pNode1, const Node< SPACE_DIM > *pNode2)
void GetOwnershipRange(PetscInt &lo, PetscInt &hi)
BoundaryElementIterator GetBoundaryElementIteratorBegin() const
void ApplyDirichletToNonlinearResidual(const Vec currentSolution, Vec residual, DistributedVectorFactory &rFactory)
void ZeroMatrixRowsWithValueOnDiagonal(std::vector< unsigned > &rRows, double diagonalValue)
DistributedVector CreateDistributedVector(Vec vec, bool readOnly=false)
NeumannMapIterator mLastNeumannCondition[PROBLEM_DIM]
void DefineZeroDirichletOnMeshBoundary(AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > *pMesh, unsigned indexOfUnknown=0)
bool IsBoundaryNode() const
static void BeginEvent(unsigned event)
bool HasDirichletBoundaryConditions()
void AddNeumannBoundaryCondition(const BoundaryElement< ELEMENT_DIM-1, SPACE_DIM > *pBoundaryElement, const AbstractBoundaryCondition< SPACE_DIM > *pBoundaryCondition, unsigned indexOfUnknown=0)
Vec & rGetDirichletBoundaryConditionsVector()
std::map< const BoundaryElement< ELEMENT_DIM-1, SPACE_DIM > *, const AbstractBoundaryCondition< SPACE_DIM > * >::const_iterator NeumannMapIterator
void ZeroMatrixRowsAndColumnsWithValueOnDiagonal(std::vector< unsigned > &rRowColIndices, double diagonalValue)
bool IsGlobalIndexLocal(unsigned globalIndex)
BoundaryNodeIterator GetBoundaryNodeIteratorBegin() const
void ApplyDirichletToLinearProblem(LinearSystem &rLinearSystem, bool applyToMatrix=true, bool applyToRhsVector=true)
double GetNeumannBCValue(const BoundaryElement< ELEMENT_DIM-1, SPACE_DIM > *pSurfaceElement, const ChastePoint< SPACE_DIM > &rX, unsigned indexOfUnknown=0)
void ApplyPeriodicBcsToLinearProblem(LinearSystem &rLinearSystem, bool applyToMatrix=true, bool applyToRhsVector=true)
void AddDirichletBoundaryCondition(const Node< SPACE_DIM > *pBoundaryNode, const AbstractBoundaryCondition< SPACE_DIM > *pBoundaryCondition, unsigned indexOfUnknown=0, bool checkIfBoundaryNode=true)
Node< SPACE_DIM > * GetNode(unsigned localIndex) const
bool HasDirichletBoundaryCondition(const Node< SPACE_DIM > *pNode, unsigned indexOfUnknown=0)
std::map< const Node< SPACE_DIM > *, const Node< SPACE_DIM > * > * mpPeriodicBcMap[PROBLEM_DIM]
~BoundaryConditionsContainer()
unsigned GetNumBoundaryNodes() const
bool Validate(AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > *pMesh)
std::vector< Node< SPACE_DIM > * >::const_iterator BoundaryNodeIterator
DirichletMapType * mpDirichletMap[PROBLEM_DIM]
#define EXCEPT_IF_NOT(test)
ConstBoundaryCondition< SPACE_DIM > * mpZeroBoundaryCondition
bool AnyNonZeroNeumannConditions()
void SetRhsVectorElement(PetscInt row, double value)
BoundaryConditionsContainer(bool deleteConditions=true)
std::map< const BoundaryElement< ELEMENT_DIM-1, SPACE_DIM > *, const AbstractBoundaryCondition< SPACE_DIM > * > * mpNeumannMap[PROBLEM_DIM]
void DefineConstantDirichletOnMeshBoundary(AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > *pMesh, double value, unsigned indexOfUnknown=0)
void ApplyDirichletToNonlinearJacobian(Mat jacobian)
void DefineZeroNeumannOnMeshBoundary(AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > *pMesh, unsigned indexOfUnknown=0)
BoundaryNodeIterator GetBoundaryNodeIteratorEnd() const
NeumannMapIterator EndNeumann()
static void EndEvent(unsigned event)
std::vector< BoundaryElement< ELEMENT_DIM-1, SPACE_DIM > * >::const_iterator BoundaryElementIterator
NeumannMapIterator BeginNeumann()
double GetValue(const ChastePoint< SPACE_DIM > &rX) const
bool HasNeumannBoundaryCondition(const BoundaryElement< ELEMENT_DIM-1, SPACE_DIM > *pSurfaceElement, unsigned indexOfUnknown=0)
bool mAnyNonZeroNeumannConditionsForUnknown[PROBLEM_DIM]
void DeleteDirichletBoundaryConditions(std::set< const AbstractBoundaryCondition< SPACE_DIM > * > alreadyDeletedConditions=std::set< const AbstractBoundaryCondition< SPACE_DIM > * >())
Vec GetMatrixRowDistributed(unsigned rowIndex)
BoundaryElementIterator GetBoundaryElementIteratorEnd() const