From 54114ba02e944a7018b9ecf40e650fa66cd9704a Mon Sep 17 00:00:00 2001 From: Thomas Witkowski <thomas.witkowski@gmx.de> Date: Tue, 11 May 2010 07:26:07 +0000 Subject: [PATCH] Work on parallelization, merged two version. --- AMDiS/src/Mesh.cc | 22 ---- AMDiS/src/Mesh.h | 13 --- AMDiS/src/RefinementManager3d.cc | 35 +++--- AMDiS/src/Traverse.cc | 45 ++++---- AMDiS/src/Traverse.h | 14 +++ AMDiS/src/parallel/ParallelDomainBase.cc | 132 ++++++++++++++++------- AMDiS/src/parallel/ParallelDomainBase.h | 2 +- 7 files changed, 155 insertions(+), 108 deletions(-) diff --git a/AMDiS/src/Mesh.cc b/AMDiS/src/Mesh.cc index b1ba2673..37f3594a 100644 --- a/AMDiS/src/Mesh.cc +++ b/AMDiS/src/Mesh.cc @@ -645,28 +645,6 @@ namespace AMDiS { } - void Mesh::fillElInfo(ElInfo *elInfo, Element *el, Flag fillFlag) - { - FUNCNAME("Mesh::fillElInfo()"); - - TEST_EXIT_DBG(elInfo != NULL)("No valide elInfo pointer given!\n"); - TEST_EXIT_DBG(el != NULL)("No valid el pointer given!\n"); - - TraverseStack stack; - ElInfo *traverseElInfo = - stack.traverseFirst(this, -1, Mesh::CALL_EVERY_EL_PREORDER | fillFlag); - - while (traverseElInfo) { - if (traverseElInfo->getElement() == el) { - *elInfo = *traverseElInfo; - break; - } - - traverseElInfo = stack.traverseNext(traverseElInfo); - } - } - - bool Mesh::findElInfoAtPoint(const WorldVector<double>& xy, ElInfo *el_info, DimVec<double>& bary, diff --git a/AMDiS/src/Mesh.h b/AMDiS/src/Mesh.h index 2ec821a2..57369844 100644 --- a/AMDiS/src/Mesh.h +++ b/AMDiS/src/Mesh.h @@ -374,19 +374,6 @@ namespace AMDiS { /// Creates a new ElInfo dependent of \ref dim of the mesh ElInfo* createNewElInfo(); - /** \brief - * Fills an ElInfo-object with the information data for a given element. Note - * that this function is quite slow, since it has to traverse the whole mesh to - * find the element. - * - * \param[out] elInfo Must be a pointer to a valide object. The data of - * the element is stored here. - * \param[in] el Pointer to the element the function has to search for. - * \param[in] fillFlag Flags for mesh traverse. Defines the data that should - * be created for the element. - */ - void fillElInfo(ElInfo *elInfo, Element *el, Flag fillFlag); - /// Frees DOFs at the given position pointed by dof void freeDOF(DegreeOfFreedom* dof, GeoIndex position); diff --git a/AMDiS/src/RefinementManager3d.cc b/AMDiS/src/RefinementManager3d.cc index e8966900..06083e2b 100644 --- a/AMDiS/src/RefinementManager3d.cc +++ b/AMDiS/src/RefinementManager3d.cc @@ -77,22 +77,22 @@ namespace AMDiS { child[0]-> setDOF(node, - const_cast<int*>(el->getDOF(node+Tetrahedron::childEdge[el_type][0][0]))); + const_cast<int*>(el->getDOF(node + Tetrahedron::childEdge[el_type][0][0]))); child[1]-> setDOF(node, - const_cast<int*>(el->getDOF(node+Tetrahedron::childEdge[el_type][1][0]))); + const_cast<int*>(el->getDOF(node + Tetrahedron::childEdge[el_type][1][0]))); child[0]-> setDOF(node + 1, - const_cast<int*>(el->getDOF(node+Tetrahedron::childEdge[el_type][0][1]))); + const_cast<int*>(el->getDOF(node + Tetrahedron::childEdge[el_type][0][1]))); child[1]-> setDOF(node + 1, - const_cast<int*>(el->getDOF(node+Tetrahedron::childEdge[el_type][1][1]))); + const_cast<int*>(el->getDOF(node + Tetrahedron::childEdge[el_type][1][1]))); child[0]-> setDOF(node + 3, - const_cast<int*>(el->getDOF(node+Tetrahedron::childEdge[el_type][0][3]))); + const_cast<int*>(el->getDOF(node + Tetrahedron::childEdge[el_type][0][3]))); child[1]-> setDOF(node + 3, - const_cast<int*>(el->getDOF(node+Tetrahedron::childEdge[el_type][1][3]))); + const_cast<int*>(el->getDOF(node + Tetrahedron::childEdge[el_type][1][3]))); /****************************************************************************/ /* adjust pointers to the dof's in the refinement edge */ @@ -136,6 +136,7 @@ namespace AMDiS { fillPatchConnectivity(ref_list, index); } + void RefinementManager3d::fillPatchConnectivity(RCNeighbourList* ref_list, int index) { @@ -213,7 +214,7 @@ namespace AMDiS { neigh->getChild(j)->getIndex(), node1); (const_cast<Element*>(el->getChild(i)))-> - setDOF(node0, const_cast<int*>( neigh->getChild(j)->getDOF(node1))); + setDOF(node0, const_cast<int*>(neigh->getChild(j)->getDOF(node1))); } if (mesh->getNumberOfDOFs(FACE)) { node0 = mesh->getNode(FACE) + i_neigh; @@ -400,28 +401,34 @@ namespace AMDiS { int neigh_el_type = neigh_info->getType(); Tetrahedron *neigh = - dynamic_cast<Tetrahedron*>(const_cast<Element*>( neigh_info->getElement())); + dynamic_cast<Tetrahedron*>(const_cast<Element*>(neigh_info->getElement())); int vertices = mesh->getGeo(VERTEX); while (neigh != el) { for (j = 0; j < vertices; j++) - if (neigh->getDOF(j) == edge[0]) break; + if (neigh->getDOF(j) == edge[0]) + break; for (k = 0; k < vertices; k++) - if (neigh->getDOF(k) == edge[1]) break; + if (neigh->getDOF(k) == edge[1]) + break; if (j > 3 || k > 3) { for (j = 0; j < vertices; j++) - if (mesh->associated(neigh->getDOF(j, 0), edge[0][0])) break; + if (mesh->associated(neigh->getDOF(j, 0), edge[0][0])) + break; for (k = 0; k < vertices; k++) - if (mesh->associated(neigh->getDOF(k, 0), edge[1][0])) break; + if (mesh->associated(neigh->getDOF(k, 0), edge[1][0])) + break; if (j > 3 || k > 3) { for (j = 0; j < vertices; j++) - if (mesh->indirectlyAssociated(neigh->getDOF(j, 0), edge[0][0])) break; + if (mesh->indirectlyAssociated(neigh->getDOF(j, 0), edge[0][0])) + break; for (k = 0; k < vertices; k++) - if (mesh->indirectlyAssociated(neigh->getDOF(k, 0), edge[1][0])) break; + if (mesh->indirectlyAssociated(neigh->getDOF(k, 0), edge[1][0])) + break; TEST_EXIT_DBG(j < vertices && k < vertices) ("dof %d or dof %d not found on element %d with nodes (%d %d %d %d)\n", diff --git a/AMDiS/src/Traverse.cc b/AMDiS/src/Traverse.cc index c503fcdc..58eeb027 100644 --- a/AMDiS/src/Traverse.cc +++ b/AMDiS/src/Traverse.cc @@ -145,7 +145,7 @@ namespace AMDiS { el = elinfo_stack[stack_used]->getElement(); if (el == NULL || el->getFirstChild() == NULL) - return (elinfo_stack[stack_used]); + return elinfo_stack[stack_used]; } else { el = elinfo_stack[stack_used]->getElement(); @@ -173,7 +173,7 @@ namespace AMDiS { el = elinfo_stack[stack_used]->getElement(); if (el == NULL || el->getFirstChild() == NULL) - return (elinfo_stack[stack_used]); + return elinfo_stack[stack_used]; } } @@ -229,7 +229,8 @@ namespace AMDiS { if (stack_used == 0) { /* first call */ currentMacro = traverse_mesh->firstMacroElement(); traverse_mel = *currentMacro; - if (traverse_mel == NULL) return NULL; + if (traverse_mel == NULL) + return NULL; stack_used = 1; elinfo_stack[stack_used]->fillMacroInfo(traverse_mel); @@ -238,7 +239,7 @@ namespace AMDiS { if ((elinfo_stack[stack_used]->getLevel() == traverse_level) || (elinfo_stack[stack_used]->getLevel() < traverse_level && elinfo_stack[stack_used]->getElement()->isLeaf())) - return(elinfo_stack[stack_used]); + return elinfo_stack[stack_used]; } Element *el = elinfo_stack[stack_used]->getElement(); @@ -255,7 +256,7 @@ namespace AMDiS { if (stack_used < 1) { currentMacro++; if (currentMacro == traverse_mesh->endOfMacroElements()) - return(NULL); + return NULL; traverse_mel = *currentMacro; stack_used = 1; @@ -265,7 +266,7 @@ namespace AMDiS { if ((elinfo_stack[stack_used]->getLevel() == traverse_level) || (elinfo_stack[stack_used]->getLevel() < traverse_level && elinfo_stack[stack_used]->getElement()->isLeaf())) - return(elinfo_stack[stack_used]); + return elinfo_stack[stack_used]; } @@ -289,7 +290,7 @@ namespace AMDiS { if ((elinfo_stack[stack_used]->getLevel() == traverse_level) || (elinfo_stack[stack_used]->getLevel() < traverse_level && elinfo_stack[stack_used]->getElement()->isLeaf())) - return(elinfo_stack[stack_used]); + return elinfo_stack[stack_used]; return traverseMultiGridLevel(); } @@ -309,7 +310,7 @@ namespace AMDiS { elinfo_stack[stack_used]->fillMacroInfo(traverse_mel); info_stack[stack_used] = 0; - return(elinfo_stack[stack_used]); + return elinfo_stack[stack_used]; } Element *el = elinfo_stack[stack_used]->getElement(); @@ -326,14 +327,14 @@ namespace AMDiS { if (stack_used < 1) { currentMacro++; if (currentMacro == traverse_mesh->endOfMacroElements()) - return(NULL); + return NULL; traverse_mel = *currentMacro; stack_used = 1; elinfo_stack[stack_used]->fillMacroInfo(traverse_mel); info_stack[stack_used] = 0; - return(elinfo_stack[stack_used]); + return elinfo_stack[stack_used]; } @@ -354,7 +355,7 @@ namespace AMDiS { info_stack[stack_used] = 0; - return(elinfo_stack[stack_used]); + return elinfo_stack[stack_used]; } @@ -422,7 +423,7 @@ namespace AMDiS { info_stack[stack_used]++; /* postorder!!! */ - return(elinfo_stack[stack_used]); + return elinfo_stack[stack_used]; } @@ -517,7 +518,7 @@ namespace AMDiS { i = traverse_mel->getOppVertex(nb); traverse_mel = traverse_mel->getNeighbour(nb); if (traverse_mel == NULL) - return(NULL); + return NULL; if (nb < 2 && save_stack_used > 1) stack2_used = 2; /* go down one level in OLD hierarchy */ @@ -746,23 +747,22 @@ namespace AMDiS { stack_used = 1; elinfo_stack[stack_used]->fillMacroInfo(const_cast<MacroElement*>( traverse_mel)); info_stack[stack_used] = 0; - } else { /* goto other child */ stack2_used = stack_used + 1; - if (save_stack_used > stack2_used) { + if (save_stack_used > stack2_used) stack2_used++; /* go down one level in OLD hierarchy */ - } + elinfo2 = save_elinfo_stack[stack2_used]; el2 = dynamic_cast<Triangle*>(const_cast<Element*>( elinfo2->getElement())); - if (stack_used >= stack_size-1) { + if (stack_used >= stack_size - 1) enlargeTraverseStack(); - } + i = 2 - info_stack[stack_used]; - info_stack[stack_used] = i+1; - elinfo_stack[stack_used+1]->fillElInfo(i, elinfo_stack[stack_used]); + info_stack[stack_used] = i + 1; + elinfo_stack[stack_used + 1]->fillElInfo(i, elinfo_stack[stack_used]); stack_used++; nb = 1-i; } @@ -846,7 +846,7 @@ namespace AMDiS { elinfo->fillDetGrdLambda(); } - return(elinfo); + return elinfo; } @@ -854,7 +854,8 @@ namespace AMDiS { { FUNCNAME("TraverseStack::update()"); - TEST_EXIT_DBG(traverse_mesh->getDim() == 3)("update only in 3d\n"); + TEST_EXIT_DBG(traverse_mesh->getDim() == 3) + ("Update only in 3d, mesh is d = %d\n", traverse_mesh->getDim()); for (int i = stack_used; i > 0; i--) dynamic_cast<ElInfo3d*>(elinfo_stack[i])->update(); diff --git a/AMDiS/src/Traverse.h b/AMDiS/src/Traverse.h index ac26a4e0..1fc1a23f 100644 --- a/AMDiS/src/Traverse.h +++ b/AMDiS/src/Traverse.h @@ -136,6 +136,20 @@ namespace AMDiS { return stack_used; } + /// Returns the elInfo object on the top of the stack. + ElInfo* getElInfo() + { + FUNCNAME("TraverseStack::getElInfo()"); + + if (stack_used < 0) + return NULL; + + TEST_EXIT_DBG(elinfo_stack.size() > static_cast<unsigned int>(stack_used)) + ("Should not happen!\n"); + + return elinfo_stack[stack_used]; + } + private: /// Enlargement of the stack void enlargeTraverseStack(); diff --git a/AMDiS/src/parallel/ParallelDomainBase.cc b/AMDiS/src/parallel/ParallelDomainBase.cc index b630d9ea..9d614352 100644 --- a/AMDiS/src/parallel/ParallelDomainBase.cc +++ b/AMDiS/src/parallel/ParallelDomainBase.cc @@ -450,6 +450,8 @@ namespace AMDiS { if (elCode.getCode() != recvCodes[i].getCode()) { TEST_EXIT_DBG(refineManager)("Refinement manager is not set correctly!\n"); + // MSG("START WITH I = %d\n", i); + bool b = fitElementToMeshCode(recvCodes[i], boundIt->rankObj.el, boundIt->rankObj.ithObj, @@ -474,6 +476,8 @@ namespace AMDiS { { FUNCNAME("ParallelDomainBase::fitElementToMeshCode()"); + TEST_EXIT_DBG(el)("No element given!\n"); + if (code.empty()) return false; @@ -483,63 +487,106 @@ namespace AMDiS { TEST_EXIT_DBG(s1 != -1 || s2 != -1)("This should not happen!\n"); bool meshChanged = false; - ElInfo *elInfo = el->getMesh()->createNewElInfo(); - el->getMesh()->fillElInfo(elInfo, el, Mesh::FILL_NEIGH | Mesh::FILL_BOUND); if (s1 != -1 && s2 != -1) { - meshChanged = fitElementToMeshCode2(code, el, elInfo, ithSide, elType); - delete elInfo; + TraverseStack stack; + ElInfo *elInfo = + stack.traverseFirst(el->getMesh(), -1, Mesh::CALL_EVERY_EL_PREORDER | Mesh::FILL_NEIGH | Mesh::FILL_BOUND); + while (elInfo && elInfo->getElement() != el) { + elInfo = stack.traverseNext(elInfo); + } + + // MSG("------- START 0 ----------\n"); + + meshChanged = fitElementToMeshCode2(code, stack, elInfo, ithSide, elType); return meshChanged; } if (el->isLeaf()) { - if (code.getNumElements() == 1 && code.isLeafElement()) { - delete elInfo; - return false; - } + if (code.getNumElements() == 1 && code.isLeafElement()) + return false; + + ERROR_EXIT("NOT YET WORKING!\n"); + ElInfo *elInfo = el->getMesh()->createNewElInfo(); + // el->getMesh()->fillElInfo(elInfo, el, Mesh::FILL_NEIGH | Mesh::FILL_BOUND); el->setMark(1); refineManager->refineFunction(elInfo); + delete elInfo; + meshChanged = true; } - ElInfo *childElInfo = el->getMesh()->createNewElInfo(); - if (s1 != -1) { - childElInfo->fillElInfo(0, elInfo); - meshChanged |= fitElementToMeshCode2(code, el->getFirstChild(), childElInfo, - s1, el->getChildType(elType)); + // MSG("------- START 1 ----------\n"); + + TraverseStack stack; + ElInfo *elInfo = + stack.traverseFirst(el->getMesh(), -1, Mesh::CALL_EVERY_EL_PREORDER | Mesh::FILL_NEIGH | Mesh::FILL_BOUND); + + while (elInfo && elInfo->getElement() != el->getFirstChild()) { + elInfo = stack.traverseNext(elInfo); + } + + meshChanged |= fitElementToMeshCode2(code, stack, elInfo, s1, el->getChildType(elType)); } else { - childElInfo->fillElInfo(1, elInfo); - meshChanged |= fitElementToMeshCode2(code, el->getSecondChild(), childElInfo, - s2, el->getChildType(elType)); + // MSG("------- START 2 --------- %d \n", el->getIndex()); + + TraverseStack stack; + ElInfo *elInfo = + stack.traverseFirst(el->getMesh(), -1, Mesh::CALL_EVERY_EL_PREORDER | Mesh::FILL_NEIGH | Mesh::FILL_BOUND); + + while (elInfo && elInfo->getElement() != el->getSecondChild()) { + elInfo = stack.traverseNext(elInfo); + } + + meshChanged |= fitElementToMeshCode2(code, stack, elInfo, s2, el->getChildType(elType)); } - delete childElInfo; - delete elInfo; + // MSG("-------- ENDE ---------\n"); return meshChanged; } bool ParallelDomainBase::fitElementToMeshCode2(MeshStructure &code, - Element *el, - ElInfo *elInfo, + TraverseStack &stack, + ElInfo *aelInfo, int ithSide, int elType) { FUNCNAME("ParallelDomainBase::fitElementToMeshCode2()"); - if (code.isLeafElement()) - return false; + ElInfo *elInfo = stack.getElInfo(); + + // MSG("START EL WITH LEVEL = %d\n", elInfo->getLevel()); bool value = false; + if (!elInfo) + return value; + + Element *el = elInfo->getElement(); + + if (code.isLeafElement()) { + int level = elInfo->getLevel(); + + do { + elInfo = stack.traverseNext(elInfo); + } while (elInfo && elInfo->getLevel() > level); + + // MSG("RETURN CODE LEAF: %d\n", elInfo->getLevel()); + + return value; + } - TEST_EXIT_DBG(el != NULL)("This should not happen!\n"); - TEST_EXIT_DBG(elInfo != NULL)("This should not happen!\n"); + if (!elInfo) + return value; - if (el->isLeaf()) { + if (el->isLeaf()) { + // MSG("REFINE CODE NO LEAF!\n"); el->setMark(1); + refineManager->setMesh(el->getMesh()); + refineManager->setStack(&stack); refineManager->refineFunction(elInfo); value = true; } @@ -547,23 +594,36 @@ namespace AMDiS { int s1 = el->getSideOfChild(0, ithSide, elType); int s2 = el->getSideOfChild(1, ithSide, elType); - ElInfo *childElInfo = el->getMesh()->createNewElInfo(); - if (s1 != -1) { - childElInfo->fillElInfo(0, elInfo); + // MSG("STEP LEFT 1\n"); + stack.traverseNext(elInfo); code.nextElement(); - value |= fitElementToMeshCode2(code, el->getFirstChild(), childElInfo, - s1, el->getChildType(elType)); + value |= fitElementToMeshCode2(code, stack, elInfo, s1, el->getChildType(elType)); + elInfo = stack.getElInfo(); + // MSG("STEP LEFT 2\n"); + } else { + do { + elInfo = stack.traverseNext(elInfo); + } while (elInfo && elInfo->getElement() != el->getSecondChild()); + // MSG("STEP LEFT OMMIT\n"); } + TEST_EXIT_DBG(elInfo->getElement() == el->getSecondChild()) + ("This should not happen!\n"); + if (s2 != -1) { - childElInfo->fillElInfo(1, elInfo); - code.nextElement(); - value |= fitElementToMeshCode2(code, el->getSecondChild(), childElInfo, - s2, el->getChildType(elType)); - } + // MSG("STEP RIGHT 1\n"); + code.nextElement(); + value |= fitElementToMeshCode2(code, stack, elInfo, s2, el->getChildType(elType)); + // MSG("STEP RIGHT 2\n"); + } else { + int level = elInfo->getLevel(); - delete childElInfo; + do { + elInfo = stack.traverseNext(elInfo); + } while (elInfo && elInfo->getLevel() > level); + // MSG("STEP RIGHT OMMIT\n"); + } return value; } diff --git a/AMDiS/src/parallel/ParallelDomainBase.h b/AMDiS/src/parallel/ParallelDomainBase.h index 27da9e6c..11900c3d 100644 --- a/AMDiS/src/parallel/ParallelDomainBase.h +++ b/AMDiS/src/parallel/ParallelDomainBase.h @@ -299,7 +299,7 @@ namespace AMDiS { int elType); bool fitElementToMeshCode2(MeshStructure &code, - Element *el, + TraverseStack &stack, ElInfo *elInfo, int ithSide, int elType); -- GitLab