#include "FiniteElemSpace.h" #include "BoundaryManager.h" #include "DOFIndexed.h" #include "DOFVector.h" #include "Traverse.h" #include "BasisFunction.h" #include "ElInfo.h" #include "OpenMP.h" namespace AMDiS { BoundaryManager::BoundaryManager(const FiniteElemSpace *feSpace) { localBounds.resize(omp_get_num_procs()); allocatedMemoryLocalBounds = feSpace->getBasisFcts()->getNumber(); for (int i = 0; i < static_cast(localBounds.size()); i++) { localBounds[i] = GET_MEMORY(BoundaryType, allocatedMemoryLocalBounds); } } BoundaryManager::BoundaryManager(BoundaryManager &bm) { localBCs = bm.localBCs; allocatedMemoryLocalBounds = bm.allocatedMemoryLocalBounds; localBounds.resize(bm.localBounds.size()); for (int i = 0; i < static_cast(localBounds.size()); i++) { localBounds[i] = GET_MEMORY(BoundaryType, allocatedMemoryLocalBounds); } } BoundaryManager::~BoundaryManager() { for (int i = 0; i < static_cast(localBounds.size()); i++) { FREE_MEMORY(localBounds[i], BoundaryType, allocatedMemoryLocalBounds); } } double BoundaryManager::boundResidual(ElInfo *elInfo, DOFMatrix *matrix, const DOFVectorBase *dv) { double result = 0.0; std::map::iterator it; for (it = localBCs.begin(); it != localBCs.end(); ++it) { if ((*it).second) result += (*it).second->boundResidual(elInfo, matrix, dv); } return result; } void BoundaryManager::fillBoundaryConditions(ElInfo *elInfo, DOFVectorBase *vec) { // ===== fill local conditions ============================================== const FiniteElemSpace *feSpace = vec->getFESpace(); Vector dofIndices; const BasisFunction *basisFcts = feSpace->getBasisFcts(); int nBasFcts = basisFcts->getNumber(); DOFAdmin *admin = feSpace->getAdmin(); std::map::iterator it; if (localBCs.size() > 0) { // get boundaries of all DOFs BoundaryType *localBound = localBounds[omp_get_thread_num()]; basisFcts->getBound(elInfo, localBound); // get dof indices basisFcts->getLocalIndicesVec(elInfo->getElement(), admin, &dofIndices); // apply non dirichlet boundary conditions for (it = localBCs.begin(); it != localBCs.end(); ++it) { if ((*it).second) { if (!(*it).second->isDirichlet()) { (*it).second->fillBoundaryCondition(vec, elInfo, &dofIndices[0], localBound, nBasFcts); } } } // apply dirichlet boundary conditions for (it = localBCs.begin(); it != localBCs.end(); ++it) { if ((*it).second) { if ((*it).second->isDirichlet()) { (*it).second->fillBoundaryCondition(vec, elInfo, &dofIndices[0], localBound, nBasFcts); } } } } } void BoundaryManager::fillBoundaryConditions(ElInfo *elInfo, DOFMatrix *mat) { // ===== fill local conditions ============================================== const FiniteElemSpace *feSpace = mat->getRowFESpace(); Vector dofIndices; const BasisFunction *basisFcts = feSpace->getBasisFcts(); int nBasFcts = basisFcts->getNumber(); DOFAdmin *admin = feSpace->getAdmin(); std::map::iterator it; if (localBCs.size() > 0) { // get boundaries of all DOFs BoundaryType *localBound = localBounds[omp_get_thread_num()]; basisFcts->getBound(elInfo, localBound); // get dof indices basisFcts->getLocalIndicesVec(elInfo->getElement(), admin, &dofIndices); // apply non dirichlet boundary conditions for (it = localBCs.begin(); it != localBCs.end(); ++it) { if ((*it).second) { if (!(*it).second->isDirichlet()) { (*it).second->fillBoundaryCondition(mat, elInfo, &dofIndices[0], localBound, nBasFcts); } } } // apply dirichlet boundary conditions for (it = localBCs.begin(); it != localBCs.end(); ++it) { if ((*it).second) { if ((*it).second->isDirichlet()) { (*it).second->fillBoundaryCondition(mat, elInfo, &dofIndices[0], localBound, nBasFcts); } } } } } void BoundaryManager::initMatrix(DOFMatrix *matrix) { std::map::iterator it; for (it = localBCs.begin(); it != localBCs.end(); ++it) { if ((*it).second) { if (!(*it).second->isDirichlet()) { (*it).second->initMatrix(matrix); } } } for (it = localBCs.begin(); it != localBCs.end(); ++it) { if ((*it).second) { if ((*it).second->isDirichlet()) { (*it).second->initMatrix(matrix); } } } } void BoundaryManager::exitMatrix(DOFMatrix *matrix) { std::map::iterator it; for (it = localBCs.begin(); it != localBCs.end(); ++it) { if ((*it).second) { if (!(*it).second->isDirichlet()) { (*it).second->exitMatrix(matrix); } } } for(it = localBCs.begin(); it != localBCs.end(); ++it) { if((*it).second) { if((*it).second->isDirichlet()) { (*it).second->exitMatrix(matrix); } } } } void BoundaryManager::initVector(DOFVectorBase *vector) { std::map::iterator it; for(it = localBCs.begin(); it != localBCs.end(); ++it) { if((*it).second) { if(!(*it).second->isDirichlet()) { (*it).second->initVector(vector); } } } for(it = localBCs.begin(); it != localBCs.end(); ++it) { if((*it).second) { if((*it).second->isDirichlet()) { (*it).second->initVector(vector); } } } } void BoundaryManager::exitVector(DOFVectorBase *vector) { std::map::iterator it; for (it = localBCs.begin(); it != localBCs.end(); ++it) { if ((*it).second) { if (!(*it).second->isDirichlet()) { (*it).second->exitVector(vector); } } } for (it = localBCs.begin(); it != localBCs.end(); ++it) { if ((*it).second) { if ((*it).second->isDirichlet()) { (*it).second->exitVector(vector); } } } } }