Commit 7908ff20 authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

3d adaptivity for parallelization.

parent 82dffb9a
...@@ -154,7 +154,9 @@ namespace AMDiS { ...@@ -154,7 +154,9 @@ namespace AMDiS {
} }
void getVertexDofs(FiniteElemSpace* feSpace, int ithEdge, int elType, void getVertexDofs(FiniteElemSpace* feSpace, int ithEdge, int elType,
DofContainer& dofs, bool parentVertices = 0) const DofContainer& dofs,
bool reverseMode,
bool parentVertices = false) const
{ {
FUNCNAME("Line::getVertexDofs()"); FUNCNAME("Line::getVertexDofs()");
......
...@@ -28,7 +28,7 @@ namespace AMDiS { ...@@ -28,7 +28,7 @@ namespace AMDiS {
MacroElement::~MacroElement() MacroElement::~MacroElement()
{ {
if (element) if (element)
delete element; delete element;
} }
MacroElement& MacroElement::operator=(const MacroElement &el) MacroElement& MacroElement::operator=(const MacroElement &el)
......
...@@ -262,7 +262,7 @@ namespace AMDiS { ...@@ -262,7 +262,7 @@ namespace AMDiS {
me->setIndex(macroElements.size()); me->setIndex(macroElements.size());
} }
void Mesh::removeMacroElements(std::vector<MacroElement*>& macros, void Mesh::removeMacroElements(std::set<MacroElement*>& macros,
const FiniteElemSpace *feSpace) const FiniteElemSpace *feSpace)
{ {
FUNCNAME("Mesh::removeMacroElement()"); FUNCNAME("Mesh::removeMacroElement()");
...@@ -276,11 +276,13 @@ namespace AMDiS { ...@@ -276,11 +276,13 @@ namespace AMDiS {
ElementDofIterator elDofIter(feSpace); ElementDofIterator elDofIter(feSpace);
// Map that stores for each dof pointer (which may have a list of dofs) // Map that stores for each dof pointer (which may have a list of dofs)
// all macro element indices that own the dof. // all macro element indices that own this dof.
DofElMap dofsOwner; DofElMap dofsOwner;
DofPosMap dofsPosIndex; DofPosMap dofsPosIndex;
// Determine all dof owner macro elements.
// === Determine to all dofs the macro elements where the dof is part of. ===
for (std::deque<MacroElement*>::iterator macroIt = macroElements.begin(); for (std::deque<MacroElement*>::iterator macroIt = macroElements.begin();
macroIt != macroElements.end(); ++macroIt) { macroIt != macroElements.end(); ++macroIt) {
elDofIter.reset((*macroIt)->getElement()); elDofIter.reset((*macroIt)->getElement());
...@@ -290,16 +292,31 @@ namespace AMDiS { ...@@ -290,16 +292,31 @@ namespace AMDiS {
} while (elDofIter.nextStrict()); } while (elDofIter.nextStrict());
} }
// Remove all the given macro elements. // === Remove macro elements from mesh macro element list. ===
for (std::vector<MacroElement*>::iterator macroIt = macros.begin();
macroIt != macros.end();
++macroIt) {
std::deque<MacroElement*>::iterator mEl = // Removing arbitrary elements from an std::deque is very slow. Therefore, we
find(macroElements.begin(), macroElements.end(), *macroIt); // create a new deque with all macro elements that should not be deleted. The
TEST_EXIT(mEl != macroElements.end()) // macro element deque is than replaced by the new created one.
("Cannot find MacroElement that should be removed!\n");
macroElements.erase(mEl); std::deque<MacroElement*> newMacroElements;
for (std::deque<MacroElement*>::iterator elIter = macroElements.begin();
elIter != macroElements.end(); ++elIter) {
// If the current mesh macro element should not be deleted, i.e., it is not a
// member of the list of macro elements to be deleted, is is inserted to the new
// macro element list.
if (macros.find(*elIter) == macros.end())
newMacroElements.push_back(*elIter);
}
// And replace the macro element list with the new one.
macroElements.clear();
macroElements = newMacroElements;
// === For all macro elements to be deleted, delete them also to be neighbours ===
// === of some other macro elements. ===
for (std::set<MacroElement*>::iterator macroIt = macros.begin();
macroIt != macros.end(); ++macroIt) {
// Go through all neighbours of the macro element and remove this macro element // Go through all neighbours of the macro element and remove this macro element
// to be neighbour of some other macro element. // to be neighbour of some other macro element.
...@@ -315,33 +332,44 @@ namespace AMDiS { ...@@ -315,33 +332,44 @@ namespace AMDiS {
} }
} }
// Decrease also the number of elements of the mesh.
nLeaves--; nLeaves--;
nElements--; nElements--;
}
// Remove this macro element from the dof owner list.
for (DofElMap::iterator dofsIt = dofsOwner.begin();
dofsIt != dofsOwner.end(); ++dofsIt) {
std::set<MacroElement*>::iterator mIt = dofsIt->second.find(*macroIt);
if (mIt != dofsIt->second.end())
dofsIt->second.erase(mIt);
}
// And remove the macro element from memory // === Check now all the dofs, that have no owner anymore and therefore have ===
delete *macroIt; // === to be removed. ===
}
int nRemainDofs = 0; int nRemainDofs = 0;
// Check now all the dofs, that have no owner anymore and therefore have to
// be removed.
for (DofElMap::iterator dofsIt = dofsOwner.begin(); for (DofElMap::iterator dofsIt = dofsOwner.begin();
dofsIt != dofsOwner.end(); ++dofsIt) { dofsIt != dofsOwner.end(); ++dofsIt) {
if (dofsIt->second.size() == 0)
bool deleteDof = true;
for (std::set<MacroElement*>::iterator elIter = dofsIt->second.begin();
elIter != dofsIt->second.end(); ++elIter) {
std::set<MacroElement*>::iterator mIt = macros.find(*elIter);
if (mIt == macros.end()) {
deleteDof = false;
break;
}
}
if (deleteDof)
freeDOF(const_cast<DegreeOfFreedom*>(dofsIt->first), freeDOF(const_cast<DegreeOfFreedom*>(dofsIt->first),
dofsPosIndex[dofsIt->first]); dofsPosIndex[dofsIt->first]);
else else
nRemainDofs++; nRemainDofs++;
} }
// === Finally, remove the macro elements from memory. ===
for (std::set<MacroElement*>::iterator macroIt = macros.begin();
macroIt != macros.end(); ++macroIt)
delete *macroIt;
nVertices = nRemainDofs; nVertices = nRemainDofs;
} }
...@@ -784,9 +812,9 @@ namespace AMDiS { ...@@ -784,9 +812,9 @@ namespace AMDiS {
int c_outside2 = c_el_info2->worldToCoord(*(g_xy), &c_lambda2); int c_outside2 = c_el_info2->worldToCoord(*(g_xy), &c_lambda2);
MSG("new_coord CHILD %d: outside=%d, lambda=(%.2f %.2f %.2f %.2f)\n", MSG("new_coord CHILD %d: outside=%d, lambda=(%.2f %.2f %.2f %.2f)\n",
ichild, c_outside, c_lambda[0],c_lambda[1],c_lambda[2],c_lambda[3]); ichild, c_outside, c_lambda[0], c_lambda[1], c_lambda[2], c_lambda[3]);
MSG("new_coord CHILD %d: outside=%d, lambda=(%.2f %.2f %.2f %.2f)\n", MSG("new_coord CHILD %d: outside=%d, lambda=(%.2f %.2f %.2f %.2f)\n",
1-ichild, c_outside2, c_lambda2[0],c_lambda2[1],c_lambda2[2], 1 - ichild, c_outside2, c_lambda2[0], c_lambda2[1], c_lambda2[2],
c_lambda2[3]); c_lambda2[3]);
if ((c_outside2 < 0) || (c_lambda2[c_outside2] > c_lambda[c_outside])) { if ((c_outside2 < 0) || (c_lambda2[c_outside2] > c_lambda[c_outside])) {
...@@ -830,23 +858,24 @@ namespace AMDiS { ...@@ -830,23 +858,24 @@ namespace AMDiS {
return inside; return inside;
} }
bool Mesh::getDofIndexCoords(const DegreeOfFreedom* dof,
bool Mesh::getDofIndexCoords(DegreeOfFreedom dof,
const FiniteElemSpace* feSpace, const FiniteElemSpace* feSpace,
WorldVector<double>& coords) WorldVector<double>& coords)
{ {
DimVec<double>* baryCoords; DimVec<double>* baryCoords;
bool found = false; bool found = false;
TraverseStack stack; TraverseStack stack;
Vector<DegreeOfFreedom> dofVec(feSpace->getBasisFcts()->getNumber()); std::vector<DegreeOfFreedom> dofVec(feSpace->getBasisFcts()->getNumber());
ElInfo *elInfo = stack.traverseFirst(this, -1, ElInfo *elInfo = stack.traverseFirst(this, -1,
Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS); Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
while (elInfo) { while (elInfo) {
feSpace->getBasisFcts()->getLocalIndicesVec(elInfo->getElement(), feSpace->getBasisFcts()->getLocalIndices(elInfo->getElement(),
feSpace->getAdmin(), feSpace->getAdmin(),
&dofVec); dofVec);
for (int i = 0; i < feSpace->getBasisFcts()->getNumber(); i++) { for (int i = 0; i < feSpace->getBasisFcts()->getNumber(); i++) {
if (dofVec[i] == *dof) { if (dofVec[i] == dof) {
baryCoords = feSpace->getBasisFcts()->getCoords(i); baryCoords = feSpace->getBasisFcts()->getCoords(i);
elInfo->coordToWorld(*baryCoords, coords); elInfo->coordToWorld(*baryCoords, coords);
found = true; found = true;
...@@ -863,39 +892,30 @@ namespace AMDiS { ...@@ -863,39 +892,30 @@ namespace AMDiS {
return found; return found;
} }
bool Mesh::getDofIndexCoords(DegreeOfFreedom dof,
const FiniteElemSpace* feSpace, void Mesh::getDofIndexCoords(const FiniteElemSpace* feSpace,
WorldVector<double>& coords) DOFVector<WorldVector<double> >& coords)
{ {
DimVec<double>* baryCoords; const BasisFunction* basFcts = feSpace->getBasisFcts();
bool found = false; int nBasFcts = basFcts->getNumber();
TraverseStack stack; std::vector<DegreeOfFreedom> dofVec(nBasFcts);
Vector<DegreeOfFreedom> dofVec(feSpace->getBasisFcts()->getNumber());
ElInfo *elInfo = stack.traverseFirst(this, -1, TraverseStack stack;
Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS); ElInfo *elInfo =
stack.traverseFirst(this, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
while (elInfo) { while (elInfo) {
feSpace->getBasisFcts()->getLocalIndicesVec(elInfo->getElement(), basFcts->getLocalIndices(elInfo->getElement(), feSpace->getAdmin(), dofVec);
feSpace->getAdmin(), for (int i = 0; i < nBasFcts; i++) {
&dofVec); DimVec<double> *baryCoords = basFcts->getCoords(i);
for (int i = 0; i < feSpace->getBasisFcts()->getNumber(); i++) { elInfo->coordToWorld(*baryCoords, coords[dofVec[i]]);
if (dofVec[i] == dof) {
baryCoords = feSpace->getBasisFcts()->getCoords(i);
elInfo->coordToWorld(*baryCoords, coords);
found = true;
break;
}
} }
if (found)
break;
elInfo = stack.traverseNext(elInfo); elInfo = stack.traverseNext(elInfo);
} }
return found;
} }
void Mesh::setDiameter(const WorldVector<double>& w) void Mesh::setDiameter(const WorldVector<double>& w)
{ {
diam = w; diam = w;
......
...@@ -414,7 +414,7 @@ namespace AMDiS { ...@@ -414,7 +414,7 @@ namespace AMDiS {
* that there are no global or local refinements, i.e., all macro elements have * that there are no global or local refinements, i.e., all macro elements have
* no children. * no children.
*/ */
void removeMacroElements(std::vector<MacroElement*>& macros, void removeMacroElements(std::set<MacroElement*>& macros,
const FiniteElemSpace* feSpace); const FiniteElemSpace* feSpace);
/// Frees the array of DOF pointers (see \ref createDOFPtrs) /// Frees the array of DOF pointers (see \ref createDOFPtrs)
...@@ -485,12 +485,31 @@ namespace AMDiS { ...@@ -485,12 +485,31 @@ namespace AMDiS {
*/ */
bool getDofIndexCoords(const DegreeOfFreedom* dof, bool getDofIndexCoords(const DegreeOfFreedom* dof,
const FiniteElemSpace* feSpace, const FiniteElemSpace* feSpace,
WorldVector<double>& coords); WorldVector<double>& coords)
{
return getDofIndexCoords(*dof, feSpace, coords);
}
/** \brief
* This function is equal to \ref getDofIndexCoords as defined above, but takes
* a DOF index instead of a DOF pointer.
*/
bool getDofIndexCoords(DegreeOfFreedom dof, bool getDofIndexCoords(DegreeOfFreedom dof,
const FiniteElemSpace* feSpace, const FiniteElemSpace* feSpace,
WorldVector<double>& coords); WorldVector<double>& coords);
/** \brief
* Traverse the whole mesh and stores to each DOF of the given finite element space
* the coordinates in a given DOFVector. Works in the same way as the function
* \ref getDofIndexCoords defined above.
*
* @param[in] feSpace The fe soace to be used for the search.
* @param[out] coords DOF vector that stores the coordinates to each dof.
*/
void getDofIndexCoords(const FiniteElemSpace* feSpace,
DOFVector<WorldVector<double> >& coords);
/// Returns FILL_ANY_?D /// Returns FILL_ANY_?D
inline static const Flag& getFillAnyFlag(int dim) inline static const Flag& getFillAnyFlag(int dim)
{ {
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "Traverse.h" #include "Traverse.h"
#include "ElInfo.h" #include "ElInfo.h"
#include "RefinementManager.h" #include "RefinementManager.h"
#include "InteriorBoundary.h"
namespace AMDiS { namespace AMDiS {
...@@ -59,7 +60,46 @@ namespace AMDiS { ...@@ -59,7 +60,46 @@ namespace AMDiS {
clear(); clear();
addAlongSide(el, ithSide, elType, reverseOrder); int s1 = el->getSideOfChild(0, ithSide, elType);
int s2 = el->getSideOfChild(1, ithSide, elType);
TEST_EXIT(s1 != -1 || s2 != -1)("This should not happen!\n");
if (!el->isLeaf()) {
if (s1 == -1)
addAlongSide(el->getSecondChild(), s2, el->getChildType(elType), reverseOrder);
else if (s2 == -1)
addAlongSide(el->getFirstChild(), s1, el->getChildType(elType), reverseOrder);
else
addAlongSide(el, ithSide, elType, reverseOrder);
}
commit();
}
void MeshStructure::init(BoundaryObject &bound)
{
FUNCNAME("MeshStructure::init()");
Element *el = bound.el;
clear();
int s1 = el->getSideOfChild(0, bound.ithObj, bound.elType);
int s2 = el->getSideOfChild(1, bound.ithObj, bound.elType);
TEST_EXIT(s1 != -1 || s2 != -1)("This should not happen!\n");
if (!el->isLeaf()) {
if (s1 == -1)
addAlongSide(el->getSecondChild(), s2,
el->getChildType(bound.elType), bound.reverseMode);
else if (s2 == -1)
addAlongSide(el->getFirstChild(), s1,
el->getChildType(bound.elType), bound.reverseMode);
else
addAlongSide(el, bound.ithObj, bound.elType, bound.reverseMode);
}
commit(); commit();
} }
...@@ -67,6 +107,14 @@ namespace AMDiS { ...@@ -67,6 +107,14 @@ namespace AMDiS {
void MeshStructure::addAlongSide(Element *el, int ithSide, int elType, void MeshStructure::addAlongSide(Element *el, int ithSide, int elType,
bool reverseOrder) bool reverseOrder)
{ {
FUNCNAME("MeshStructure::addAlongSide()");
if (debugMode) {
MSG("addAlondSide(%d, %d, %d, %d)\n",
el->getIndex(), ithSide, elType, reverseOrder);
MSG("Element is leaf: %d\n", el->isLeaf());
}
insertElement(el->isLeaf()); insertElement(el->isLeaf());
if (!el->isLeaf()) { if (!el->isLeaf()) {
...@@ -75,14 +123,14 @@ namespace AMDiS { ...@@ -75,14 +123,14 @@ namespace AMDiS {
if (!reverseOrder) { if (!reverseOrder) {
if (s1 != -1) if (s1 != -1)
addAlongSide(el->getFirstChild(), s1, el->getChildType(elType), reverseOrder); addAlongSide(el->getFirstChild(), s1, el->getChildType(elType), false);
if (s2 != -1) if (s2 != -1)
addAlongSide(el->getSecondChild(), s2, el->getChildType(elType), reverseOrder); addAlongSide(el->getSecondChild(), s2, el->getChildType(elType), false);
} else { } else {
if (s2 != -1) if (s2 != -1)
addAlongSide(el->getSecondChild(), s2, el->getChildType(elType), reverseOrder); addAlongSide(el->getSecondChild(), s2, el->getChildType(elType), false);
if (s1 != -1) if (s1 != -1)
addAlongSide(el->getFirstChild(), s1, el->getChildType(elType), reverseOrder); addAlongSide(el->getFirstChild(), s1, el->getChildType(elType), false);
} }
} }
} }
...@@ -90,9 +138,13 @@ namespace AMDiS { ...@@ -90,9 +138,13 @@ namespace AMDiS {
void MeshStructure::reset() void MeshStructure::reset()
{ {
currentIndex = 0; currentIndex = 0;
currentCode = code[0];
pos = 0; pos = 0;
currentElement = 0; currentElement = 0;
if (code.size() > 0)
currentCode = code[0];
else
currentCode = 0;
} }
bool MeshStructure::nextElement(MeshStructure *insert) bool MeshStructure::nextElement(MeshStructure *insert)
...@@ -238,4 +290,8 @@ namespace AMDiS { ...@@ -238,4 +290,8 @@ namespace AMDiS {
} while (!finished); } while (!finished);
} }
bool MeshStructure::compare(MeshStructure &other)
{
return (other.getCode() == code);
}
} }
...@@ -36,7 +36,8 @@ namespace AMDiS { ...@@ -36,7 +36,8 @@ namespace AMDiS {
currentCode(0), currentCode(0),
pos(0), pos(0),
currentElement(0), currentElement(0),
nElements(0) nElements(0),
debugMode(false)
{} {}
void clear(); void clear();
...@@ -46,6 +47,8 @@ namespace AMDiS { ...@@ -46,6 +47,8 @@ namespace AMDiS {
void init(Element *el, int ithSide, int elType, bool reverseOrder); void init(Element *el, int ithSide, int elType, bool reverseOrder);
void init(BoundaryObject &bound);
void init(const std::vector<unsigned long int>& initCode, int n) void init(const std::vector<unsigned long int>& initCode, int n)
{ {
code = initCode; code = initCode;
...@@ -59,6 +62,12 @@ namespace AMDiS { ...@@ -59,6 +62,12 @@ namespace AMDiS {
*/ */
void reset(); void reset();
/// Returns whether the code is empty or not.
inline bool empty()
{
return (nElements == 0);
}
inline void commit() inline void commit()
{ {
if (pos > 0) if (pos > 0)
...@@ -104,6 +113,11 @@ namespace AMDiS { ...@@ -104,6 +113,11 @@ namespace AMDiS {
{ {
FUNCNAME("MeshStructure::print()"); FUNCNAME("MeshStructure::print()");
if (empty()) {
std::cout << "-" << std::endl;
return;
}
reset(); reset();
bool cont = true; bool cont = true;
while (cont) { while (cont) {
...@@ -133,6 +147,14 @@ namespace AMDiS { ...@@ -133,6 +147,14 @@ namespace AMDiS {
return currentElement; return currentElement;
} }
void setDebugMode(bool b)
{
debugMode = b;
}
/// Returns true, if the given mesh structure code is equal to this one.
bool compare(MeshStructure &other);
protected: protected:
/// Insert a new element to the structure code. Is used by the init function. /// Insert a new element to the structure code. Is used by the init function.
void insertElement(bool isLeaf); void insertElement(bool isLeaf);
...@@ -157,6 +179,8 @@ namespace AMDiS { ...@@ -157,6 +179,8 @@ namespace AMDiS {
int nElements; int nElements;
bool debugMode;
static const int unsignedLongSize; static const int unsignedLongSize;
}; };
......
...@@ -24,8 +24,7 @@ namespace AMDiS { ...@@ -24,8 +24,7 @@ namespace AMDiS {
int dow = Global::getGeo(WORLD); int dow = Global::getGeo(WORLD);
TraverseStack stack; TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(mesh, -1, ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER);
Mesh::CALL_EVERY_EL_PREORDER);
while (elInfo) { while (elInfo) {
// get partition data // get partition data
PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> PartitionElementData *partitionData = dynamic_cast<PartitionElementData*>
...@@ -33,9 +32,8 @@ namespace AMDiS { ...@@ -33,9 +32,8 @@ namespace AMDiS {