Commit 3b97cf2b authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

* Parallel assemblage

* BoundaryManager.hh deleted, was not included in any file
parent 1a397625
...@@ -177,18 +177,17 @@ namespace AMDiS { ...@@ -177,18 +177,17 @@ namespace AMDiS {
DegreeOfFreedom*) const = 0; DegreeOfFreedom*) const = 0;
/** \brief /** \brief
* Pointer to a function which fills a vector with the boundary types of the * The second argument 'bound' has to be a pointer to a vector which has
* basis functions; * to be filled. Its length is \ref nBasFcts (the number of basis functions
* getBound(el info, bound) returns a pointer to this vector of length * in the used finite element space). After calling this function, the i-th
* \ref nBasFcts where the i-th entry is the boundary type of the i-th basis * entry of the array is the boundary type of the i-th basis function of this
* function; bound may be a pointer to a vector which has to be filled * element.
* (compare the dof argument of \ref getDOFIindices); *
* such a function needs boundary information; thus, all routines using this * This function needs boundary information within the ElInfo object; thus,
* function on the elements need the FILL_BOUND flag during mesh traversal; * all routines using this function on the elements need the FILL_BOUND
*/ * flag during mesh traversal;
virtual const BoundaryType* getBound(const ElInfo*, BoundaryType *) const { */
return NULL; virtual void getBound(const ElInfo*, BoundaryType *) const {};
};
/** \brief /** \brief
* Returns \ref degree of BasisFunction * Returns \ref degree of BasisFunction
......
#include "FiniteElemSpace.h" #include "FiniteElemSpace.h"
//#include "BoundaryCondition.h"
#include "BoundaryManager.h" #include "BoundaryManager.h"
#include "DOFIndexed.h" #include "DOFIndexed.h"
#include "DOFVector.h" #include "DOFVector.h"
#include "Traverse.h" #include "Traverse.h"
#include "BasisFunction.h" #include "BasisFunction.h"
#include "ElInfo.h" #include "ElInfo.h"
#include "OpenMP.h"
namespace AMDiS { namespace AMDiS {
BoundaryManager::BoundaryManager(const FiniteElemSpace *feSpace)
{
localBounds.resize(omp_get_max_threads());
allocatedMemoryLocalBounds = feSpace->getBasisFcts()->getNumber();
for (int i = 0; i < static_cast<int>(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<int>(localBounds.size()); i++) {
localBounds[i] = GET_MEMORY(BoundaryType, allocatedMemoryLocalBounds);
}
}
BoundaryManager::~BoundaryManager()
{
for (int i = 0; i < static_cast<int>(localBounds.size()); i++) {
FREE_MEMORY(localBounds[i], BoundaryType, allocatedMemoryLocalBounds);
}
}
double BoundaryManager::boundResidual(ElInfo *elInfo, double BoundaryManager::boundResidual(ElInfo *elInfo,
DOFMatrix *matrix, DOFMatrix *matrix,
const DOFVectorBase<double> *dv) const DOFVectorBase<double> *dv)
{ {
double result = 0; double result = 0.0;
std::map<BoundaryType, BoundaryCondition*>::iterator it; std::map<BoundaryType, BoundaryCondition*>::iterator it;
for (it = localBCs.begin(); it != localBCs.end(); ++it) { for (it = localBCs.begin(); it != localBCs.end(); ++it) {
if ((*it).second) if ((*it).second)
...@@ -37,7 +63,7 @@ namespace AMDiS { ...@@ -37,7 +63,7 @@ namespace AMDiS {
if (localBCs.size() > 0) { if (localBCs.size() > 0) {
// get boundaries of all DOFs // get boundaries of all DOFs
BoundaryType *localBound = GET_MEMORY(BoundaryType, nBasFcts); BoundaryType *localBound = localBounds[omp_get_thread_num()];
basisFcts->getBound(elInfo, localBound); basisFcts->getBound(elInfo, localBound);
// get dof indices // get dof indices
...@@ -60,8 +86,6 @@ namespace AMDiS { ...@@ -60,8 +86,6 @@ namespace AMDiS {
} }
} }
} }
FREE_MEMORY(localBound, BoundaryType, nBasFcts);
} }
} }
...@@ -79,7 +103,9 @@ namespace AMDiS { ...@@ -79,7 +103,9 @@ namespace AMDiS {
if (localBCs.size() > 0) { if (localBCs.size() > 0) {
// get boundaries of all DOFs // get boundaries of all DOFs
const BoundaryType *localBound = basisFcts->getBound(elInfo, NULL); BoundaryType *localBound = localBounds[omp_get_thread_num()];
basisFcts->getBound(elInfo, localBound);
// get dof indices // get dof indices
basisFcts->getLocalIndicesVec(elInfo->getElement(), admin, &dofIndices); basisFcts->getLocalIndicesVec(elInfo->getElement(), admin, &dofIndices);
......
...@@ -50,6 +50,12 @@ namespace AMDiS { ...@@ -50,6 +50,12 @@ namespace AMDiS {
public: public:
MEMORY_MANAGED(BoundaryManager); MEMORY_MANAGED(BoundaryManager);
BoundaryManager(const FiniteElemSpace *feSpace);
BoundaryManager(BoundaryManager &bm);
~BoundaryManager();
/** \brief /** \brief
* Adds a local boundary condition to the list of managed conditions. * Adds a local boundary condition to the list of managed conditions.
*/ */
...@@ -92,11 +98,6 @@ namespace AMDiS { ...@@ -92,11 +98,6 @@ namespace AMDiS {
return localBCs[type]; return localBCs[type];
}; };
// /** \brief
// * Fills boundary types in DOFVectorBase bound.
// */
// void fillGlobalBoundVector(DOFVectorBase<BoundaryType> *bound);
const std::map<BoundaryType, BoundaryCondition*>& getBoundaryConditionMap() { const std::map<BoundaryType, BoundaryCondition*>& getBoundaryConditionMap() {
return localBCs; return localBCs;
}; };
...@@ -110,6 +111,17 @@ namespace AMDiS { ...@@ -110,6 +111,17 @@ namespace AMDiS {
* Map of managed local boundary conditions. * Map of managed local boundary conditions.
*/ */
std::map<BoundaryType, BoundaryCondition*> localBCs; std::map<BoundaryType, BoundaryCondition*> localBCs;
/** \brief
* Temporary thread-safe variable for functions fillBoundaryconditions.
*/
std::vector<BoundaryType*> localBounds;
/** \brief
* Stores the number of byte that were allocated in the constructor for
* each localBounds value. Is used to free the memory in the destructor.
*/
int allocatedMemoryLocalBounds;
}; };
} }
......
#include "FiniteElemSpace.h"
#include "DOFIndexed.h"
#include "DOFVector.h"
#include "Traverse.h"
#include "BasisFunction.h"
#include "ElInfo.h"
#include "BoundaryCondition.h"
#include <list>
namespace AMDiS {
template<typename T>
double BoundaryManager<T>::boundResidual(ElInfo *elInfo, Estimator<T> *estimator)
{
double result = 0;
typename std::list<LocalBC<T>*>::iterator it;
for(it = localBCs.begin(); it != localBCs.end(); ++it) {
result += (*it)->boundResidual(elInfo, estimator);
}
return result;
}
template<typename T>
void BoundaryManager<T>::fillGlobalBoundVector(DOFVector<BoundaryType> *globalBound)
{
int i;
TraverseStack stack;
const FiniteElemSpace *feSpace = globalBound->getFESpace();
const BasisFunction *basisFcts = feSpace->getBasisFcts();
int nBasFcts = basisFcts->getNumber();
Mesh *mesh = feSpace->getMesh();
DOFAdmin *admin = feSpace->getAdmin();
const BoundaryType *localBound = NULL;
const DegreeOfFreedom *dofIndices = NULL;
ElInfo *elInfo =
stack.traverseFirst(mesh, -1,
Mesh::CALL_LEAF_EL |
Mesh::FILL_BOUND |
Mesh::FILL_COORDS);
// for all elements ...
while(elInfo) {
// get boundaries of all DOFs
localBound = basisFcts->getBound(elInfo, NULL);
// get dof indices
dofIndices = basisFcts->getLocalIndices(elInfo->getElement(),
admin, NULL);
// for all DOFs
for(i=0; i < nBasFcts; i++) {
(*globalBound)[dofIndices[i]] = localBound[i];
}
elInfo = stack.traverseNext(elInfo);
}
}
template<typename T>
void BoundaryManager<T>::fillLocalBCs(ElInfo *elInfo,
DOFVector<T> *vec)
{
int i;
// ===== fill local conditions ==============================================
const FiniteElemSpace *feSpace = vec->getFESpace();
const BoundaryType *localBound = NULL;
const DegreeOfFreedom *dofIndices = NULL;
Mesh *mesh = feSpace->getMesh();
const BasisFunction *basisFcts = feSpace->getBasisFcts();
int nBasFcts = basisFcts->getNumber();
LocalBC<T> *localBC;
DOFAdmin *admin = feSpace->getAdmin();
typename std::list<LocalBC<T>*>::iterator it;
if(localBCs.size() > 0) {
// get boundaries of all DOFs
localBound = basisFcts->getBound(elInfo, NULL);
// get dof indices
dofIndices = basisFcts->getLocalIndices(elInfo->getElement(),
admin, NULL);
// apply boundary conditions
for(it = localBCs.begin(); it != localBCs.end(); ++it) {
(*it)->fillLocalBC(vec, elInfo, dofIndices, localBound, nBasFcts);
}
}
}
template<typename T>
void BoundaryManager<T>::fillLocalBCs(ElInfo *elInfo,
DOFMatrix *mat)
{
int i;
// ===== fill local conditions ==============================================
const FiniteElemSpace *feSpace = mat->getRowFESpace();
const BoundaryType *localBound = NULL;
const DegreeOfFreedom *dofIndices = NULL;
Mesh *mesh = feSpace->getMesh();
const BasisFunction *basisFcts = feSpace->getBasisFcts();
int nBasFcts = basisFcts->getNumber();
LocalBC<T> *localBC;
DOFAdmin *admin = feSpace->getAdmin();
typename std::list<LocalBC<T>*>::iterator it;
if(localBCs.size() > 0) {
// get boundaries of all DOFs
localBound = basisFcts->getBound(elInfo, NULL);
// get dof indices
dofIndices = basisFcts->getLocalIndices(elInfo->getElement(),
admin, NULL);
// apply boundary conditions
for(it = localBCs.begin(); it != localBCs.end(); ++it) {
(*it)->fillLocalBC(mat, elInfo, dofIndices, localBound, nBasFcts);
}
}
}
}
...@@ -42,9 +42,11 @@ namespace AMDiS { ...@@ -42,9 +42,11 @@ namespace AMDiS {
if (rowFESpace && rowFESpace->getAdmin()) if (rowFESpace && rowFESpace->getAdmin())
(const_cast<DOFAdmin*>(rowFESpace->getAdmin()))->addDOFIndexed(this); (const_cast<DOFAdmin*>(rowFESpace->getAdmin()))->addDOFIndexed(this);
boundaryManager = NEW BoundaryManager; boundaryManager = NEW BoundaryManager(rowFESpace_);
elementMatrix = NEW ElementMatrix(rowFESpace->getBasisFcts()->getNumber(), elementMatrix = NEW ElementMatrix(rowFESpace->getBasisFcts()->getNumber(),
colFESpace->getBasisFcts()->getNumber()); colFESpace->getBasisFcts()->getNumber());
applyDBCs.clear();
} }
DOFMatrix::DOFMatrix(const DOFMatrix& rhs) DOFMatrix::DOFMatrix(const DOFMatrix& rhs)
...@@ -215,7 +217,7 @@ namespace AMDiS { ...@@ -215,7 +217,7 @@ namespace AMDiS {
operatorFactor = rhs.operatorFactor; operatorFactor = rhs.operatorFactor;
matrix = rhs.matrix; matrix = rhs.matrix;
if (rhs.boundaryManager) { if (rhs.boundaryManager) {
boundaryManager = new BoundaryManager(*rhs.boundaryManager); boundaryManager = NEW BoundaryManager(*rhs.boundaryManager);
} else { } else {
boundaryManager = NULL; boundaryManager = NULL;
} }
...@@ -248,14 +250,15 @@ namespace AMDiS { ...@@ -248,14 +250,15 @@ namespace AMDiS {
bound ? boundaryManager->getBoundaryCondition(bound[i]) : NULL; bound ? boundaryManager->getBoundaryCondition(bound[i]) : NULL;
if (condition && condition->isDirichlet()) { if (condition && condition->isDirichlet()) {
MatrixRow *matrixRow = &(matrix[row]); /* MatrixRow *matrixRow = &(matrix[row]);
if (coupleMatrix) { if (coupleMatrix) {
matrixRow->resize(0); matrixRow->resize(0);
} else { } else {
matrixRow->resize(1); matrixRow->resize(1);
((*matrixRow)[0]).col = row; ((*matrixRow)[0]).col = row;
((*matrixRow)[0]).entry = 1.0; ((*matrixRow)[0]).entry = 1.0;
} } */
applyDBCs.insert(static_cast<int>(row));
} else { } else {
for (int j = 0; j < nCol; j++) { // for all columns for (int j = 0; j < nCol; j++) { // for all columns
addSparseDOFEntry(sign, row, elMat.colIndices[j], addSparseDOFEntry(sign, row, elMat.colIndices[j],
...@@ -653,6 +656,21 @@ namespace AMDiS { ...@@ -653,6 +656,21 @@ namespace AMDiS {
} }
} }
void DOFMatrix::removeRowsWithDBC(std::set<int> *rows)
{
for (std::set<int>::iterator it = rows->begin();
it != rows->end();
++it) {
if (coupleMatrix) {
matrix[*it].resize(0);
} else {
matrix[*it].resize(1);
matrix[*it][0].col = *it;
matrix[*it][0].entry = 1.0;
}
}
}
void DOFMatrix::createPictureFile(const char* filename, int dim) void DOFMatrix::createPictureFile(const char* filename, int dim)
{ {
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
...@@ -814,4 +832,36 @@ namespace AMDiS { ...@@ -814,4 +832,36 @@ namespace AMDiS {
} }
} }
void addDOFMatrix(DOFMatrix *result, const DOFMatrix *a)
{
DOFMatrix::Iterator resultIterator(result, USED_DOFS);
DOFMatrix::Iterator aIterator(const_cast<DOFMatrix*>(a), USED_DOFS);
for (resultIterator.reset(), aIterator.reset();
!aIterator.end();
++resultIterator, ++aIterator) {
std::vector<MatEntry>::iterator resultRowIt;
std::vector<MatEntry>::const_iterator aRowIt;
for (aRowIt = aIterator->begin();
aRowIt != aIterator->end();
++aRowIt) {
bool added = false;
for (resultRowIt = resultIterator->begin();
resultRowIt != resultIterator->end();
++resultRowIt) {
if (aRowIt->col == resultRowIt->col) {
resultRowIt->entry += aRowIt->entry;
added = true;
break;
}
}
if (!added) {
resultIterator->push_back(*aRowIt);
}
}
}
}
} }
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
// ============================================================================ // ============================================================================
#include <vector> #include <vector>
#include <set>
#include <memory> #include <memory>
#include <list> #include <list>
#include "Global.h" #include "Global.h"
...@@ -581,6 +582,8 @@ namespace AMDiS { ...@@ -581,6 +582,8 @@ namespace AMDiS {
void addRow(std::vector<MatEntry> row); void addRow(std::vector<MatEntry> row);
void removeRowsWithDBC(std::set<int> *rows);
/** \brief /** \brief
* Prints \ref matrix to stdout * Prints \ref matrix to stdout
*/ */
...@@ -619,6 +622,10 @@ namespace AMDiS { ...@@ -619,6 +622,10 @@ namespace AMDiS {
return boundaryManager; return boundaryManager;
}; };
std::set<int>* getApplyDBCs() {
return &applyDBCs;
}
inline void setBoundaryManager(BoundaryManager *bm) { inline void setBoundaryManager(BoundaryManager *bm) {
boundaryManager = bm; boundaryManager = bm;
}; };
...@@ -720,6 +727,8 @@ namespace AMDiS { ...@@ -720,6 +727,8 @@ namespace AMDiS {
*/ */
ElementMatrix *elementMatrix; ElementMatrix *elementMatrix;
std::set<int> applyDBCs;
friend class DOFAdmin; friend class DOFAdmin;
friend class DOFVector<double>; friend class DOFVector<double>;
friend class DOFVector<unsigned char>; friend class DOFVector<unsigned char>;
...@@ -739,8 +748,16 @@ namespace AMDiS { ...@@ -739,8 +748,16 @@ namespace AMDiS {
double max(std::vector<MatEntry> *row); double max(std::vector<MatEntry> *row);
/** \brief
* Addes two matrices. The result matrix is overwritten.
*/
void addDOFMatrix(DOFMatrix *result, const DOFMatrix *a, const DOFMatrix *b); void addDOFMatrix(DOFMatrix *result, const DOFMatrix *a, const DOFMatrix *b);
/** \brief
* Addes matrix a to matrix result.
*/
void addDOFMatrix(DOFMatrix *result, const DOFMatrix *a);
} }
#endif // AMDIS_DOFMATRIX_H #endif // AMDIS_DOFMATRIX_H
...@@ -70,7 +70,7 @@ namespace AMDiS { ...@@ -70,7 +70,7 @@ namespace AMDiS {
(feSpace->getAdmin())->addDOFIndexed(this); (feSpace->getAdmin())->addDOFIndexed(this);
} }
this->boundaryManager = NEW BoundaryManager; this->boundaryManager = NEW BoundaryManager(f);
} }
template<typename T> template<typename T>
......
...@@ -88,13 +88,6 @@ namespace AMDiS { ...@@ -88,13 +88,6 @@ namespace AMDiS {
*/ */
#define DIM_OF_INDEX(ind, dim) ((static_cast<int>(ind) == 0) ? dim : static_cast<int>(ind) - 1) #define DIM_OF_INDEX(ind, dim) ((static_cast<int>(ind) == 0) ? dim : static_cast<int>(ind) - 1)
/** \brief
* Returns boundary->getBound() if boundary is not NULL. Returns INTERIOR
* otherwise.
*/
//#define GET_BOUND(boundary) ((boundary) ? (boundary)->getBound() : INTERIOR)
/** \brief /** \brief
* Calculates factorial of i * Calculates factorial of i
*/ */
......
...@@ -765,27 +765,8 @@ namespace AMDiS { ...@@ -765,27 +765,8 @@ namespace AMDiS {
return NULL; return NULL;
} }
const BoundaryType* Lagrange::getBound(const ElInfo* el_info, void Lagrange::getBound(const ElInfo* el_info, BoundaryType* bound) const
BoundaryType* bound) const
{ {
static BoundaryType *bound_vec = NULL;
static int bound_vec_size = 0;
BoundaryType *result;
if (bound) {
result = bound;
} else {
// realloc memory if neccessary
if (bound_vec_size < nBasFcts) {
if (bound_vec)
FREE_MEMORY(bound_vec, BoundaryType, bound_vec_size);
bound_vec = GET_MEMORY(BoundaryType, nBasFcts);
bound_vec_size = nBasFcts;
}
result = bound_vec;
}
el_info->testFlag(Mesh::FILL_BOUND); el_info->testFlag(Mesh::FILL_BOUND);
// boundaries // boundaries
...@@ -801,7 +782,7 @@ namespace AMDiS { ...@@ -801,7 +782,7 @@ namespace AMDiS {
boundaryType = el_info->getBoundary(j); boundaryType = el_info->getBoundary(j);
int kto = (*nDOF)[INDEX_OF_DIM(i, dim)]; int kto = (*nDOF)[INDEX_OF_DIM(i, dim)];
for (int k = 0; k < kto; k++) { for (int k = 0; k < kto; k++) {
result[index++] = boundaryType; bound[index++] = boundaryType;
} }
} }
offset -= Global::getGeo(INDEX_OF_DIM(i + 1, dim), dim); offset -= Global::getGeo(INDEX_OF_DIM(i + 1, dim), dim);
...@@ -809,12 +790,10 @@ namespace AMDiS { ...@@ -809,12 +790,10 @@ namespace AMDiS {
// interior nodes in the center // interior nodes in the center
for (int i = 0; i < (*nDOF)[CENTER]; i++) { for (int i = 0; i < (*nDOF)[CENTER]; i++) {
result[index++] = INTERIOR; bound[index++] = INTERIOR;
} }