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

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

parent acfe9a60
......@@ -257,7 +257,7 @@ namespace AMDiS {
edge[0][0], edge[1][0], neigh->getIndex(), neigh->getDOF(0,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);
/****************************************************************************/
......
......@@ -231,21 +231,22 @@ namespace AMDiS {
void printInfoByDof(FiniteElemSpace *feSpace, DegreeOfFreedom dof)
{
FUNCNAME("debug::printInfoByDof()");
Element *el = getDofIndexElement(feSpace, dof);
Element *parEl = getLevel0ParentElement(feSpace->getMesh(), el);
std::cout << "[DBG] DOF-INFO: dof = " << dof
<< " elidx = " << el->getIndex()
<< " pelidx = " << parEl->getIndex() << std::endl;
MSG("[DBG] DOF-INFO: dof = %d elidx = %d pelidx = %d\n",
dof, el->getIndex(), parEl->getIndex());
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(feSpace->getMesh(), -1,
Mesh::CALL_EVERY_EL_PREORDER);
while (elInfo) {
if (elInfo->getElement()->getIndex() == parEl->getIndex())
std::cout << "[DBG] EL INFO TO " << parEl->getIndex() << ": "
<< " type = " << elInfo->getType() << std::endl;
if (elInfo->getElement()->getIndex() == parEl->getIndex()) {
MSG("[DBG] EL INFO TO %d: type = %d\n", parEl->getIndex(), elInfo->getType());
}
elInfo = stack.traverseNext(elInfo);
}
}
......@@ -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)
{
FUNCNAME("debug::dbgCreateElementMap()");
......
......@@ -135,6 +135,8 @@ namespace AMDiS {
void printElementHierarchie(Mesh *mesh, int elIndex);
int getLocalNeighbourIndex(Mesh *mesh, int elIndex, int neighIndex);
/** \brief
* Traverse a mesh and store for each element all its vertex DOFs in local sorted
* order (by values).
......
......@@ -1346,7 +1346,7 @@ namespace AMDiS {
if (!mesh->getNumberOfDOFs(EDGE) && nei->getIndex() < mel_index)
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");
......@@ -1428,7 +1428,7 @@ namespace AMDiS {
if (nei->getIndex() < mel_index)
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");
......@@ -1440,7 +1440,7 @@ namespace AMDiS {
("dof %d on element %d is already set, but not on element %d\n",
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) {
......
......@@ -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)
{
return (other.getCode() == code);
......
......@@ -114,29 +114,7 @@ namespace AMDiS {
int macroElIndex = -1);
/// Prints the mesh structure code.
void print()
{
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());
}
void print(bool resetCode = true);
/// Returns the mesh structure code.
inline const std::vector<unsigned long int>& getCode()
......
......@@ -53,7 +53,7 @@ namespace AMDiS {
stack->traverseFirst(mesh, -1,
Mesh::CALL_LEAF_EL | Mesh::FILL_NEIGH | Mesh::FILL_BOUND);
while (elInfo) {
if (elInfo->getElement()->getMark() > 0) {
if (elInfo->getElement()->getMark() > 0) {
doMoreRecursiveRefine =
doMoreRecursiveRefine || (elInfo->getElement()->getMark() > 1);
elInfo = refineFunction(elInfo);
......
This diff is collapsed.
......@@ -47,15 +47,19 @@ namespace AMDiS {
void setNewCoords();
/** \brief
* gets the elements around the refinement edge with vertices node[0] and
* node[1] ; refines those elements at this edge are not compatible
* devisible;
* dir determines the direction of the first neighbour
* get_refine_patch returns 1 if the domain's boundary is reached while
* looping around the refinement edge, otherwise 0
* Gets the elements around the refinement edge with vertices node[0] and
* node[1]. Refines those elements at this edge that are not compatible
* devisible. The function returns 1 if the domain's boundary is reached
* while looping around the refinement edge, otherwise 0.
*
* \param[in] direction Determines the direction of the first neighbour
*
*/
int getRefinePatch(ElInfo **el_info, DegreeOfFreedom *edge[2], int dir,
RCNeighbourList* refineList, int *n_neigh);
int getRefinePatch(ElInfo **el_info,
DegreeOfFreedom *edge[2],
int direction,
RCNeighbourList* refineList,
int *n_neigh);
/// Refines all elements in the patch.
DegreeOfFreedom refinePatch(DegreeOfFreedom *edge[2], RCNeighbourList* refineList,
......
......@@ -30,10 +30,10 @@ namespace AMDiS {
{1,-1},
{1,-1}};
const unsigned char Tetrahedron::edgeOfDOFs[4][4] = {{255,0,1,2},
{0,255,3,4},
{1,3,255,5},
{2,4,5,255}};
const unsigned char Tetrahedron::edgeOfDofs[4][4] = {{255, 0, 1, 2},
{0, 255, 3, 4},
{1, 3, 255, 5},
{2, 4, 5, 255}};
const int Tetrahedron::vertexOfEdge[6][2] = {{0,1},
{0,2},
......
......@@ -200,7 +200,7 @@ namespace AMDiS {
static const signed char childOrientation[3][2];
/// edgeOfDOFs[i][j]: gives the local index of edge with vertices i and j
static const unsigned char edgeOfDOFs[4][4];
static const unsigned char edgeOfDofs[4][4];
///
static const int edgeOfFace[4][3];
......
......@@ -10,6 +10,7 @@
#include "FixVec.h"
#include "Parametric.h"
#include "OpenMP.h"
#include "Debug.h"
namespace AMDiS {
......@@ -73,9 +74,9 @@ namespace AMDiS {
else if (traverse_fill_flag.isSet(Mesh::CALL_MG_LEVEL))
elinfo = traverseMultiGridLevel();
else
if (traverse_fill_flag.isSet(Mesh::CALL_EVERY_EL_PREORDER))
if (traverse_fill_flag.isSet(Mesh::CALL_EVERY_EL_PREORDER)) {
elinfo = traverseEveryElementPreorder();
else if (traverse_fill_flag.isSet(Mesh::CALL_EVERY_EL_INORDER))
} else if (traverse_fill_flag.isSet(Mesh::CALL_EVERY_EL_INORDER))
elinfo = traverseEveryElementInorder();
else if (traverse_fill_flag.isSet(Mesh::CALL_EVERY_EL_POSTORDER))
elinfo = traverseEveryElementPostorder();
......@@ -347,10 +348,13 @@ namespace AMDiS {
enlargeTraverseStack();
int fillIthChild = info_stack[stack_used];
info_stack[stack_used]++;
if (traverse_fill_flag.isSet(Mesh::CALL_REVERSE_MODE))
fillIthChild = 1 - fillIthChild;
elinfo_stack[stack_used + 1]->fillElInfo(fillIthChild, elinfo_stack[stack_used]);
stack_used++;
TEST_EXIT_DBG(stack_used < stack_size)
......@@ -453,18 +457,17 @@ namespace AMDiS {
ElInfo* TraverseStack::traverseNeighbour3d(ElInfo* elinfo_old, int neighbour)
{
FUNCNAME("TraverseStackLLtraverseNeighbour3d()");
FUNCNAME("TraverseStack::traverseNeighbour3d()");
Element *el2;
ElInfo *elinfo2;
const DegreeOfFreedom *dof;
int stack2_used;
int sav_neighbour = neighbour;
// father.neigh[coarse_nb[i][j]] == child[i-1].neigh[j]
static int coarse_nb[3][3][4] = {{{-2,-2,-2,-2}, {-1,2,3,1}, {-1,3,2,0}},
{{-2,-2,-2,-2}, {-1,2,3,1}, {-1,2,3,0}},
{{-2,-2,-2,-2}, {-1,2,3,1}, {-1,2,3,0}}};
// father.neigh[coarse_nb[i][j]] == child[i - 1].neigh[j]
static int coarse_nb[3][3][4] = {{{-2, -2, -2, -2}, {-1, 2, 3, 1}, {-1, 3, 2, 0}},
{{-2, -2, -2, -2}, {-1, 2, 3, 1}, {-1, 2, 3, 0}},
{{-2, -2, -2, -2}, {-1, 2, 3, 1}, {-1, 2, 3, 0}}};
TEST_EXIT_DBG(stack_used > 0)("no current element\n");
......@@ -479,7 +482,7 @@ namespace AMDiS {
Element *el = elinfo_stack[stack_used]->getElement();
int sav_index = el->getIndex();
/* first, goto to leaf level, if necessary... */
// First, goto to leaf level, if necessary ...
if ((traverse_fill_flag & Mesh::CALL_LEAF_EL).isAnySet()) {
if (el->getChild(0) && neighbour < 2) {
if (stack_used >= stack_size - 1)
......@@ -517,12 +520,12 @@ namespace AMDiS {
elinfo_stack[stack_used + 1]->getElement())
("Should not happen!\n");
nb = coarse_nb[typ][elIsIthChild][nb];
if (nb == -1)
break;
TEST_EXIT_DBG(nb >= 0)("invalid coarse_nb %d\n",nb);
TEST_EXIT_DBG(nb >= 0)("Invalid coarse_nb %d!\n", nb);
}
for (int i = stack_used; i <= save_stack_used; i++) {
......@@ -537,6 +540,7 @@ namespace AMDiS {
// Go to macro element neighbour.
int i = traverse_mel->getOppVertex(nb);
traverse_mel = traverse_mel->getNeighbour(nb);
if (traverse_mel == NULL)
return NULL;
......@@ -562,7 +566,7 @@ namespace AMDiS {
elinfo2 = save_elinfo_stack[stack2_used];
el2 = elinfo2->getElement();
if (stack_used >= stack_size-1)
if (stack_used >= stack_size - 1)
enlargeTraverseStack();
int i = 2 - info_stack[stack_used];
......@@ -570,7 +574,7 @@ namespace AMDiS {
int fillIthChild = i;
if (traverse_fill_flag.isSet(Mesh::CALL_REVERSE_MODE))
fillIthChild = 1 - fillIthChild;
elinfo_stack[stack_used+1]->fillElInfo(fillIthChild, elinfo_stack[stack_used]);
elinfo_stack[stack_used + 1]->fillElInfo(fillIthChild, elinfo_stack[stack_used]);
stack_used++;
info_stack[stack_used] = 0;
nb = 0;
......@@ -588,11 +592,16 @@ namespace AMDiS {
if (stack_used >= stack_size - 1)
enlargeTraverseStack();
info_stack[stack_used] = 2 - nb;
if (traverse_fill_flag.isSet(Mesh::CALL_REVERSE_MODE)) {
int t = 2 - nb;
info_stack[stack_used] = (t == 2 ? 1 : 2);
} else {
info_stack[stack_used] = 2 - nb;
}
int fillIthChild = 1 - nb;
if (traverse_fill_flag.isSet(Mesh::CALL_REVERSE_MODE))
fillIthChild = 1 - fillIthChild;
elinfo_stack[stack_used + 1]->fillElInfo(fillIthChild, elinfo_stack[stack_used]);
stack_used++;
......@@ -618,18 +627,23 @@ namespace AMDiS {
else if (traverse_mesh->associated(el->getDOF(1, 0), el2->getDOF(0, 0)))
i = 2 - save_info_stack[stack2_used];
else {
ERROR_EXIT("no common refinement edge\n");
ERROR_EXIT("No common refinement edge! %d\n", traverse_fill_flag.isSet(Mesh::CALL_REVERSE_MODE));
}
}
int testChild = i;
if (traverse_fill_flag.isSet(Mesh::CALL_REVERSE_MODE))
testChild = 1 - testChild;
if (el->getChild(0) &&
(el->getChild(i)->getDOF(1) == el->getDOF(nb) ||
traverse_mesh->associated(el->getChild(i)->getDOF(1, 0), el->getDOF(nb, 0))))
(el->getChild(testChild)->getDOF(1) == el->getDOF(nb) ||
traverse_mesh->associated(el->getChild(testChild)->getDOF(1, 0), el->getDOF(nb, 0))))
nb = 1;
else
nb = 2;
info_stack[stack_used] = i + 1;
info_stack[stack_used] = i + 1;
if (stack_used >= stack_size - 1)
enlargeTraverseStack();
......@@ -647,8 +661,9 @@ namespace AMDiS {
stack2_used++;
elinfo2 = save_elinfo_stack[stack2_used];
el2 = elinfo2->getElement();
if (save_stack_used > stack2_used) {
dof = el2->getDOF(1);
const DegreeOfFreedom *dof = el2->getDOF(1);
if (dof != el->getDOF(1) && dof != el->getDOF(2) &&
!traverse_mesh->associated(dof[0], el->getDOF(1, 0)) &&
!traverse_mesh->associated(dof[0], el->getDOF(2, 0))) {
......@@ -663,6 +678,7 @@ namespace AMDiS {
elinfo = elinfo_stack[stack_used];
el = elinfo->getElement();
break;
}
}
......@@ -706,7 +722,7 @@ namespace AMDiS {
int sav_neighbour = neighbour;
// father.neigh[coarse_nb[i][j]] == child[i-1].neigh[j]
static int coarse_nb[3][3] = {{-2,-2,-2}, {2,-1,1}, {-1,2,0}};
static int coarse_nb[3][3] = {{-2, -2, -2}, {2, -1, 1}, {-1, 2, 0}};
TEST_EXIT_DBG(stack_used > 0)("no current element");
......
......@@ -62,7 +62,7 @@ namespace AMDiS {
stack_used(0),
save_stack_used(0),
myThreadId(0),
maxThreads(1)
maxThreads(1)
{}
/// Destructor
......@@ -150,6 +150,11 @@ namespace AMDiS {
return elinfo_stack[stack_used];
}
inline Flag getTraverseFlag()
{
return traverse_fill_flag;
}
private:
/// Enlargement of the stack
void enlargeTraverseStack();
......
......@@ -551,6 +551,9 @@ namespace AMDiS {
std::map<int, MeshCodeVec> sendCodes;
for (RankToBoundMap::iterator it = allBound.begin(); it != allBound.end(); ++it) {
// MSG("HAVE %d BOUNDARIES WITH RANK %d!\n", it->second.size(), it->first);
for (std::vector<AtomicBoundary>::iterator boundIt = it->second.begin();
boundIt != it->second.end(); ++boundIt) {
MeshStructure elCode;
......@@ -568,6 +571,15 @@ namespace AMDiS {
bool meshFitTogether = true;
// if (mpiRank == 0) {
// debug::highlightElementIndexMesh(mesh, 139, "rank0_139.vtu");
// debug::highlightElementIndexMesh(mesh, 161, "rank0_161.vtu");
// debug::printElementHierarchie(mesh, 139);
// } else {
// debug::highlightElementIndexMesh(mesh, 137, "rank1_137.vtu");
// debug::highlightElementIndexMesh(mesh, 163, "rank1_163.vtu");
// }
for (RankToBoundMap::iterator it = allBound.begin(); it != allBound.end(); ++it) {
MeshCodeVec &recvCodes = stdMpi.getRecvData()[it->first];
......@@ -577,21 +589,56 @@ namespace AMDiS {
boundIt != it->second.end(); ++boundIt) {
MeshStructure elCode;
// if (i == 13)
// elCode.setDebugMode(true);
elCode.init(boundIt->rankObj);
if (elCode.getCode() != recvCodes[i].getCode()) {
TEST_EXIT_DBG(refineManager)("Refinement manager is not set correctly!\n");
/*
MSG("----------------------------------------------------------------\n");
MSG("CODE %d: MESH SUB OBJ = %d INDEX = %d ITH = %d REVERSE = %d\n",
i,
boundIt->rankObj.subObj,
boundIt->rankObj.el->getIndex(),
boundIt->rankObj.ithObj,
boundIt->rankObj.reverseMode);
MSG("RANK CODE: \n");
elCode.print();
elCode.reset();
MSG("OTHER CODE: \n");
recvCodes[i].print();
recvCodes[i].reset();
*/
bool b = fitElementToMeshCode(recvCodes[i],
boundIt->rankObj.el,
boundIt->rankObj.subObj,
boundIt->rankObj.ithObj,
boundIt->rankObj.elType,
boundIt->rankObj.reverseMode);
boundIt->neighObj.reverseMode);
// MSG("Mesh changed in bound from %d to %d: %d\n", mpiRank, it->first, b);
if (b)
meshFitTogether = false;
}
} else {
/*
MSG("----------------------------------------------------------------\n");
MSG("CODE %d is equal!\n", i);
MSG("RANK CODE: \n");
elCode.print();
elCode.reset();
MSG("OTHER CODE: \n");
recvCodes[i].print();
recvCodes[i].reset();
*/
}
i++;
}
......@@ -615,6 +662,13 @@ namespace AMDiS {
if (code.empty())
return false;
// MSG("FIT EL %d!\n", el->getIndex());
// if (mpiRank == 0) {
// debug::highlightElementIndexMesh(mesh, 139, "test.vtu");
// }
// MSG("REVERSE MODE = %d\n", reverseMode);
int s1 = el->getSubObjOfChild(0, subObj, ithObj, elType);
int s2 = el->getSubObjOfChild(1, subObj, ithObj, elType);
......@@ -629,12 +683,19 @@ namespace AMDiS {
traverseFlag |= Mesh::CALL_REVERSE_MODE;
}
// MSG("SUB-OBJ (SWAPED): %d %d\n", s1, s2);
if (s1 != -1 && s2 != -1) {
// MSG("GO TO FIT 1\n");
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(el->getMesh(), -1, traverseFlag);
while (elInfo && elInfo->getElement() != el)
elInfo = stack.traverseNext(elInfo);
TEST_EXIT_DBG(elInfo->getElement() == el)("This should not happen!\n");
// MSG("START WITH EL = %d\n", elInfo->getElement()->getIndex());
meshChanged = fitElementToMeshCode2(code, stack, subObj, ithObj, elType, reverseMode);
return meshChanged;
}
......@@ -643,6 +704,8 @@ namespace AMDiS {
if (code.getNumElements() == 1 && code.isLeafElement())
return false;
// MSG("GO TO FIT 2\n");
meshChanged = true;
TraverseStack stack;
......@@ -666,6 +729,8 @@ namespace AMDiS {
std::swap(child0, child1);
if (s1 != -1) {
// MSG("GO TO FIT 3\n");
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(el->getMesh(), -1, traverseFlag);
......@@ -676,6 +741,8 @@ namespace AMDiS {
meshChanged |=
fitElementToMeshCode2(code, stack, subObj, s1, el->getChildType(elType), reverseMode);
} else {
// MSG("GO TO FIT 4\n");
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(el->getMesh(), -1, traverseFlag);
......@@ -702,6 +769,11 @@ namespace AMDiS {
ElInfo *elInfo = stack.getElInfo();
// MSG("IN %d\n", elInfo->getElement()->getIndex());
// MeshStructure c = code;
// c.print(false);
bool value = false;
if (!elInfo)
return value;
......@@ -709,11 +781,18 @@ namespace AMDiS {
Element *el = elInfo->getElement();
if (code.isLeafElement()) {
// MSG("HERE 1\n");
int level = elInfo->getLevel();
do {
elInfo = stack.traverseNext(elInfo);
} while (elInfo && elInfo->getLevel() > level);
// if (elInfo) {
// MSG("NEXT ELEMENT IS: %d\n", elInfo->getElement()->getIndex());
// } else {
// MSG("NO NEXT ELEMENT!\n");
// }
return value;
}
......@@ -722,6 +801,10 @@ namespace AMDiS {
return value;
if (el->isLeaf()) {
// MSG("HERE 2: %d\n", el->getIndex());
// if (mpiRank == 0) {
// debug::highlightElementIndexMesh(mesh, 1592, "test_1592.vtu");
// }
el->setMark(1);
refineManager->setMesh(el->getMesh());
refineManager->setStack(&stack);
......@@ -739,22 +822,27 @@ namespace AMDiS {
}
if (s1 != -1) {
// MSG("HERE 3\n");
stack.traverseNext(elInfo);
code.nextElement();
value |= fitElementToMeshCode2(code, stack, subObj, s1, el->getChildType(elType), reverseMode);