Commit 5367e947 authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

Repartitioning for higher order elements works now.

parent 865377f4
...@@ -34,12 +34,11 @@ namespace AMDiS { ...@@ -34,12 +34,11 @@ namespace AMDiS {
newCoord = NULL; newCoord = NULL;
elementData = NULL; elementData = NULL;
mark = 0; mark = 0;
dofValid = true;
if (mesh) if (mesh)
createNewDofPtrs(); createNewDofPtrs();
else else
mesh = NULL; dof = NULL;
} }
...@@ -302,6 +301,8 @@ namespace AMDiS { ...@@ -302,6 +301,8 @@ namespace AMDiS {
void Element::changeDofs1(const DOFAdmin* admin, std::vector<int>& newDofIndex, void Element::changeDofs1(const DOFAdmin* admin, std::vector<int>& newDofIndex,
int n0, int nd0, int nd, int pos) int n0, int nd0, int nd, int pos)
{ {
FUNCNAME("Element::changeDofs1()");
DegreeOfFreedom *ldof = dof[n0 + pos] + nd0; DegreeOfFreedom *ldof = dof[n0 + pos] + nd0;
for (int j = 0; j < nd; j++) { for (int j = 0; j < nd; j++) {
int k = ldof[j]; int k = ldof[j];
...@@ -396,9 +397,10 @@ namespace AMDiS { ...@@ -396,9 +397,10 @@ namespace AMDiS {
int nodes = mesh->getNumberOfNodes(); int nodes = mesh->getNumberOfNodes();
int j = 0; int j = 0;
SerUtil::serialize(out, nodes); SerUtil::serialize(out, nodes);
int dofValid = (dof != NULL ? 1 : 0);
SerUtil::serialize(out, dofValid); SerUtil::serialize(out, dofValid);
if (dofValid) { if (dof != NULL) {
for (int pos = 0; pos <= dim; pos++) { for (int pos = 0; pos <= dim; pos++) {
GeoIndex position = INDEX_OF_DIM(pos, dim); GeoIndex position = INDEX_OF_DIM(pos, dim);
int ndof = 0; int ndof = 0;
...@@ -493,10 +495,11 @@ namespace AMDiS { ...@@ -493,10 +495,11 @@ namespace AMDiS {
// read dofs // read dofs
int nodes; int nodes;
SerUtil::deserialize(in, nodes); SerUtil::deserialize(in, nodes);
int dofValid = 0;
SerUtil::deserialize(in, dofValid); SerUtil::deserialize(in, dofValid);
TEST_EXIT_DBG(nodes > 0)("Should not happen!\n"); TEST_EXIT_DBG(nodes > 0)("Should not happen!\n");
dof = new DegreeOfFreedom*[nodes]; dof = (dofValid ? new DegreeOfFreedom*[nodes] : NULL);
if (dofValid) { if (dofValid) {
for (int i = 0; i < nodes; i++) { for (int i = 0; i < nodes; i++) {
......
...@@ -119,7 +119,7 @@ namespace AMDiS { ...@@ -119,7 +119,7 @@ namespace AMDiS {
/// Returns \ref dof[i][j] which is the j-th DOF of the i-th node of Element. /// Returns \ref dof[i][j] which is the j-th DOF of the i-th node of Element.
inline DegreeOfFreedom getDof(int i, int j) const inline DegreeOfFreedom getDof(int i, int j) const
{ {
TEST_EXIT_DBG(dofValid)("DOFs are not valid in element %d!\n", index); TEST_EXIT_DBG(dof != NULL)("DOFs are not valid in element %d!\n", index);
return dof[i][j]; return dof[i][j];
} }
...@@ -127,7 +127,7 @@ namespace AMDiS { ...@@ -127,7 +127,7 @@ namespace AMDiS {
/// Returns \ref dof[i] which is a pointer to the DOFs of the i-th node. /// Returns \ref dof[i] which is a pointer to the DOFs of the i-th node.
inline const DegreeOfFreedom* getDof(int i) const inline const DegreeOfFreedom* getDof(int i) const
{ {
TEST_EXIT_DBG(dofValid)("DOFs are not valid in element %d!\n", index); TEST_EXIT_DBG(dof != NULL)("DOFs are not valid in element %d!\n", index);
return dof[i]; return dof[i];
} }
...@@ -135,7 +135,7 @@ namespace AMDiS { ...@@ -135,7 +135,7 @@ namespace AMDiS {
/// Returns a pointer to the DOFs of this Element /// Returns a pointer to the DOFs of this Element
inline const DegreeOfFreedom** getDof() const inline const DegreeOfFreedom** getDof() const
{ {
TEST_EXIT_DBG(dofValid)("DOFs are not valid in element %d!\n", index); TEST_EXIT_DBG(dof != NULL)("DOFs are not valid in element %d!\n", index);
return const_cast<const DegreeOfFreedom**>(dof); return const_cast<const DegreeOfFreedom**>(dof);
} }
...@@ -146,11 +146,6 @@ namespace AMDiS { ...@@ -146,11 +146,6 @@ namespace AMDiS {
return mesh; return mesh;
} }
inline void setDofValid(bool b)
{
dofValid = b;
}
/// Returns \ref elementData's error estimation, if Element is a leaf element /// Returns \ref elementData's error estimation, if Element is a leaf element
/// and has leaf data. /// and has leaf data.
inline double getEstimation(int row) const inline double getEstimation(int row) const
...@@ -276,6 +271,15 @@ namespace AMDiS { ...@@ -276,6 +271,15 @@ namespace AMDiS {
dof[pos] = p; dof[pos] = p;
} }
/// Delets the main DOF pointer. The caller must ensure that the DOFs are
/// either freed correctly elsewhere or that they are still used by other
/// elements.
void delDofPtr()
{
delete [] dof;
dof = NULL;
}
/// Checks whether Element is a leaf element and whether it has leaf data. /// Checks whether Element is a leaf element and whether it has leaf data.
/// If the checks don't fail, leaf data's error estimation is set to est. /// If the checks don't fail, leaf data's error estimation is set to est.
inline void setEstimation(double est, int row) inline void setEstimation(double est, int row)
...@@ -336,10 +340,8 @@ namespace AMDiS { ...@@ -336,10 +340,8 @@ namespace AMDiS {
* \{ * \{
*/ */
/** \brief /// orient the vertices of edges/faces.
* orient the vertices of edges/faces. /// Used by Estimator for the jumps => same quadrature nodes from both sides!
* Used by Estimator for the jumps => same quadrature nodes from both sides!
*/
virtual const FixVec<int,WORLD>& virtual const FixVec<int,WORLD>&
sortFaceIndices(int face, FixVec<int, WORLD> *vec) const = 0; sortFaceIndices(int face, FixVec<int, WORLD> *vec) const = 0;
...@@ -466,7 +468,8 @@ namespace AMDiS { ...@@ -466,7 +468,8 @@ namespace AMDiS {
} }
/// Coarsens Element's leaf data /// Coarsens Element's leaf data
inline void coarsenElementData(Element* child1, Element* child2, int elType = 0) inline void coarsenElementData(Element* child1, Element* child2,
int elType = 0)
{ {
ElementData *childData; ElementData *childData;
childData = child1->getElementData(); childData = child1->getElementData();
...@@ -549,10 +552,8 @@ namespace AMDiS { ...@@ -549,10 +552,8 @@ namespace AMDiS {
void changeDofs2(int n0, int nd0, int nd, int pos); void changeDofs2(int n0, int nd0, int nd, int pos);
protected: protected:
/** \brief /// Pointers to the two children of interior elements of the tree. Pointers
* Pointers to the two children of interior elements of the tree. Pointers /// to NULL for leaf elements.
* to NULL for leaf elements.
*/
Element *child[2]; Element *child[2];
/** \brief /** \brief
...@@ -595,19 +596,9 @@ namespace AMDiS { ...@@ -595,19 +596,9 @@ namespace AMDiS {
/// Pointer to Element's leaf data /// Pointer to Element's leaf data
ElementData* elementData; ElementData* elementData;
/** \brief /// This map is used for deletion of all DOFs of all elements of a mesh. Once
* Is true, if the DOF pointers are valid. In sequential computations this /// a DOF-vector (all DOFS at a node, edge, etc.) is deleted, its address is
* is always the case. In parallel computations all macro elements are stored /// added to this map to note not to delete it a second time.
* in memory though not all of them are part of the mesh (because they are owned
* by another rank). In this case, there are no valid DOFs on the element.
*/
bool dofValid;
/** \brief
* This map is used for deletion of all DOFs of all elements of a mesh. Once
* a DOF-vector (all DOFS at a node, edge, etc.) is deleted, its address is
* added to this map to note not to delete it a second time.
*/
static std::map<DegreeOfFreedom*, bool> deletedDOFs; static std::map<DegreeOfFreedom*, bool> deletedDOFs;
friend class Mesh; friend class Mesh;
......
...@@ -1158,7 +1158,8 @@ namespace AMDiS { ...@@ -1158,7 +1158,8 @@ namespace AMDiS {
/* newest vertex of child[0] and child[1] */ /* newest vertex of child[0] and child[1] */
/****************************************************************************/ /****************************************************************************/
DegreeOfFreedom cdof = el->getChild(0)->getDof(node + 2, n0); /* newest vertex is DIM */ // newest vertex is DIM
DegreeOfFreedom cdof = el->getChild(0)->getDof(node + 2, n0);
(*drv)[cdof] = (*drv)[pdof[5]]; (*drv)[cdof] = (*drv)[pdof[5]];
node = drv->getFeSpace()->getMesh()->getNode(EDGE); node = drv->getFeSpace()->getMesh()->getNode(EDGE);
......
...@@ -269,7 +269,7 @@ namespace AMDiS { ...@@ -269,7 +269,7 @@ namespace AMDiS {
} }
void Mesh::removeMacroElements(std::set<MacroElement*>& macros, void Mesh::removeMacroElements(std::set<MacroElement*>& delMacros,
vector<const FiniteElemSpace*>& feSpaces) vector<const FiniteElemSpace*>& feSpaces)
{ {
FUNCNAME("Mesh::removeMacroElement()"); FUNCNAME("Mesh::removeMacroElement()");
...@@ -319,7 +319,7 @@ namespace AMDiS { ...@@ -319,7 +319,7 @@ namespace AMDiS {
// If the current mesh macro element should not be deleted, i.e., it is not // 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 // a member of the list of macro elements to be deleted, is is inserted to
// the new macro element list. // the new macro element list.
if (macros.find(*elIter) == macros.end()) if (delMacros.find(*elIter) == delMacros.end())
newMacroElements.push_back(*elIter); newMacroElements.push_back(*elIter);
} }
...@@ -332,8 +332,8 @@ namespace AMDiS { ...@@ -332,8 +332,8 @@ namespace AMDiS {
// === neighbours of some other macro elements. Furtheremore, delete the === // === neighbours of some other macro elements. Furtheremore, delete the ===
// === whole element hierarchie structure of the macro element. === // === whole element hierarchie structure of the macro element. ===
for (std::set<MacroElement*>::iterator macroIt = macros.begin(); for (std::set<MacroElement*>::iterator macroIt = delMacros.begin();
macroIt != macros.end(); ++macroIt) { macroIt != delMacros.end(); ++macroIt) {
// Go through all neighbours of the macro element and remove this macro // Go through all neighbours of the macro element and remove this macro
// element to be neighbour of some other macro element. // element to be neighbour of some other macro element.
...@@ -343,26 +343,24 @@ namespace AMDiS { ...@@ -343,26 +343,24 @@ namespace AMDiS {
if ((*macroIt)->getNeighbour(i)->getNeighbour(j) == *macroIt) if ((*macroIt)->getNeighbour(i)->getNeighbour(j) == *macroIt)
(*macroIt)->getNeighbour(i)->setNeighbour(j, NULL); (*macroIt)->getNeighbour(i)->setNeighbour(j, NULL);
Element *mel = (*macroIt)->getElement();
// Delete element hierarchie // Delete element hierarchie
if (!(*macroIt)->getElement()->isLeaf()) { if (!(mel->isLeaf())) {
delete (*macroIt)->getElement()->getChild(0); delete mel->getChild(0);
delete (*macroIt)->getElement()->getChild(1); delete mel->getChild(1);
(*macroIt)->getElement()->child[0] = NULL; mel->child[0] = NULL;
(*macroIt)->getElement()->child[1] = NULL; mel->child[1] = NULL;
(*macroIt)->getElement()->setElementData(elementDataPrototype->clone()); mel->setElementData(elementDataPrototype->clone());
} }
// We will delete at least some element DOFs in the next but will keep the mel->delDofPtr();
// element object still in memory. Therefore the DOF pointer must be set
// invalid.
(*macroIt)->getElement()->setDofValid(false);
} }
// === Check now all the DOFs that have no owner anymore and therefore have === // === Check now all the DOFs that have no owner anymore and therefore ===
// === to be removed. === // === have to be removed. ===
for (DofElMap::iterator dofsIt = dofsOwner.begin(); for (DofElMap::iterator dofsIt = dofsOwner.begin();
dofsIt != dofsOwner.end(); ++dofsIt) { dofsIt != dofsOwner.end(); ++dofsIt) {
...@@ -371,8 +369,8 @@ namespace AMDiS { ...@@ -371,8 +369,8 @@ namespace AMDiS {
for (std::set<MacroElement*>::iterator elIter = dofsIt->second.begin(); for (std::set<MacroElement*>::iterator elIter = dofsIt->second.begin();
elIter != dofsIt->second.end(); ++elIter) { elIter != dofsIt->second.end(); ++elIter) {
std::set<MacroElement*>::iterator mIt = macros.find(*elIter); std::set<MacroElement*>::iterator mIt = delMacros.find(*elIter);
if (mIt == macros.end()) { if (mIt == delMacros.end()) {
deleteDof = false; deleteDof = false;
break; break;
} }
...@@ -525,7 +523,8 @@ namespace AMDiS { ...@@ -525,7 +523,8 @@ namespace AMDiS {
int n = localAdmin->getNumberOfDofs(position); int n = localAdmin->getNumberOfDofs(position);
int n0 = localAdmin->getNumberOfPreDofs(position); int n0 = localAdmin->getNumberOfPreDofs(position);
TEST_EXIT_DBG(n + n0 <= ndof)("n=%d, n0=%d too large: ndof=%d\n", n, n0, ndof); TEST_EXIT_DBG(n + n0 <= ndof)
("n = %d, n0 = %d too large: ndof = %d\n", n, n0, ndof);
for (int j = 0; j < n; j++) for (int j = 0; j < n; j++)
dof[n0 + j] = const_cast<DOFAdmin*>(localAdmin)->getDOFIndex(); dof[n0 + j] = const_cast<DOFAdmin*>(localAdmin)->getDOFIndex();
...@@ -630,7 +629,6 @@ namespace AMDiS { ...@@ -630,7 +629,6 @@ namespace AMDiS {
} }
delete [] dof; delete [] dof;
dof = NULL;
} }
......
...@@ -798,10 +798,9 @@ namespace AMDiS { ...@@ -798,10 +798,9 @@ namespace AMDiS {
*/ */
DimVec<int> nDof; DimVec<int> nDof;
/** \brief /// Number of nodes on a single element where DOFs are located. Needed for
* Number of nodes on a single element where DOFs are located; needed for /// the (de-) allocation of the dof-vector on the element (\ref Element::dof).
* the (de-) allocation of the dof-vector on the element (\ref Element::dof); /// Here "node" is equivalent to the number of basis functions on the element.
*/
int nNodeEl; int nNodeEl;
/** \brief /** \brief
......
...@@ -301,9 +301,7 @@ namespace AMDiS { ...@@ -301,9 +301,7 @@ namespace AMDiS {
setDof(mesh->getNode(CENTER), mesh->getDof(CENTER)); setDof(mesh->getNode(CENTER), mesh->getDof(CENTER));
} }
/****************************************************************************/ // === Domain size ===
/* domain size */
/****************************************************************************/
WorldVector<double> x_min, x_max; WorldVector<double> x_min, x_max;
......
...@@ -271,6 +271,7 @@ namespace AMDiS { ...@@ -271,6 +271,7 @@ namespace AMDiS {
macroElementNeighbours[(*it)->getIndex()][i] = -1; macroElementNeighbours[(*it)->getIndex()][i] = -1;
macroElementNeighbours[neighIndex][(*it)->getOppVertex(i)] = -1; macroElementNeighbours[neighIndex][(*it)->getOppVertex(i)] = -1;
} }
} }
} }
...@@ -1138,11 +1139,13 @@ namespace AMDiS { ...@@ -1138,11 +1139,13 @@ namespace AMDiS {
// === Create new element weights. === // === Create new element weights. ===
elemWeights.clear(); elemWeights.clear();
TraverseStack stack; {
ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL); TraverseStack stack;
while (elInfo) { ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL);
elemWeights[elInfo->getMacroElement()->getIndex()]++; while (elInfo) {
elInfo = stack.traverseNext(elInfo); elemWeights[elInfo->getMacroElement()->getIndex()]++;
elInfo = stack.traverseNext(elInfo);
}
} }
// === Run mesh partitioner to calculate a new mesh partitioning. === // === Run mesh partitioner to calculate a new mesh partitioning. ===
...@@ -1207,11 +1210,13 @@ namespace AMDiS { ...@@ -1207,11 +1210,13 @@ namespace AMDiS {
mel->setNeighbour(i, NULL); mel->setNeighbour(i, NULL);
// Create new DOFs for the macro element. // Create new DOFs for the macro element.
mel->getElement()->createNewDofPtrs();
for (int i = 0; i < mesh->getGeo(VERTEX); i++) for (int i = 0; i < mesh->getGeo(VERTEX); i++)
mel->getElement()->setDof(i, mesh->getDof(VERTEX)); mel->getElement()->setDof(i, mesh->getDof(VERTEX));
// The macro element now has valid DOF pointers. for (int i = 0; i < mesh->getGeo(EDGE); i++)
mel->getElement()->setDofValid(true); mel->getElement()->setDof(mesh->getGeo(VERTEX) + i, mesh->getDof(EDGE));
// Push the macro element to all macro elements in mesh. // Push the macro element to all macro elements in mesh.
mesh->getMacroElements().push_back(mel); mesh->getMacroElements().push_back(mel);
...@@ -1852,7 +1857,7 @@ namespace AMDiS { ...@@ -1852,7 +1857,7 @@ namespace AMDiS {
void MeshDistributor::removeMacroElements() void MeshDistributor::removeMacroElements()
{ {
FUNCNAME("MeshDistributor::removeMacroElements()"); FUNCNAME("MeshDistributor::removeMacroElements()");
std::set<MacroElement*> macrosToRemove; std::set<MacroElement*> macrosToRemove;
for (deque<MacroElement*>::iterator it = mesh->firstMacroElement(); for (deque<MacroElement*>::iterator it = mesh->firstMacroElement();
it != mesh->endOfMacroElements(); ++it) it != mesh->endOfMacroElements(); ++it)
......
...@@ -228,9 +228,9 @@ namespace AMDiS { ...@@ -228,9 +228,9 @@ namespace AMDiS {
elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER); elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER);
while (elInfo) { while (elInfo) {
for (int i = 0; i < mesh->getGeo(VERTEX); i++) for (int i = 0; i < mesh->getNumberOfNodes(); i++)
if (mapDelDofs.count(elInfo->getElement()->getDof(i)) == 1) if (mapDelDofs.count(elInfo->getElement()->getDof(i)) == 1)
elInfo->getElement()->setDof(i, const_cast<DegreeOfFreedom*>(mapDelDofs[elInfo->getElement()->getDof(i)])); elInfo->getElement()->setDof(i, const_cast<DegreeOfFreedom*>(mapDelDofs[elInfo->getElement()->getDof(i)]));
elInfo = stack.traverseNext(elInfo); elInfo = stack.traverseNext(elInfo);
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment