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