Commit 9bb9b920 authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

Fixed some problems in 3D refinement with reversed mesh traversel stratagey.

parent acfe9a60
...@@ -257,7 +257,7 @@ namespace AMDiS { ...@@ -257,7 +257,7 @@ namespace AMDiS {
edge[0][0], edge[1][0], neigh->getIndex(), neigh->getDOF(0,0), edge[0][0], edge[1][0], neigh->getIndex(), neigh->getDOF(0,0),
neigh->getDOF(1,0), neigh->getDOF(2,0), neigh->getDOF(3,0)); neigh->getDOF(1,0), neigh->getDOF(2,0), neigh->getDOF(3,0));
} }
edge_no = Tetrahedron::edgeOfDOFs[j][k]; edge_no = Tetrahedron::edgeOfDofs[j][k];
coarsenList->setCoarsePatch(*n_neigh, edge_no == 0); coarsenList->setCoarsePatch(*n_neigh, edge_no == 0);
/****************************************************************************/ /****************************************************************************/
......
...@@ -231,21 +231,22 @@ namespace AMDiS { ...@@ -231,21 +231,22 @@ namespace AMDiS {
void printInfoByDof(FiniteElemSpace *feSpace, DegreeOfFreedom dof) void printInfoByDof(FiniteElemSpace *feSpace, DegreeOfFreedom dof)
{ {
FUNCNAME("debug::printInfoByDof()");
Element *el = getDofIndexElement(feSpace, dof); Element *el = getDofIndexElement(feSpace, dof);
Element *parEl = getLevel0ParentElement(feSpace->getMesh(), el); Element *parEl = getLevel0ParentElement(feSpace->getMesh(), el);
std::cout << "[DBG] DOF-INFO: dof = " << dof MSG("[DBG] DOF-INFO: dof = %d elidx = %d pelidx = %d\n",
<< " elidx = " << el->getIndex() dof, el->getIndex(), parEl->getIndex());
<< " pelidx = " << parEl->getIndex() << std::endl;
TraverseStack stack; TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(feSpace->getMesh(), -1, ElInfo *elInfo = stack.traverseFirst(feSpace->getMesh(), -1,
Mesh::CALL_EVERY_EL_PREORDER); Mesh::CALL_EVERY_EL_PREORDER);
while (elInfo) { while (elInfo) {
if (elInfo->getElement()->getIndex() == parEl->getIndex()) if (elInfo->getElement()->getIndex() == parEl->getIndex()) {
std::cout << "[DBG] EL INFO TO " << parEl->getIndex() << ": " MSG("[DBG] EL INFO TO %d: type = %d\n", parEl->getIndex(), elInfo->getType());
<< " type = " << elInfo->getType() << std::endl; }
elInfo = stack.traverseNext(elInfo); elInfo = stack.traverseNext(elInfo);
} }
} }
...@@ -470,6 +471,37 @@ namespace AMDiS { ...@@ -470,6 +471,37 @@ namespace AMDiS {
} }
int getLocalNeighbourIndex(Mesh *mesh, int elIndex, int neighIndex)
{
FUNCNAME("debug::getLocalNeighbourIndex()");
TraverseStack stack;
ElInfo *elInfo =
stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER | Mesh::FILL_NEIGH);
while (elInfo) {
if (elInfo->getElement()->getIndex() == elIndex) {
int returnValue = -1;
for (int i = 0; i <= mesh->getDim(); i++) {
if (elInfo->getNeighbour(i)) {
MSG("NEIGH %d of El-Idx %d: %d\n", i, elIndex, elInfo->getNeighbour(i)->getIndex());
} else {
MSG("NEIGH %d of El-Idx %d: %d\n", i, elIndex, -1);
}
if (elInfo->getNeighbour(i) &&
elInfo->getNeighbour(i)->getIndex() == neighIndex)
returnValue = i;
}
return returnValue;
}
elInfo = stack.traverseNext(elInfo);
}
return -2;
}
void createSortedDofs(Mesh *mesh, ElementIdxToDofs &elMap) void createSortedDofs(Mesh *mesh, ElementIdxToDofs &elMap)
{ {
FUNCNAME("debug::dbgCreateElementMap()"); FUNCNAME("debug::dbgCreateElementMap()");
......
...@@ -135,6 +135,8 @@ namespace AMDiS { ...@@ -135,6 +135,8 @@ namespace AMDiS {
void printElementHierarchie(Mesh *mesh, int elIndex); void printElementHierarchie(Mesh *mesh, int elIndex);
int getLocalNeighbourIndex(Mesh *mesh, int elIndex, int neighIndex);
/** \brief /** \brief
* Traverse a mesh and store for each element all its vertex DOFs in local sorted * Traverse a mesh and store for each element all its vertex DOFs in local sorted
* order (by values). * order (by values).
......
...@@ -1346,7 +1346,7 @@ namespace AMDiS { ...@@ -1346,7 +1346,7 @@ namespace AMDiS {
if (!mesh->getNumberOfDOFs(EDGE) && nei->getIndex() < mel_index) if (!mesh->getNumberOfDOFs(EDGE) && nei->getIndex() < mel_index)
return false; return false;
edge_no = Tetrahedron::edgeOfDOFs[j][k]; edge_no = Tetrahedron::edgeOfDofs[j][k];
TEST_EXIT(*n_neigh < max_no_list_el) TEST_EXIT(*n_neigh < max_no_list_el)
("too many neigbours for local list\n"); ("too many neigbours for local list\n");
...@@ -1428,7 +1428,7 @@ namespace AMDiS { ...@@ -1428,7 +1428,7 @@ namespace AMDiS {
if (nei->getIndex() < mel_index) if (nei->getIndex() < mel_index)
return false; return false;
edge_no = Tetrahedron::edgeOfDOFs[j][k]; edge_no = Tetrahedron::edgeOfDofs[j][k];
TEST_EXIT(*n_neigh < max_no_list_el)("too many neigbours for local list\n"); TEST_EXIT(*n_neigh < max_no_list_el)("too many neigbours for local list\n");
...@@ -1440,7 +1440,7 @@ namespace AMDiS { ...@@ -1440,7 +1440,7 @@ namespace AMDiS {
("dof %d on element %d is already set, but not on element %d\n", ("dof %d on element %d is already set, but not on element %d\n",
node + edge_no, nei->getIndex(), mel_index); node + edge_no, nei->getIndex(), mel_index);
nei->element->setDOF(node+edge_no,edge_dof); nei->element->setDOF(node+edge_no, edge_dof);
} }
if (next_el[edge_no][0] != opp_v) { if (next_el[edge_no][0] != opp_v) {
......
...@@ -308,6 +308,33 @@ namespace AMDiS { ...@@ -308,6 +308,33 @@ namespace AMDiS {
} }
void MeshStructure::print(bool resetCode)
{
FUNCNAME("MeshStructure::print()");
std::stringstream oss;
if (empty()) {
oss << "-" << std::endl;
} else {
if (resetCode)
reset();
bool cont = true;
while (cont) {
if (isLeafElement())
oss << "0";
else
oss << "1";
cont = nextElement();
}
}
MSG("Mesh structure code: %s\n", oss.str().c_str());
}
bool MeshStructure::compare(MeshStructure &other) bool MeshStructure::compare(MeshStructure &other)
{ {
return (other.getCode() == code); return (other.getCode() == code);
......
...@@ -114,29 +114,7 @@ namespace AMDiS { ...@@ -114,29 +114,7 @@ namespace AMDiS {
int macroElIndex = -1); int macroElIndex = -1);
/// Prints the mesh structure code. /// Prints the mesh structure code.
void print() void print(bool resetCode = true);
{
FUNCNAME("MeshStructure::print()");
std::stringstream oss;
if (empty()) {
oss << "-" << std::endl;
} else {
reset();
bool cont = true;
while (cont) {
if (isLeafElement())
oss << "0";
else
oss << "1";
cont = nextElement();
}
}
MSG("Mesh structure code: %s\n", oss.str().c_str());
}
/// Returns the mesh structure code. /// Returns the mesh structure code.
inline const std::vector<unsigned long int>& getCode() inline const std::vector<unsigned long int>& getCode()
......
...@@ -53,7 +53,7 @@ namespace AMDiS { ...@@ -53,7 +53,7 @@ namespace AMDiS {
stack->traverseFirst(mesh, -1, stack->traverseFirst(mesh, -1,
Mesh::CALL_LEAF_EL | Mesh::FILL_NEIGH | Mesh::FILL_BOUND); Mesh::CALL_LEAF_EL | Mesh::FILL_NEIGH | Mesh::FILL_BOUND);
while (elInfo) { while (elInfo) {
if (elInfo->getElement()->getMark() > 0) { if (elInfo->getElement()->getMark() > 0) {
doMoreRecursiveRefine = doMoreRecursiveRefine =
doMoreRecursiveRefine || (elInfo->getElement()->getMark() > 1); doMoreRecursiveRefine || (elInfo->getElement()->getMark() > 1);
elInfo = refineFunction(elInfo); elInfo = refineFunction(elInfo);
......
...@@ -146,13 +146,13 @@ namespace AMDiS { ...@@ -146,13 +146,13 @@ namespace AMDiS {
int el_type = ref_list->getType(index); int el_type = ref_list->getType(index);
int n_type = 0; int n_type = 0;
int dir, adjc, i, j, i_neigh, j_neigh; int dir, adjc, i, j, i_neigh, j_neigh;
int node0, node1, opp_v = 0; int node0, node1, oppVertex = 0;
for (dir = 0; dir < 2; dir++) { for (dir = 0; dir < 2; dir++) {
neigh = ref_list->getNeighbourElement(index, dir); neigh = ref_list->getNeighbourElement(index, dir);
if (neigh) { if (neigh) {
n_type = ref_list->getType(ref_list->getNeighbourNr(index, dir)); n_type = ref_list->getType(ref_list->getNeighbourNr(index, dir));
opp_v = ref_list->getOppVertex(index, dir); oppVertex = ref_list->getOppVertex(index, dir);
} }
if (!neigh || neigh->isLeaf()) { if (!neigh || neigh->isLeaf()) {
...@@ -199,7 +199,7 @@ namespace AMDiS { ...@@ -199,7 +199,7 @@ namespace AMDiS {
j = Tetrahedron::adjacentChild[adjc][i]; j = Tetrahedron::adjacentChild[adjc][i];
i_neigh = Tetrahedron::nChildFace[el_type][i][dir]; i_neigh = Tetrahedron::nChildFace[el_type][i][dir];
j_neigh = Tetrahedron::nChildFace[n_type][j][opp_v - 2]; j_neigh = Tetrahedron::nChildFace[n_type][j][oppVertex - 2];
/****************************************************************************/ /****************************************************************************/
/* adjust dof pointer in the edge in the common face of el and neigh and */ /* adjust dof pointer in the edge in the common face of el and neigh and */
...@@ -208,7 +208,7 @@ namespace AMDiS { ...@@ -208,7 +208,7 @@ namespace AMDiS {
if (mesh->getNumberOfDOFs(EDGE)) { if (mesh->getNumberOfDOFs(EDGE)) {
node0 = mesh->getNode(EDGE) + Tetrahedron::nChildEdge[el_type][i][dir]; node0 = mesh->getNode(EDGE) + Tetrahedron::nChildEdge[el_type][i][dir];
node1 = mesh->getNode(EDGE) + Tetrahedron::nChildEdge[n_type][j][opp_v - 2]; node1 = mesh->getNode(EDGE) + Tetrahedron::nChildEdge[n_type][j][oppVertex - 2];
TEST_EXIT_DBG(neigh->getChild(j)->getDOF(node1)) TEST_EXIT_DBG(neigh->getChild(j)->getDOF(node1))
("no dof on neighbour %d at node %d\n", ("no dof on neighbour %d at node %d\n",
...@@ -267,9 +267,8 @@ namespace AMDiS { ...@@ -267,9 +267,8 @@ namespace AMDiS {
edge[i] = const_cast<int*>(el_info->getElement()->getDOF(i)); edge[i] = const_cast<int*>(el_info->getElement()->getDOF(i));
if (getRefinePatch(&elinfo, edge, 0, refList, &n_neigh)) { if (getRefinePatch(&elinfo, edge, 0, refList, &n_neigh)) {
/****************************************************************************/ // Domain's boundary was reached while looping around the refinement edge.
/* domain's boundary was reached while looping around the refinement edge */
/****************************************************************************/
getRefinePatch(&elinfo, edge, 1, refList, &n_neigh); getRefinePatch(&elinfo, edge, 1, refList, &n_neigh);
} }
...@@ -383,173 +382,209 @@ namespace AMDiS { ...@@ -383,173 +382,209 @@ namespace AMDiS {
int RefinementManager3d::getRefinePatch(ElInfo **el_info, int RefinementManager3d::getRefinePatch(ElInfo **el_info,
DegreeOfFreedom *edge[2], DegreeOfFreedom *edge[2],
int dir, int direction,
RCNeighbourList* refineList, RCNeighbourList* refineList,
int *n_neigh) int *n_neigh)
{ {
FUNCNAME("RefinementManager3d::getRefinePatch()"); FUNCNAME("RefinementManager3d::getRefinePatch()");
int i, j, k; int localNeighbour = 3 - direction;
Tetrahedron *el = Tetrahedron *el =
dynamic_cast<Tetrahedron*>(const_cast<Element*>((*el_info)->getElement())); dynamic_cast<Tetrahedron*>(const_cast<Element*>((*el_info)->getElement()));
if ((*el_info)->getNeighbour(3 - dir) == NULL) if ((*el_info)->getNeighbour(localNeighbour) == NULL)
return 1; return 1;
int opp_v = (*el_info)->getOppVertex(3-dir); int oppVertex = (*el_info)->getOppVertex(localNeighbour);
ElInfo *neigh_info = stack->traverseNeighbour3d((*el_info), 3 - dir); int testIndex = (*el_info)->getNeighbour(localNeighbour)->getIndex();
int neigh_el_type = neigh_info->getType(); ElInfo *neighInfo = stack->traverseNeighbour3d((*el_info), localNeighbour);
int neighElType = neighInfo->getType();
TEST_EXIT_DBG(neighInfo->getElement()->getIndex() == testIndex)
("Should not happen!\n");
Tetrahedron *neigh = Tetrahedron *neigh =
dynamic_cast<Tetrahedron*>(const_cast<Element*>(neigh_info->getElement())); dynamic_cast<Tetrahedron*>(const_cast<Element*>(neighInfo->getElement()));
int vertices = mesh->getGeo(VERTEX); int vertices = mesh->getGeo(VERTEX);
while (neigh != el) { while (neigh != el) {
for (j = 0; j < vertices; j++) // === Determine the common edge of the element and its neighbour. ===
if (neigh->getDOF(j) == edge[0])
int edgeDof0, edgeDof1;
for (edgeDof0 = 0; edgeDof0 < vertices; edgeDof0++)
if (neigh->getDOF(edgeDof0) == edge[0])
break; break;
for (k = 0; k < vertices; k++) for (edgeDof1 = 0; edgeDof1 < vertices; edgeDof1++)
if (neigh->getDOF(k) == edge[1]) if (neigh->getDOF(edgeDof1) == edge[1])
break; break;
if (edgeDof0 > 3 || edgeDof1 > 3) {
if (j > 3 || k > 3) { for (edgeDof0 = 0; edgeDof0 < vertices; edgeDof0++)
for (j = 0; j < vertices; j++) if (mesh->associated(neigh->getDOF(edgeDof0, 0), edge[0][0]))
if (mesh->associated(neigh->getDOF(j, 0), edge[0][0]))
break; break;
for (k = 0; k < vertices; k++) for (edgeDof1 = 0; edgeDof1 < vertices; edgeDof1++)
if (mesh->associated(neigh->getDOF(k, 0), edge[1][0])) if (mesh->associated(neigh->getDOF(edgeDof1, 0), edge[1][0]))
break; break;
if (j > 3 || k > 3) { if (edgeDof0 > 3 || edgeDof1 > 3) {
for (j = 0; j < vertices; j++) for (edgeDof0 = 0; edgeDof0 < vertices; edgeDof0++)
if (mesh->indirectlyAssociated(neigh->getDOF(j, 0), edge[0][0])) if (mesh->indirectlyAssociated(neigh->getDOF(edgeDof0, 0), edge[0][0]))
break; break;
for (k = 0; k < vertices; k++) for (edgeDof1 = 0; edgeDof1 < vertices; edgeDof1++)
if (mesh->indirectlyAssociated(neigh->getDOF(k, 0), edge[1][0])) if (mesh->indirectlyAssociated(neigh->getDOF(edgeDof1, 0), edge[1][0]))
break; break;
TEST_EXIT_DBG(j < vertices && k < vertices) TEST_EXIT_DBG(edgeDof0 < vertices && edgeDof1 < vertices)
("dof %d or dof %d not found on element %d with nodes (%d %d %d %d)\n", ("dof %d or dof %d not found on element %d with nodes (%d %d %d %d)\n",
edge[0][0], edge[1][0], neigh->getIndex(), neigh->getDOF(0,0), edge[0][0], edge[1][0], neigh->getIndex(), neigh->getDOF(0,0),
neigh->getDOF(1,0), neigh->getDOF(2,0), neigh->getDOF(3,0)); neigh->getDOF(1, 0), neigh->getDOF(2, 0), neigh->getDOF(3, 0));
} }
} }
TEST_EXIT_DBG(j < mesh->getGeo(VERTEX) && TEST_EXIT_DBG(edgeDof0 < vertices && edgeDof1 < vertices)
k < mesh->getGeo(VERTEX))
("dof %d or dof %d not found on element %d with nodes (%d %d %d %d)\n", ("dof %d or dof %d not found on element %d with nodes (%d %d %d %d)\n",
edge[0][0], edge[1][0], neigh->getIndex(), neigh->getDOF(0,0), edge[0][0], edge[1][0], neigh->getIndex(), neigh->getDOF(0, 0),
neigh->getDOF(1,0), neigh->getDOF(2,0), neigh->getDOF(3,0)); neigh->getDOF(1, 0), neigh->getDOF(2, 0), neigh->getDOF(3, 0));
int edgeNo = Tetrahedron::edgeOfDofs[edgeDof0][edgeDof1];
if (edgeNo) {
// Only 0 can be a compatible commen refinement edge. Thus, neigh has not
// a compatible refinement edge. Refine it first.
int edge_no = Tetrahedron::edgeOfDOFs[j][k];
if (edge_no) {
/****************************************************************************/
/* neigh has not a compatible refinement edge */
/****************************************************************************/
neigh->setMark(max(neigh->getMark(), 1)); neigh->setMark(max(neigh->getMark(), 1));
neigh_info = refineFunction(neigh_info);
neighInfo = refineFunction(neighInfo);
/****************************************************************************/
/* now, go to a child at the edge and determine the opposite vertex for */ // === Now, go to a child at the edge and determine the opposite vertex ===
/* this child; continue the looping around the edge with this element */ // === for this child; continue the looping around the edge with this ===
/****************************************************************************/ // === element. ===
neigh_info = stack->traverseNext(neigh_info); neighInfo = stack->traverseNext(neighInfo);
neigh_el_type = neigh_info->getType(); neighElType = neighInfo->getType();
bool reverseMode = stack->getTraverseFlag().isSet(Mesh::CALL_REVERSE_MODE);
switch (edge_no) { switch (edgeNo) {
case 1: case 1:
opp_v = opp_v == 1 ? 3 : 2; if (reverseMode) {
neighInfo = stack->traverseNext(neighInfo);
neighElType = neighInfo->getType();
}
oppVertex = (oppVertex == 1 ? 3 : 2);
break; break;
case 2: case 2:
opp_v = opp_v == 2 ? 1 : 3; if (reverseMode) {
neighInfo = stack->traverseNext(neighInfo);
neighElType = neighInfo->getType();
}
oppVertex = (oppVertex == 2 ? 1 : 3);
break; break;
case 3: case 3:
neigh_info = stack->traverseNext(neigh_info); if (!reverseMode) {
neigh_el_type = neigh_info->getType(); neighInfo = stack->traverseNext(neighInfo);
if (neigh_el_type != 1) neighElType = neighInfo->getType();
opp_v = opp_v == 0 ? 3 : 2; }
if (neighElType != 1)
oppVertex = (oppVertex == 0 ? 3 : 2);
else else
opp_v = opp_v == 0 ? 3 : 1; oppVertex = (oppVertex == 0 ? 3 : 1);
break; break;
case 4: case 4:
neigh_info = stack->traverseNext(neigh_info); if (!reverseMode) {
neigh_el_type = neigh_info->getType(); neighInfo = stack->traverseNext(neighInfo);
if (neigh_el_type != 1) neighElType = neighInfo->getType();
opp_v = opp_v == 0 ? 3 : 1; }
if (neighElType != 1)
oppVertex = (oppVertex == 0 ? 3 : 1);
else else
opp_v = opp_v == 0 ? 3 : 2; oppVertex = (oppVertex == 0 ? 3 : 2);
break; break;
case 5: case 5:
if (neigh_el_type != 1) { if (neighElType != 1) {
neigh_info = stack->traverseNext(neigh_info); if (!reverseMode) {
neigh_el_type = neigh_info->getType(); neighInfo = stack->traverseNext(neighInfo);
neighElType = neighInfo->getType();
}
} }
opp_v = 3; oppVertex = 3;
break; break;
} }
neigh = neigh =
dynamic_cast<Tetrahedron*>(const_cast<Element*>(neigh_info->getElement())); dynamic_cast<Tetrahedron*>(const_cast<Element*>(neighInfo->getElement()));
} else { } else {
/****************************************************************************/ // Neigh is compatible devisible. Put neigh to the list of patch elements
/* neigh is compatible devisible; put neigh to the list of patch elements; */ // and go to next neighbour.
/* go to next neighbour */
/****************************************************************************/
TEST_EXIT_DBG(*n_neigh < mesh->getMaxEdgeNeigh()) TEST_EXIT_DBG(*n_neigh < mesh->getMaxEdgeNeigh())
("too many neighbours %d in refine patch\n", *n_neigh); ("too many neighbours %d in refine patch\n", *n_neigh);
refineList->setElement(*n_neigh, neigh); refineList->setElement(*n_neigh, neigh);
refineList->setElType(*n_neigh, neigh_el_type); refineList->setElType(*n_neigh, neighElType);
/****************************************************************************/
/* we have to go back to the starting element via opp_v values */
/* correct information is produce by get_neigh_on_patch() */
/****************************************************************************/
refineList->setOppVertex(*n_neigh, 0, opp_v);
++*n_neigh; // We have to go back to the starting element via oppVertex values.
if (opp_v != 3) refineList->setOppVertex(*n_neigh, 0, oppVertex);
i = 3;
else
i = 2;
if (neigh_info->getNeighbour(i)) { (*n_neigh)++;
opp_v = neigh_info->getOppVertex(i);
neigh_info = stack->traverseNeighbour3d(neigh_info, i); int i = (oppVertex != 3 ? 3 : 2);
neigh_el_type = neigh_info->getType();
if (neighInfo->getNeighbour(i)) {
oppVertex = neighInfo->getOppVertex(i);
int testIndex = neighInfo->getNeighbour(i)->getIndex();