From 29fd364cfa6b6d9079372644319d96c2dacad67d Mon Sep 17 00:00:00 2001
From: Thomas Witkowski <thomas.witkowski@gmx.de>
Date: Fri, 18 Jun 2010 09:32:08 +0000
Subject: [PATCH] Fixed a serious bug for mesh coarsening in parallel code.

---
 AMDiS/libtool                            |  24 +--
 AMDiS/src/BasisFunction.h                |   3 +
 AMDiS/src/DOFMatrix.cc                   |   5 +-
 AMDiS/src/DOFVector.cc                   |  17 +-
 AMDiS/src/Debug.cc                       |  89 +++++++-
 AMDiS/src/Debug.h                        |  11 +
 AMDiS/src/ElementFileWriter.cc           |  21 +-
 AMDiS/src/Lagrange.cc                    |  17 +-
 AMDiS/src/Mesh.cc                        |   5 +-
 AMDiS/src/Mesh.h                         |   3 +
 AMDiS/src/MeshStructure.cc               |  23 ++-
 AMDiS/src/MeshStructure.h                |  30 +--
 AMDiS/src/ProblemInstat.cc               |  10 +
 AMDiS/src/ProblemVec.cc                  |  13 +-
 AMDiS/src/RefinementManager.cc           |   2 +-
 AMDiS/src/Traverse.cc                    |  23 ++-
 AMDiS/src/parallel/GlobalMatrixSolver.cc |  17 +-
 AMDiS/src/parallel/MpiHelper.cc          |   6 +
 AMDiS/src/parallel/MpiHelper.h           |   2 +
 AMDiS/src/parallel/ParallelDomainBase.cc | 248 ++++++++++++++++-------
 AMDiS/src/parallel/ParallelDomainBase.h  |  14 +-
 AMDiS/src/parallel/ParallelDomainDbg.cc  |  43 +++-
 AMDiS/src/parallel/ParallelDomainDbg.h   |   3 +
 23 files changed, 475 insertions(+), 154 deletions(-)

diff --git a/AMDiS/libtool b/AMDiS/libtool
index 076d8ba8..ae88f17c 100755
--- a/AMDiS/libtool
+++ b/AMDiS/libtool
@@ -44,7 +44,7 @@ available_tags=" CXX F77"
 
 # ### BEGIN LIBTOOL CONFIG
 
-# Libtool was configured on host p2q081:
+# Libtool was configured on host p2q084:
 
 # Shell to use when invoking shell scripts.
 SHELL="/bin/sh"
@@ -82,13 +82,13 @@ AR="ar"
 AR_FLAGS="cru"
 
 # A C compiler.
-LTCC="gcc"
+LTCC="/licsoft/libraries/openmpi/1.2.6/64bit/bin/mpicc"
 
 # LTCC compiler flags.
 LTCFLAGS="-g -O2"
 
 # A language-specific compiler.
-CC="gcc"
+CC="/licsoft/libraries/openmpi/1.2.6/64bit/bin/mpicc"
 
 # Is the compiler the GNU C compiler?
 with_gcc=yes
@@ -171,7 +171,7 @@ dlopen_self=unknown
 dlopen_self_static=unknown
 
 # Compiler flag to prevent dynamic linking.
-link_static_flag="-static"
+link_static_flag=""
 
 # Compiler flag to turn off builtin functions.
 no_builtin_flag=" -fno-builtin"
@@ -6760,7 +6760,7 @@ build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac`
 # End:
 # ### BEGIN LIBTOOL TAG CONFIG: CXX
 
-# Libtool was configured on host p2q081:
+# Libtool was configured on host p2q084:
 
 # Shell to use when invoking shell scripts.
 SHELL="/bin/sh"
@@ -6798,13 +6798,13 @@ AR="ar"
 AR_FLAGS="cru"
 
 # A C compiler.
-LTCC="gcc"
+LTCC="/licsoft/libraries/openmpi/1.2.6/64bit/bin/mpicc"
 
 # LTCC compiler flags.
 LTCFLAGS="-g -O2"
 
 # A language-specific compiler.
-CC="g++"
+CC="/licsoft/libraries/openmpi/1.2.6/64bit/bin/mpiCC"
 
 # Is the compiler the GNU C compiler?
 with_gcc=yes
@@ -6887,7 +6887,7 @@ dlopen_self=unknown
 dlopen_self_static=unknown
 
 # Compiler flag to prevent dynamic linking.
-link_static_flag="-static"
+link_static_flag=""
 
 # Compiler flag to turn off builtin functions.
 no_builtin_flag=" -fno-builtin"
@@ -6954,11 +6954,11 @@ predeps=""
 
 # Dependencies to place after the objects being linked to create a
 # shared library.
-postdeps="-lstdc++ -lm -lgcc_s -lc -lgcc_s"
+postdeps="-lmpi_cxx -lmpi -lopen-rte -lopen-pal -libverbs -lrt -lnuma -ldl -lnsl -lutil -ldl -lstdc++ -lm -lgcc_s -lpthread -lc -lgcc_s"
 
 # The library search path used internally by the compiler when linking
 # a shared library.
-compiler_lib_search_path="-L/usr/lib64/gcc/x86_64-suse-linux/4.1.2 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/fastfs/wir/local/lib -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../x86_64-suse-linux/lib -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../.."
+compiler_lib_search_path="-L/usr/lib64 -L/licsoft/libraries/openmpi/1.2.6/64bit/lib -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/fastfs/wir/local/lib -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../x86_64-suse-linux/lib -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../.."
 
 # Method to check whether dependent libraries are shared objects.
 deplibs_check_method="pass_all"
@@ -7065,7 +7065,7 @@ include_expsyms=""
 
 # ### BEGIN LIBTOOL TAG CONFIG: F77
 
-# Libtool was configured on host p2q081:
+# Libtool was configured on host p2q084:
 
 # Shell to use when invoking shell scripts.
 SHELL="/bin/sh"
@@ -7103,7 +7103,7 @@ AR="ar"
 AR_FLAGS="cru"
 
 # A C compiler.
-LTCC="gcc"
+LTCC="/licsoft/libraries/openmpi/1.2.6/64bit/bin/mpicc"
 
 # LTCC compiler flags.
 LTCFLAGS="-g -O2"
diff --git a/AMDiS/src/BasisFunction.h b/AMDiS/src/BasisFunction.h
index d8038de6..e5612afb 100644
--- a/AMDiS/src/BasisFunction.h
+++ b/AMDiS/src/BasisFunction.h
@@ -41,6 +41,7 @@ namespace AMDiS {
     virtual double operator()(const DimVec<double>&) const = 0;
   };
 
+
   /// Function interface for evaluating gradients of basis functions. 
   class GrdBasFctType
   {
@@ -52,6 +53,7 @@ namespace AMDiS {
     virtual void operator()(const DimVec<double>&, DimVec<double>&) const = 0;
   };
   
+
   /// Function interface for evaluating second derivative of basis functions.
   class D2BasFctType
   {
@@ -62,6 +64,7 @@ namespace AMDiS {
 
     virtual void operator()(const DimVec<double>&, DimMat<double>&) const = 0;
   };
+
 			    
   typedef BasFctType *BFptr;
   typedef GrdBasFctType *GBFptr;
diff --git a/AMDiS/src/DOFMatrix.cc b/AMDiS/src/DOFMatrix.cc
index b8227d97..64b339ff 100644
--- a/AMDiS/src/DOFMatrix.cc
+++ b/AMDiS/src/DOFMatrix.cc
@@ -219,10 +219,7 @@ namespace AMDiS {
       } else {
 	for (int j = 0; j < nCol; j++) {
 	  DegreeOfFreedom col = colIndices[j];
-	  double entry = elMat[i][j];
-  
-	  //	  std::cout << "ADD at " << row << " " << col << std::endl;
-	  ins[row][col] += entry;
+	  ins[row][col] += elMat[i][j];
 	}
       }
     }
diff --git a/AMDiS/src/DOFVector.cc b/AMDiS/src/DOFVector.cc
index 593b8603..a1a6a2d9 100644
--- a/AMDiS/src/DOFVector.cc
+++ b/AMDiS/src/DOFVector.cc
@@ -9,6 +9,8 @@ namespace AMDiS {
   template<>
   void DOFVector<double>::coarseRestrict(RCNeighbourList& list, int n)
   {
+    FUNCNAME("DOFVector<double>::coarseRestrict()");
+
     switch (coarsenOperation) {
     case NO_OPERATION:
       return;
@@ -17,11 +19,8 @@ namespace AMDiS {
       (const_cast<BasisFunction*>(feSpace->getBasisFcts()))->coarseRestr(this, &list, n);
       break;
     case COARSE_INTERPOL:
-      if (feSpace == NULL || !feSpace)
-	ERROR_EXIT("ERR1\n");
-
-      if (feSpace->getBasisFcts() == NULL || !(feSpace->getBasisFcts()))
-	ERROR_EXIT("ERR2\n");
+      TEST_EXIT_DBG(feSpace)("Should not happen!\n");
+      TEST_EXIT_DBG(feSpace->getBasisFcts())("Shoud not happen!\n");
 
       (const_cast<BasisFunction*>(feSpace->getBasisFcts()))->coarseInter(this, &list, n);
       break;
@@ -31,12 +30,14 @@ namespace AMDiS {
     }
   }
 
+
   template<>
   void DOFVector<double>::refineInterpol(RCNeighbourList& list, int n)
   {
     (const_cast<BasisFunction*>(feSpace->getBasisFcts()))->refineInter(this, &list, n);
   }
 
+
   template<>
   void DOFVector<WorldVector<double> >::refineInterpol(RCNeighbourList& list, int n)
   {
@@ -53,6 +54,7 @@ namespace AMDiS {
     vec[dof_new] *= 0.5;
   }
 
+
   template<>
   DOFVector<WorldVector<double> >*
   DOFVector<double>::getGradient(DOFVector<WorldVector<double> > *grad) const 
@@ -138,6 +140,7 @@ namespace AMDiS {
     return result;
   }
 
+
   template<>
   DOFVector<WorldVector<double> >*
   DOFVector<double>::getRecoveryGradient(DOFVector<WorldVector<double> > *grad) const 
@@ -211,6 +214,7 @@ namespace AMDiS {
     return result;
   }
 
+
   template<>
   const WorldVector<double> *DOFVectorBase<double>::getGrdAtQPs(const ElInfo *elInfo, 
 								const Quadrature *quad,
@@ -296,6 +300,7 @@ namespace AMDiS {
     return const_cast<const WorldVector<double>*>(result);
   }
 
+
   template<>
   const WorldVector<double> *DOFVectorBase<double>::getGrdAtQPs(const ElInfo *smallElInfo,
 								const ElInfo *largeElInfo,
@@ -373,6 +378,7 @@ namespace AMDiS {
     return const_cast<const WorldVector<double>*>(result);
   }
 
+
   template<>
   const WorldMatrix<double> *DOFVectorBase<double>::getD2AtQPs(const ElInfo *elInfo, 
 							       const Quadrature *quad,
@@ -469,6 +475,7 @@ namespace AMDiS {
     return const_cast<const WorldMatrix<double>*>(result);
   }
 
+
   template<>
   void DOFVector<double>::interpol(DOFVector<double> *source, double factor) 
   {
diff --git a/AMDiS/src/Debug.cc b/AMDiS/src/Debug.cc
index 3727dfee..d7291ed4 100644
--- a/AMDiS/src/Debug.cc
+++ b/AMDiS/src/Debug.cc
@@ -6,6 +6,7 @@
 #include "MacroElement.h"
 #include "VtkWriter.h"
 #include "ElementFileWriter.h"
+#include "ElementDofIterator.h"
 
 namespace AMDiS {
 
@@ -165,6 +166,57 @@ namespace AMDiS {
       return NULL;
     }
 
+
+    Element* getParentElement(Mesh *mesh, Element *el)
+    {
+      TraverseStack stack;
+      ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER);
+      while (elInfo) {
+	if (elInfo->getElement()->getChild(0) == el || 
+	    elInfo->getElement()->getChild(1) == el)
+	  return elInfo->getElement();      
+	
+	elInfo = stack.traverseNext(elInfo);
+      }
+      
+      return NULL;
+
+    }
+
+
+    Element* getParentElement(Mesh *mesh, int elIndex)
+    {
+      TraverseStack stack;
+      ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER);
+      while (elInfo) {
+	if (elInfo->getElement()->isLeaf() == false) 
+	  if (elInfo->getElement()->getChild(0)->getIndex() == elIndex || 
+	      elInfo->getElement()->getChild(1)->getIndex() == elIndex)
+	    return elInfo->getElement();
+	
+	elInfo = stack.traverseNext(elInfo);
+      }
+      
+      return NULL;
+
+    }
+
+
+    void printElementInfo(Element *el)
+    {
+      FUNCNAME("printElementInfo()");
+      
+      if (el->isLeaf()) {
+	MSG("el %d is leaf!\n", el->getIndex());
+      } else {
+	MSG("el child0 %d    child1 %d\n", 
+	    el->getChild(0)->getIndex(),
+	    el->getChild(1)->getIndex());
+	printElementInfo(el->getChild(0));
+	printElementInfo(el->getChild(1));
+      }
+    }
+
     
     void printInfoByDof(FiniteElemSpace *feSpace, DegreeOfFreedom dof)
     {
@@ -181,7 +233,7 @@ namespace AMDiS {
       while (elInfo) {
 	if (elInfo->getElement()->getIndex() == parEl->getIndex())
 	  std::cout << "[DBG] EL INFO TO " << parEl->getIndex() << ": " 
-		    << " tzpe = " << elInfo->getType() << std::endl;
+		    << " type = " << elInfo->getType() << std::endl;
 	
 	elInfo = stack.traverseNext(elInfo);
       }	  
@@ -230,6 +282,41 @@ namespace AMDiS {
     }
 
 
+    void printAllDofCoords(FiniteElemSpace *feSpace)
+    {
+      FUNCNAME("printAllDofCoords()");
+
+      TraverseStack stack;
+      ElInfo *elInfo = stack.traverseFirst(feSpace->getMesh(), -1, 
+					   Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
+      while (elInfo) {
+	Element *el = elInfo->getElement();
+	for (int i = 0; i <= feSpace->getMesh()->getDim(); i++) {
+	  MSG("Coords for DOF %d = %f %f\n", 
+	      *(el->getDOF(i)), (elInfo->getCoord(i))[0], (elInfo->getCoord(i))[1]);
+	}
+	elInfo = stack.traverseNext(elInfo);
+      }      
+    }
+
+
+    void getAllDofs(FiniteElemSpace *feSpace, std::set<const DegreeOfFreedom*>& dofs)
+    {
+      FUNCNAME("getAllDofs()");
+
+      ElementDofIterator elDofIter(feSpace);
+      TraverseStack stack;
+      ElInfo *elInfo = stack.traverseFirst(feSpace->getMesh(), -1, Mesh::CALL_LEAF_EL);
+      while (elInfo) {	
+	elDofIter.reset(elInfo->getElement());
+	do {
+	  dofs.insert(elDofIter.getDofPtr());
+	} while (elDofIter.next());
+	elInfo = stack.traverseNext(elInfo);
+      }      
+    }
+
+
     void writeMatlabMatrix(DOFMatrix &mat, std::string filename)
     {
       using mtl::tag::major; using mtl::tag::nz; using mtl::begin; using mtl::end;
diff --git a/AMDiS/src/Debug.h b/AMDiS/src/Debug.h
index 8c502e30..0c724cd2 100644
--- a/AMDiS/src/Debug.h
+++ b/AMDiS/src/Debug.h
@@ -22,6 +22,7 @@
 #ifndef AMDIS_DEBUG_H
 #define AMDIS_DEBUG_H
 
+#include <set>
 #include "AMDiS_fwd.h"
 #include "Global.h"
 
@@ -85,11 +86,21 @@ namespace AMDiS {
     Element* getDofIndexElement(FiniteElemSpace *feSpace, DegreeOfFreedom dof);
     
     Element* getLevel0ParentElement(Mesh *mesh, Element *el);
+
+    Element* getParentElement(Mesh *mesh, Element *el);
+
+    Element* getParentElement(Mesh *mesh, int elIndex);
+
+    void printElementInfo(Element *el);
     
     void printInfoByDof(FiniteElemSpace *feSpace, DegreeOfFreedom dof);
 
     void printMatValuesStatistics(Matrix<DOFMatrix*> *mat);
 
+    void printAllDofCoords(FiniteElemSpace *feSpace);
+
+    void getAllDofs(FiniteElemSpace *feSpace, std::set<const DegreeOfFreedom*>& dofs);
+
     /** \brief
      * Creates a text file storing the value of a sparse matrix. Each line of the file
      * has three columns:
diff --git a/AMDiS/src/ElementFileWriter.cc b/AMDiS/src/ElementFileWriter.cc
index f312cc96..188840cc 100644
--- a/AMDiS/src/ElementFileWriter.cc
+++ b/AMDiS/src/ElementFileWriter.cc
@@ -280,6 +280,7 @@ namespace AMDiS {
     fout.close();
   }
 
+
   void ElementFileWriter::writeVtkValues(std::string filename)
   {
     FUNCNAME("ElementFileWriter::writeVtkValues()");
@@ -291,7 +292,6 @@ namespace AMDiS {
     int dimOfWorld = Global::getGeo(WORLD);
     int vertices = mesh->getGeo(VERTEX);
     int nElements = mesh->getNumberOfLeaves();
-    double val;
 
     fout << "<?xml version=\"1.0\"?>" << std::endl;
     fout << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">" << std::endl;
@@ -304,10 +304,8 @@ namespace AMDiS {
 
     // === Write vertex coordinates (every vertex for every element). ===
     TraverseStack stack;
-
-    ElInfo *elInfo = stack.traverseFirst(mesh,
-					 -1, 
-					 Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
+    ElInfo *elInfo = 
+      stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
 
     while (elInfo) {
       // Write coordinates of all element vertices.
@@ -369,18 +367,19 @@ namespace AMDiS {
 
     fout.setf(std::ios::scientific,std::ios::floatfield);
 
-    elInfo = stack.traverseFirst(mesh,
-				 -1, 
-				 Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
+    elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
     int vc = 0;
     while (elInfo) {
       // Get element value.
-      val = vec[elInfo->getElement()->getIndex()];
+      double val = vec[elInfo->getElement()->getIndex()];
+      if (vc == 1101) {
+	MSG("FOUND EL %d\n", elInfo->getElement()->getIndex());
+      }
    
       // Write value for each vertex of each element.
-      for (int i = 0; i <= dim; i++) {      
+      for (int i = 0; i <= dim; i++) 
 	fout << (fabs(val) < 1e-40 ? 0.0 : val) << "\n";
-      }
+      
       vc++;
       elInfo = stack.traverseNext(elInfo);
     } 
diff --git a/AMDiS/src/Lagrange.cc b/AMDiS/src/Lagrange.cc
index 79415e2e..a57bed36 100644
--- a/AMDiS/src/Lagrange.cc
+++ b/AMDiS/src/Lagrange.cc
@@ -4217,15 +4217,15 @@ namespace AMDiS {
     }
   }
 
-  // ====== coarseInter functions ======
 
   void Lagrange::coarseInter0(DOFIndexed<double> *drv, RCNeighbourList* list, 
 			      int n, BasisFunction* basFct)
   {
     FUNCNAME("Lagrange::coarseInter0()");
 
-    TEST_EXIT(drv->getFeSpace())("No fe_space in dof_real_vec!\n");
-    TEST_EXIT(drv->getFeSpace()->getBasisFcts())("No basis functions in fe_space!\n");
+    TEST_EXIT_DBG(drv->getFeSpace())("No fe_space in dof_real_vec!\n");
+    TEST_EXIT_DBG(drv->getFeSpace()->getBasisFcts())
+      ("No basis functions in fe_space!\n");
 
     if (n < 1) 
       return;
@@ -4241,13 +4241,15 @@ namespace AMDiS {
     (*drv)[pdof] = (*drv)[cdof];
   }
 
+
   void Lagrange::coarseInter2_1d(DOFIndexed<double> *drv, RCNeighbourList *list, 
 				 int n, BasisFunction* basFct)
   {
-    FUNCNAME("real_coarseInter2()");
+    FUNCNAME("Lagrange::coarseInter2_1d()");
 
-    TEST_EXIT(drv->getFeSpace())("No fe_space in dof_real_vec!\n");
-    TEST_EXIT(drv->getFeSpace()->getBasisFcts())("No basis functions in fe_space!\n");
+    TEST_EXIT_DBG(drv->getFeSpace())("No fe_space in dof_real_vec!\n");
+    TEST_EXIT_DBG(drv->getFeSpace()->getBasisFcts())
+      ("No basis functions in fe_space!\n");
 
     if (n < 1) 
       return;
@@ -4257,12 +4259,13 @@ namespace AMDiS {
     Mesh *mesh = const_cast<Mesh*>(drv->getFeSpace()->getMesh());
 
     // values on child[0] 
-    DegreeOfFreedom cdof = el->getChild(0)->getDOF(mesh->getNode(VERTEX)+1, 
+    DegreeOfFreedom cdof = el->getChild(0)->getDOF(mesh->getNode(VERTEX) + 1, 
 						   admin->getNumberOfPreDOFs(VERTEX)); 
     DegreeOfFreedom pdof = el->getDOF(mesh->getNode(CENTER), admin->getNumberOfPreDOFs(CENTER)); 
     (*drv)[pdof] = (*drv)[cdof];
   }
 
+
   void Lagrange::coarseInter2_2d(DOFIndexed<double> *drv, RCNeighbourList* list, 
 				 int n, BasisFunction* basFct)
   {
diff --git a/AMDiS/src/Mesh.cc b/AMDiS/src/Mesh.cc
index 35612050..0d4433a1 100644
--- a/AMDiS/src/Mesh.cc
+++ b/AMDiS/src/Mesh.cc
@@ -58,11 +58,10 @@ namespace AMDiS {
   const Flag Mesh::CALL_LEAF_EL            = 0X0800L;
   const Flag Mesh::CALL_LEAF_EL_LEVEL      = 0X1000L;
   const Flag Mesh::CALL_EL_LEVEL           = 0X2000L;
-  const Flag Mesh::CALL_MG_LEVEL           = 0X4000L ; // used in mg methods 
+  const Flag Mesh::CALL_MG_LEVEL           = 0X4000L;  
+  const Flag Mesh::CALL_REVERSE_MODE       = 0X8000L;
 
 
-  // const Flag Mesh::USE_PARAMETRIC          = 0X8000L ; // used in mg methods 
-
   std::vector<DegreeOfFreedom> Mesh::dof_used;
   const int Mesh::MAX_DOF = 100;
   std::map<std::pair<DegreeOfFreedom, int>, DegreeOfFreedom*> Mesh::serializedDOFs;
diff --git a/AMDiS/src/Mesh.h b/AMDiS/src/Mesh.h
index 53578c78..b4cca8cf 100644
--- a/AMDiS/src/Mesh.h
+++ b/AMDiS/src/Mesh.h
@@ -644,6 +644,9 @@ namespace AMDiS {
     ///
     static const Flag CALL_MG_LEVEL;
 
+    /// If set, left and right children are swapped in traverse.
+    static const Flag CALL_REVERSE_MODE;
+
   protected:
     ///
     bool findElementAtPointRecursive(ElInfo *elinfo,
diff --git a/AMDiS/src/MeshStructure.cc b/AMDiS/src/MeshStructure.cc
index ecce7dea..94637989 100644
--- a/AMDiS/src/MeshStructure.cc
+++ b/AMDiS/src/MeshStructure.cc
@@ -69,6 +69,13 @@ namespace AMDiS {
     int s2 = el->getSubObjOfChild(1, bound.subObj, bound.ithObj, bound.elType);
     
     TEST_EXIT(s1 != -1 || s2 != -1)("This should not happen!\n");
+
+    if (debugMode) {
+      MSG("addAlondSide(%d, %d, %d, %d)\n",
+	  bound.elIndex, bound.ithObj, bound.elType, bound.reverseMode);
+      MSG("Element is leaf: %d\n", el->isLeaf());
+      MSG("s1 = %d    s2 = %d\n", s1, s2);
+    }
     
     if (!el->isLeaf()) {
       if (s1 == -1)
@@ -102,16 +109,24 @@ namespace AMDiS {
       int s1 = el->getSubObjOfChild(0, subObj, ithObj, elType);
       int s2 = el->getSubObjOfChild(1, subObj, ithObj, elType);
 
+      if (debugMode) {
+	MSG("Child index %d  %d\n", 
+	    el->getFirstChild()->getIndex(),
+	    el->getSecondChild()->getIndex());
+	MSG("s1 = %d    s2 = %d\n", s1, s2);
+	MSG("   \n");
+      }
+
       if (!reverseOrder) {
 	if (s1 != -1) 
-	  addAlongSide(el->getFirstChild(), subObj, s1, el->getChildType(elType), false);
+	  addAlongSide(el->getFirstChild(), subObj, s1, el->getChildType(elType), reverseOrder);
 	if (s2 != -1)
-	  addAlongSide(el->getSecondChild(), subObj, s2, el->getChildType(elType), false);
+	  addAlongSide(el->getSecondChild(), subObj, s2, el->getChildType(elType), reverseOrder);
       } else {
 	if (s2 != -1)
-	  addAlongSide(el->getSecondChild(), subObj, s2, el->getChildType(elType), false);
+	  addAlongSide(el->getSecondChild(), subObj, s2, el->getChildType(elType), reverseOrder);
 	if (s1 != -1) 
-	  addAlongSide(el->getFirstChild(), subObj, s1, el->getChildType(elType), false);
+	  addAlongSide(el->getFirstChild(), subObj, s1, el->getChildType(elType), reverseOrder);
       }
     }
   }
diff --git a/AMDiS/src/MeshStructure.h b/AMDiS/src/MeshStructure.h
index 3594b7a5..2fac234a 100644
--- a/AMDiS/src/MeshStructure.h
+++ b/AMDiS/src/MeshStructure.h
@@ -112,22 +112,24 @@ namespace AMDiS {
     {
       FUNCNAME("MeshStructure::print()");
 
+      std::stringstream oss;
+
       if (empty()) {
-	std::cout << "-" << std::endl;
-	return;
-      }	
-	
-      reset();
-      bool cont = true;
-      while (cont) {
-	if (isLeafElement())
-	  std::cout << "0";
-	else
-	  std::cout << "1";
-	
-	cont = nextElement();
+	oss << "-" << std::endl;
+      }	else {	
+	reset();
+	bool cont = true;
+	while (cont) {
+	  if (isLeafElement())
+	    oss << "0";
+	  else
+	    oss << "1";
+	  
+	  cont = nextElement();
+	}
       }
-      std::cout << std::endl;
+
+      MSG("Mesh structure code: %s\n", oss.str().c_str());
     }
 
     /// Returns the mesh structure code.
diff --git a/AMDiS/src/ProblemInstat.cc b/AMDiS/src/ProblemInstat.cc
index 1ed2ffe0..e7d6ffeb 100644
--- a/AMDiS/src/ProblemInstat.cc
+++ b/AMDiS/src/ProblemInstat.cc
@@ -94,6 +94,7 @@ namespace AMDiS {
       WARNING("no oldSolution created\n");
   }
 
+
   void ProblemInstatScal::createUhOld() 
   {
     if (oldSolution) {
@@ -115,12 +116,14 @@ namespace AMDiS {
     problemStat->writeFiles(adaptInfo, force);
   }
 
+
   void ProblemInstatVec::closeTimestep(AdaptInfo *adaptInfo) 
   {
     bool force = (adaptInfo->getTime() >= adaptInfo->getEndTime());
     problemStat->writeFiles(adaptInfo, force);
   }
 
+
   ProblemInstatVec::ProblemInstatVec(std::string sname, 
 				     ProblemVec *prob, ProblemStatBase *initialProb)
     : ProblemInstat(sname, initialProb), 
@@ -128,12 +131,14 @@ namespace AMDiS {
       oldSolution(NULL)
   {}
 
+
   ProblemInstatVec::ProblemInstatVec(std::string sname, ProblemVec &prob)
     : ProblemInstat(sname, NULL), 
       problemStat(&prob),
       oldSolution(NULL)
   {}
 
+
   ProblemInstatVec::ProblemInstatVec(std::string sname, 
 				     ProblemVec &prob, ProblemStatBase &initialProb)
     : ProblemInstat(sname, &initialProb), 
@@ -141,11 +146,13 @@ namespace AMDiS {
       oldSolution(NULL)
   {}
 
+
   ProblemInstatVec::~ProblemInstatVec()
   {
     delete oldSolution;
   }
 
+
   void ProblemInstatVec::initialize(Flag initFlag, ProblemInstat *adoptProblem,
 				    Flag adoptFlag) 
   {
@@ -173,6 +180,7 @@ namespace AMDiS {
       WARNING("no oldSolution created\n");
   }
 
+
   void ProblemInstatVec::createUhOld() 
   {
     if (oldSolution) {
@@ -193,11 +201,13 @@ namespace AMDiS {
     }
   }
 
+
   void ProblemInstatScal::initTimestep(AdaptInfo *adaptInfo) 
   {
     oldSolution->copy(*(problemStat->getSolution())); 
   }
 
+
   void ProblemInstatVec::initTimestep(AdaptInfo *adaptInfo) 
   {
     oldSolution->copy(*(problemStat->getSolution())); 
diff --git a/AMDiS/src/ProblemVec.cc b/AMDiS/src/ProblemVec.cc
index 03baff91..a8f12021 100644
--- a/AMDiS/src/ProblemVec.cc
+++ b/AMDiS/src/ProblemVec.cc
@@ -226,6 +226,7 @@ namespace AMDiS {
     doOtherStuff();
   }
 
+
   void ProblemVec::createMesh() 
   {
     FUNCNAME("ProblemVec::createMesh()");
@@ -273,6 +274,7 @@ namespace AMDiS {
     }
   }
 
+
   void ProblemVec::createFeSpace(DOFAdmin *admin)
   {
     FUNCNAME("ProblemVec::createFeSpace()");
@@ -322,6 +324,7 @@ namespace AMDiS {
     }
   }
 
+
   void ProblemVec::createMatricesAndVectors()
   {
     FUNCNAME("ProblemVec::createMatricesAndVectors()");
@@ -349,6 +352,7 @@ namespace AMDiS {
     }
   }
 
+
   void ProblemVec::createSolver()
   {
     FUNCNAME("ProblemVec::createSolver()");
@@ -424,6 +428,7 @@ namespace AMDiS {
     }
   }
 
+
   void ProblemVec::createFileWriter()
   {
     FUNCNAME("ProblemVec::createFileWriter()");
@@ -479,10 +484,12 @@ namespace AMDiS {
 #endif
   }
 
+
   void ProblemVec::doOtherStuff()
   {
   }
 
+
   void ProblemVec::solve(AdaptInfo *adaptInfo, bool fixedMatrix)
   {
     FUNCNAME("Problem::solve()");
@@ -670,7 +677,7 @@ namespace AMDiS {
       for (int j = 0; j < nComponents; j++) {
 
 	if (writeAsmInfo)
-	  std::cout << "-------" << i << " " << j << "----------------" << std::endl;
+	  MSG("--------- %d %d -------------\n", i, j);
 
 	// Only if this variable is true, the current matrix will be assembled.	
 	bool assembleMatrix = true;
@@ -750,10 +757,10 @@ namespace AMDiS {
  				 solution->getDOFVector(i),
  				 componentMeshes[i],
  				 assembleFlag);     
-    }
+    }  
 
     if (asmMatrix) {
-      solverMatrix.setMatrix(*systemMatrix);      
+      solverMatrix.setMatrix(*systemMatrix);
       createPrecon();
 
       INFO(info, 8)("fillin of assembled matrix: %d\n", nnz);
diff --git a/AMDiS/src/RefinementManager.cc b/AMDiS/src/RefinementManager.cc
index c6dd1e13..9386be79 100644
--- a/AMDiS/src/RefinementManager.cc
+++ b/AMDiS/src/RefinementManager.cc
@@ -68,7 +68,7 @@ namespace AMDiS {
     delete stack;
 
     nElements -= mesh->getNumberOfLeaves();
-   
+ 
     if (nElements != 0) {
       aMesh->incChangeIndex();
       return MESH_REFINED;
diff --git a/AMDiS/src/Traverse.cc b/AMDiS/src/Traverse.cc
index 6a48d8dd..07fb4b5a 100644
--- a/AMDiS/src/Traverse.cc
+++ b/AMDiS/src/Traverse.cc
@@ -16,6 +16,10 @@ namespace AMDiS {
   ElInfo* TraverseStack::traverseFirst(Mesh *mesh, int level, Flag fill_flag)
   {
     FUNCNAME("TraverseStack::traverseFirst()");
+    
+    TEST_EXIT_DBG(fill_flag.isSet(Mesh::CALL_REVERSE_MODE) == false ||
+		  fill_flag.isSet(Mesh::CALL_EVERY_EL_PREORDER))
+      ("Not yet implemented!\n");
 
     traverse_mesh = mesh;
     traverse_level = level;
@@ -343,13 +347,20 @@ namespace AMDiS {
     if (stack_used >= stack_size - 1) 
       enlargeTraverseStack();
 
-    int i = info_stack[stack_used];
+    int fillIthChild = info_stack[stack_used];
     info_stack[stack_used]++;
-    elinfo_stack[stack_used + 1]->fillElInfo(i, elinfo_stack[stack_used]);
+    if (traverse_fill_flag.isSet(Mesh::CALL_REVERSE_MODE)) {
+      if (fillIthChild == 0)
+	fillIthChild = 1;
+      else 
+	fillIthChild = 0;
+    }
+
+    elinfo_stack[stack_used + 1]->fillElInfo(fillIthChild, elinfo_stack[stack_used]);
     stack_used++;
 
     TEST_EXIT_DBG(stack_used < stack_size)
-      ("stack_size=%d too small, level=%d\n",
+      ("stack_size = %d too small, level = %d\n",
        stack_size, elinfo_stack[stack_used]->getLevel());
 
     info_stack[stack_used] = 0;
@@ -763,7 +774,7 @@ namespace AMDiS {
       info_stack[stack_used] = i + 1;
       elinfo_stack[stack_used + 1]->fillElInfo(i, elinfo_stack[stack_used]);
       stack_used++;
-      nb = 1-i;
+      nb = 1 - i;
     }
 
     /****************************************************************************/
@@ -780,8 +791,8 @@ namespace AMDiS {
       if (nb < 2) {   /* go down one level in hierarchy */
 	if (stack_used >= stack_size-1)
 	  enlargeTraverseStack();
-	elinfo_stack[stack_used+1]->fillElInfo(1-nb, elinfo_stack[stack_used]);
-	info_stack[stack_used] = 2-nb;
+	elinfo_stack[stack_used + 1]->fillElInfo(1 - nb, elinfo_stack[stack_used]);
+	info_stack[stack_used] = 2 - nb;
 	stack_used++;
 	nb = 2;
       }
diff --git a/AMDiS/src/parallel/GlobalMatrixSolver.cc b/AMDiS/src/parallel/GlobalMatrixSolver.cc
index 19640da4..5616bf83 100644
--- a/AMDiS/src/parallel/GlobalMatrixSolver.cc
+++ b/AMDiS/src/parallel/GlobalMatrixSolver.cc
@@ -3,6 +3,7 @@
 #include "Debug.h"
 #include "SystemVector.h"
 #include "parallel/StdMpi.h"
+#include "parallel/ParallelDomainDbg.h"
 
 #include "petscksp.h"
 
@@ -190,6 +191,8 @@ namespace AMDiS {
   void GlobalMatrixSolver::setDofVector(Vec& petscVec, DOFVector<double>* vec, 
 					int dispMult, int dispAdd)
   {
+    FUNCNAME("GlobalMatrixSolver::setDofVector()");
+
     // Traverse all used dofs in the dof vector.
     DOFVector<double>::Iterator dofIt(vec, USED_DOFS);
     for (dofIt.reset(); !dofIt.end(); ++dofIt) {
@@ -215,7 +218,7 @@ namespace AMDiS {
 	double value = *dofIt;
 	VecSetValues(petscVec, 1, &index, &value, ADD_VALUES);
       }
-    }    
+    }
   }
 
 
@@ -402,7 +405,9 @@ namespace AMDiS {
     if (!d_nnz || meshDistributor->getLastMeshChangeIndex() != lastMeshNnz) {
       if (d_nnz) {
 	delete [] d_nnz;
+	d_nnz = NULL;
 	delete [] o_nnz;
+	o_nnz = NULL;
       }
 
       createPetscNnzStructure(mat);
@@ -430,7 +435,7 @@ namespace AMDiS {
     for (int i = 0; i < nComponents; i++)
       for (int j = 0; j < nComponents; j++)
 	if ((*mat)[i][j])
-	  setDofMatrix((*mat)[i][j], nComponents, i, j);
+	  setDofMatrix((*mat)[i][j], nComponents, i, j);	
 
     INFO(info, 8)("Fill petsc matrix 2 needed %.5f seconds\n", TIME_USED(first, clock()));
 
@@ -474,12 +479,18 @@ namespace AMDiS {
     // Do not delete the solution vector, use it for the initial guess.
     //    KSPSetInitialGuessNonzero(solver, PETSC_TRUE);
 
+#if (DEBUG != 0)
+    //    ParallelDomainDbg::writeCoordsFile(*meshDistributor, "mpi-coords", "dat");
+#endif
+
 
     // === Run Petsc. ===
 
     KSPSolve(solver, petscRhsVec, petscSolVec);
 
+
     // === Transfere values from Petsc's solution vectors to the dof vectors.
+
     PetscScalar *vecPointer;
     VecGetArray(petscSolVec, &vecPointer);
 
@@ -488,7 +499,7 @@ namespace AMDiS {
       DOFVector<double> *dofvec = vec.getDOFVector(i);
       for (int j = 0; j < nRankDofs; j++)
 	(*dofvec)[meshDistributor->mapLocalToDofIndex(j)] = 
-	  vecPointer[j * nComponents + i];      
+	  vecPointer[j * nComponents + i]; 
     }
 
     VecRestoreArray(petscSolVec, &vecPointer);
diff --git a/AMDiS/src/parallel/MpiHelper.cc b/AMDiS/src/parallel/MpiHelper.cc
index b4663288..ff0d193c 100644
--- a/AMDiS/src/parallel/MpiHelper.cc
+++ b/AMDiS/src/parallel/MpiHelper.cc
@@ -11,6 +11,12 @@ namespace AMDiS {
       double valCopy = value;
       MPI::COMM_WORLD.Allreduce(&valCopy, &value, 1, MPI_DOUBLE, MPI_SUM);
     }
+
+    void globalAdd(int &value)
+    {
+      int valCopy = value;
+      MPI::COMM_WORLD.Allreduce(&valCopy, &value, 1, MPI_INT, MPI_SUM);
+    }
     
     void globalMin(double &value)
     {
diff --git a/AMDiS/src/parallel/MpiHelper.h b/AMDiS/src/parallel/MpiHelper.h
index b7e3f229..bf8557e4 100644
--- a/AMDiS/src/parallel/MpiHelper.h
+++ b/AMDiS/src/parallel/MpiHelper.h
@@ -31,6 +31,8 @@ namespace AMDiS {
   namespace mpi {
     void globalAdd(double &value);
 
+    void globalAdd(int &value);
+
     void globalMin(double &value);
 
     void globalMax(double &value);
diff --git a/AMDiS/src/parallel/ParallelDomainBase.cc b/AMDiS/src/parallel/ParallelDomainBase.cc
index 4d5a872f..a7ddc962 100644
--- a/AMDiS/src/parallel/ParallelDomainBase.cc
+++ b/AMDiS/src/parallel/ParallelDomainBase.cc
@@ -49,7 +49,8 @@ namespace AMDiS {
       nOverallDofs(0),
       rstart(0),
       deserialized(false),
-      lastMeshChangeIndex(0)
+      lastMeshChangeIndex(0),
+      macroElementStructureConsisten(false)
   {
     FUNCNAME("MeshDistributor::ParalleDomainBase()");
 
@@ -117,14 +118,18 @@ namespace AMDiS {
 
     createLocalGlobalNumbering();
 
+
     // === Remove all macro elements that are not part of the rank partition. ===
 
     removeMacroElements();
+    macroElementStructureConsisten = true;
+
 
     // === Reset all DOFAdmins of the mesh. ===
 
     updateDofAdmins();
 
+
     // === If in debug mode, make some tests. ===
 
 #if (DEBUG != 0)
@@ -137,10 +142,12 @@ namespace AMDiS {
     debug::writeMesh(feSpace, -1, "macro_mesh");   
 #endif
 
+
     // === Create periodic dof mapping, if there are periodic boundaries. ===
 
     createPeriodicMap();
 
+
     // === Global refinements. ===
 
     int globalRefinement = 0;
@@ -160,6 +167,7 @@ namespace AMDiS {
       createPeriodicMap();
     }
 
+
     /// === Set DOF rank information to all matrices and vectors. ===
 
     for (unsigned int i = 0; i < probStat.size(); i++) {
@@ -177,6 +185,7 @@ namespace AMDiS {
       }
     }
 
+
     // === Remove periodic boundary conditions in sequential problem definition. ===
 
     // Remove periodic boundaries in boundary manager on matrices and vectors.
@@ -403,6 +412,10 @@ namespace AMDiS {
   {
     FUNCNAME("MeshDistributor::checkMeshChange()");
 
+#if (DEBUG != 0)
+    debug::writeMesh(feSpace, -1, "before_check_mesh");
+#endif
+
     // === If mesh has not been changed on all ranks, return. ===
 
     int recvAllValues = 0;
@@ -460,6 +473,7 @@ namespace AMDiS {
 
     // === Because the mesh has been changed, update the DOF numbering and mappings. ===
 
+    mesh->dofCompress();
     updateLocalGlobalNumbering();
   }
 
@@ -508,7 +522,8 @@ namespace AMDiS {
 					boundIt->rankObj.el,
 					boundIt->rankObj.subObj,
 					boundIt->rankObj.ithObj, 
-					boundIt->rankObj.elType);  
+					boundIt->rankObj.elType,
+					boundIt->rankObj.reverseMode);  
 
 	  if (b)
 	    meshFitTogether = false;
@@ -523,10 +538,11 @@ namespace AMDiS {
 
 
   bool MeshDistributor::fitElementToMeshCode(MeshStructure &code, 
-						Element *el, 
-						GeoIndex subObj,
-						int ithObj, 
-						int elType)
+					     Element *el, 
+					     GeoIndex subObj,
+					     int ithObj, 
+					     int elType,
+					     bool reverseMode)
   {
     FUNCNAME("MeshDistributor::fitElementToMeshCode()");
 
@@ -541,16 +557,22 @@ namespace AMDiS {
     TEST_EXIT_DBG(s1 != -1 || s2 != -1)("This should not happen!\n");
 
     bool meshChanged = false;
+    Flag traverseFlag = 
+      Mesh::CALL_EVERY_EL_PREORDER | Mesh::FILL_NEIGH | Mesh::FILL_BOUND;
+
+    if (reverseMode) {
+      std::swap(s1, s2);
+      traverseFlag |= Mesh::CALL_REVERSE_MODE;
+    }
 
     if (s1 != -1 && s2 != -1) {
       TraverseStack stack;
-      ElInfo *elInfo = 
-	stack.traverseFirst(el->getMesh(), -1, Mesh::CALL_EVERY_EL_PREORDER | Mesh::FILL_NEIGH | Mesh::FILL_BOUND);
+      ElInfo *elInfo = stack.traverseFirst(el->getMesh(), -1, traverseFlag);
       while (elInfo && elInfo->getElement() != el) {
 	elInfo = stack.traverseNext(elInfo);
       }
 
-      meshChanged = fitElementToMeshCode2(code, stack, subObj, ithObj, elType);
+      meshChanged = fitElementToMeshCode2(code, stack, subObj, ithObj, elType, reverseMode);
       return meshChanged;
     }
 
@@ -561,8 +583,7 @@ namespace AMDiS {
       meshChanged = true;
 
       TraverseStack stack;
-      ElInfo *elInfo = 
-	stack.traverseFirst(el->getMesh(), -1, Mesh::CALL_EVERY_EL_PREORDER | Mesh::FILL_NEIGH | Mesh::FILL_BOUND);
+      ElInfo *elInfo = stack.traverseFirst(el->getMesh(), -1, traverseFlag);
 
       while (elInfo && elInfo->getElement() != el) {
 	elInfo = stack.traverseNext(elInfo);
@@ -576,28 +597,31 @@ namespace AMDiS {
       refineManager->refineFunction(elInfo);
     }
 
+    Element *child0 = el->getFirstChild();
+    Element *child1 = el->getSecondChild();
+    if (reverseMode)
+      std::swap(child0, child1);
+
     if (s1 != -1) {
       TraverseStack stack;
-      ElInfo *elInfo = 
-	stack.traverseFirst(el->getMesh(), -1, Mesh::CALL_EVERY_EL_PREORDER | Mesh::FILL_NEIGH | Mesh::FILL_BOUND);
+      ElInfo *elInfo = stack.traverseFirst(el->getMesh(), -1, traverseFlag);
 
-      while (elInfo && elInfo->getElement() != el->getFirstChild()) {
+      while (elInfo && elInfo->getElement() != child0) {
 	elInfo = stack.traverseNext(elInfo);
       }
 
       meshChanged |= 
-	fitElementToMeshCode2(code, stack, subObj, s1, el->getChildType(elType));
+	fitElementToMeshCode2(code, stack, subObj, s1, el->getChildType(elType), reverseMode);
     } else {
       TraverseStack stack;
-      ElInfo *elInfo = 
-	stack.traverseFirst(el->getMesh(), -1, Mesh::CALL_EVERY_EL_PREORDER | Mesh::FILL_NEIGH | Mesh::FILL_BOUND);
+      ElInfo *elInfo = stack.traverseFirst(el->getMesh(), -1, traverseFlag);
 
-      while (elInfo && elInfo->getElement() != el->getSecondChild()) {
+      while (elInfo && elInfo->getElement() != child1) {
 	elInfo = stack.traverseNext(elInfo);
       }
 
       meshChanged |= 
-	fitElementToMeshCode2(code, stack, subObj, s2, el->getChildType(elType));
+	fitElementToMeshCode2(code, stack, subObj, s2, el->getChildType(elType), reverseMode);
     }
 
     return meshChanged;
@@ -605,10 +629,11 @@ namespace AMDiS {
 
 
   bool MeshDistributor::fitElementToMeshCode2(MeshStructure &code, 
-						 TraverseStack &stack,
-						 GeoIndex subObj,
-						 int ithObj, 
-						 int elType)
+					      TraverseStack &stack,
+					      GeoIndex subObj,
+					      int ithObj, 
+					      int elType,
+					      bool reverseMode)
   {
     FUNCNAME("MeshDistributor::fitElementToMeshCode2()");
 
@@ -643,24 +668,29 @@ namespace AMDiS {
 
     int s1 = el->getSubObjOfChild(0, subObj, ithObj, elType);
     int s2 = el->getSubObjOfChild(1, subObj, ithObj, elType);
+    Element *child0 = el->getFirstChild();
+    Element *child1 = el->getSecondChild();
+    if (reverseMode) {
+      std::swap(s1, s2);
+      std::swap(child0, child1);
+    }
 
     if (s1 != -1) {
       stack.traverseNext(elInfo);
       code.nextElement();
-      value |= fitElementToMeshCode2(code, stack, subObj, s1, el->getChildType(elType));
+      value |= fitElementToMeshCode2(code, stack, subObj, s1, el->getChildType(elType), reverseMode);
       elInfo = stack.getElInfo();
     } else {
       do {
 	elInfo = stack.traverseNext(elInfo);
-      } while (elInfo && elInfo->getElement() != el->getSecondChild());      
+      } while (elInfo && elInfo->getElement() != child1);      
     }  
 
-    TEST_EXIT_DBG(elInfo->getElement() == el->getSecondChild())
-      ("This should not happen!\n");
+    TEST_EXIT_DBG(elInfo->getElement() == child1)("This should not happen!\n");
 
     if (s2 != -1) {
       code.nextElement();
-      value |= fitElementToMeshCode2(code, stack, subObj, s2, el->getChildType(elType));
+      value |= fitElementToMeshCode2(code, stack, subObj, s2, el->getChildType(elType), reverseMode);
     } else {
       int level = elInfo->getLevel();
 
@@ -685,7 +715,7 @@ namespace AMDiS {
 
 
   void MeshDistributor::deserialize(std::istream &in, DofContainer &data,
-				       std::map<int, const DegreeOfFreedom*> &dofMap)
+				    std::map<int, const DegreeOfFreedom*> &dofMap)
   {
     FUNCNAME("MeshDistributor::deserialize()");
 
@@ -717,7 +747,7 @@ namespace AMDiS {
 
   
   void MeshDistributor::deserialize(std::istream &in, RankToDofContainer &data,
-				       std::map<int, const DegreeOfFreedom*> &dofMap)
+				    std::map<int, const DegreeOfFreedom*> &dofMap)
   {
     int mapSize = 0;
     SerUtil::deserialize(in, mapSize);
@@ -1223,7 +1253,7 @@ namespace AMDiS {
     // === the necessary boundary objects.                                         ===
 
     for (std::map<int, std::vector<BoundaryObject> >::iterator it = recvObjs.begin();
-	it != recvObjs.end(); ++it) {
+	 it != recvObjs.end(); ++it) {
       if (it->second.size() > 0) {	
 	TEST_EXIT_DBG(it->second.size() == stdMpiObjs.getRecvData(it->first).size())
 	  ("This should not happen!\n");
@@ -1297,7 +1327,7 @@ namespace AMDiS {
 
 
     for (std::map<int, std::vector<BoundaryObject> >::iterator it = recvObjs.begin();
-	it != recvObjs.end(); ++it) {
+	 it != recvObjs.end(); ++it) {
       if (it->second.size() > 0) {	
 	TEST_EXIT_DBG(it->second.size() == stdMpiObjs.getRecvData(it->first).size())
 	  ("Should not happen!\n");
@@ -1389,7 +1419,7 @@ namespace AMDiS {
 
 
     // === Create information which dof indices must be send and which must  ===
-    // === be received.                                                      ===
+    // === be received to/from other ranks.                                  ===
 
     // Stores to each rank a map from DOF pointers (which are all owned by the rank
     // and lie on an interior boundary) to new global DOF indices.
@@ -1447,7 +1477,7 @@ namespace AMDiS {
     std::map<int, DofMapVec> &dofMap = stdMpi.getRecvData();
 
 
-    // === Change dof indices at boundary from other ranks. ===
+    // === Change global dof indices at boundary from other ranks. ===
 
     // Within this small data structure we track which dof index was already changed.
     // This is used to avoid the following situation: Assume, there are two dof indices
@@ -1463,10 +1493,10 @@ namespace AMDiS {
 	 ++dofIt)
       dofChanged[dofIt->first] = false;
 
-    for (std::map<int, std::vector<std::pair<DegreeOfFreedom, DegreeOfFreedom> > >::iterator rankIt = dofMap.begin();
+    for (std::map<int, DofMapVec>::iterator rankIt = dofMap.begin();
  	 rankIt != dofMap.end(); ++rankIt) {
       
-      for (std::vector<std::pair<DegreeOfFreedom, DegreeOfFreedom> >::iterator recvDofIt = rankIt->second.begin();
+      for (DofMapVec::iterator recvDofIt = rankIt->second.begin();
 	   recvDofIt != rankIt->second.end(); ++recvDofIt) {
 
 	DegreeOfFreedom oldDof = recvDofIt->first;
@@ -1511,7 +1541,7 @@ namespace AMDiS {
 
 #if (DEBUG != 0)
     debug::ElementIdxToDofs elMap;
-    debug::createSortedDofs(mesh, elMap);
+    debug::createSortedDofs(mesh, elMap);   
 #endif
 
     typedef std::set<const DegreeOfFreedom*> DofSet;
@@ -1530,17 +1560,25 @@ namespace AMDiS {
     TraverseStack stack;
     ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL);
     while (elInfo) {
-      Element *element = elInfo->getElement();     
-      elDofIt.reset(element);
+      elDofIt.reset(elInfo->getElement());
       do {
 	rankDofSet.insert(elDofIt.getDofPtr());
+	vertexDof[elDofIt.getDofPtr()] = false;
+      } while(elDofIt.next());
 
-	if (elDofIt.getCurrentPos() == 0) 
+      elInfo = stack.traverseNext(elInfo);
+    }
+
+    elInfo = stack.traverseFirst(mesh, 0, Mesh::CALL_EL_LEVEL);
+    while (elInfo) {
+      Element *element = elInfo->getElement();     
+      elDofIt.reset(element);
+      elDofIt.reset(elInfo->getElement());
+      do {
+ 	if (elDofIt.getCurrentPos() == 0) 
 	  vertexDof[elDofIt.getDofPtr()] = true;
-	else
-	  vertexDof[elDofIt.getDofPtr()] = false;
       } while(elDofIt.next());
-
+      
       elInfo = stack.traverseNext(elInfo);
     }
 
@@ -1566,7 +1604,7 @@ namespace AMDiS {
 	   dofIt != it->second.end(); ++dofIt)
 	if (oldVertexDof[*dofIt] && vertexDof[*dofIt])
 	  sendDofs[it->first].push_back(*dofIt);
-
+     
 
     for (RankToDofContainer::iterator it = oldRecvDofs.begin();
 	 it != oldRecvDofs.end(); ++it) {
@@ -1578,22 +1616,27 @@ namespace AMDiS {
 	  DofContainer::iterator eraseIt = 
 	    find(rankDofs.begin(), rankDofs.end(), *dofIt);
 	  if (eraseIt != rankDofs.end())
-	    rankDofs.erase(eraseIt);    
+	    rankDofs.erase(eraseIt);    	  
 	}
       }
     }
 
+
     for (InteriorBoundary::iterator it(myIntBoundary); !it.end(); ++it) {
       DofContainer dofs;	
       it->rankObj.el->getVertexDofs(feSpace, it->rankObj, dofs);
       it->rankObj.el->getNonVertexDofs(feSpace, it->rankObj, dofs);
-     
+    
       for (int i = 0; i < static_cast<int>(dofs.size()); i++) {
-	/* FOR DEBUGGING
+	// FOR DEBUGGING
+	/*
 	  WorldVector<double> cs;
 	  mesh->getDofIndexCoords(dofs[i], feSpace, cs);
 	  MSG("SEND EL %d DOF %d TO %d\n", it->rankObj.elIndex, *(dofs[i]), it.getRank());
-	  MSG("COORDS: %f %f %f\n", cs[0], cs[1], cs[2]);
+	  if (cs.getSize() == 2) 
+	  MSG("COORDS-s2: %f %f\n", cs[0], cs[1]);
+	  else
+	  MSG("COORDS-s2: %f %f %f\n", cs[0], cs[1], cs[2]);
 	*/
 
 	sendDofs[it.getRank()].push_back(dofs[i]);      
@@ -1612,17 +1655,22 @@ namespace AMDiS {
 	if (eraseIt != rankDofs.end()) 
 	  rankDofs.erase(eraseIt);	 
 
-	/* FOR DEBUGGING
-	   WorldVector<double> cs;
-	   mesh->getDofIndexCoords(dofs[i], feSpace, cs);	
-	   MSG("RECV EL %d DOF %d FROM %d\n", it->rankObj.elIndex, *(dofs[i]), it.getRank());
-	   MSG("COORDS: %f %f %f\n", cs[0], cs[1], cs[2]);
+	// FOR DEBUGGING
+	/*
+	  WorldVector<double> cs;
+	  mesh->getDofIndexCoords(dofs[i], feSpace, cs);	
+	  MSG("RECV EL %d DOF %d FROM %d\n", it->rankObj.elIndex, *(dofs[i]), it.getRank());
+	  if (cs.getSize() == 2) 
+	  MSG("COORDS-r2: %f %f\n", cs[0], cs[1]);
+	  else
+	  MSG("COORDS-r2: %f %f %f\n", cs[0], cs[1], cs[2]);
 	*/
 
 	recvDofs[it.getRank()].push_back(dofs[i]);
       }
     }
 
+
     nRankDofs = rankDofs.size();
 
     // === Get starting position for global rank dof ordering. ====
@@ -1643,7 +1691,6 @@ namespace AMDiS {
     int i = 0;
     for (DofContainer::iterator dofIt = rankAllDofs.begin();
 	 dofIt != rankAllDofs.end(); ++dofIt) {
-
       rankDofsNewLocalIndex[*dofIt] = i;
       // First, we set all dofs in ranks partition to be owend by the rank. Later,
       // the dofs in ranks partition that are owned by other rank are set to false.
@@ -1709,45 +1756,104 @@ namespace AMDiS {
     
 #if (DEBUG != 0)
     debug::testSortedDofs(mesh, elMap);
-    debug::writeMesh(feSpace, -1, "last_update_mesh");
     ParallelDomainDbg::testCommonDofs(*this, true);
+    
+#if 0
+    MSG("------------- Debug information -------------\n");
+    MSG("nRankDofs = %d\n", nRankDofs);
+    MSG("nOverallDofs = %d\n", nOverallDofs);
+    MSG("rstart %d\n", rstart);
+    for (RankToDofContainer::iterator it = sendDofs.begin(); 
+	 it != sendDofs.end(); ++it) {
+      MSG("send %d DOFs to rank %d\n", it->second.size(), it->first);
+
+      for (unsigned int i = 0; i < it->second.size(); i++)
+	MSG("%d send DOF: %d\n", i, *(it->second[i]));
+    }
+    for (RankToDofContainer::iterator it = recvDofs.begin();
+	 it != recvDofs.end(); ++it) {
+      MSG("recv %d DOFs from rank %d\n", it->second.size(), it->first);
+
+      for (unsigned int i = 0; i < it->second.size(); i++)
+	MSG("%d recv DOF: %d\n", i, *(it->second[i]));
+    }
+
+    std::set<const DegreeOfFreedom*> testDofs;
+    debug::getAllDofs(feSpace, testDofs);
+    for (std::set<const DegreeOfFreedom*>::iterator it = testDofs.begin();
+	 it != testDofs.end(); ++it) {
+      MSG("DOF %d:   mapLocalGlobalDofs = %d   vertexDof = %d    isRankDof = %d\n", **it, 
+	  mapLocalGlobalDofs[**it], 
+	  vertexDof[*it],
+	  isRankDof[**it]);
+    }
+    MSG("\n");
+    for (DofMapping::iterator it = mapLocalDofIndex.begin(); 
+	 it != mapLocalDofIndex.end(); ++it) {
+      MSG("mapLocalDofIndex[%d] = %d\n", it->first, it->second);
+    }
+#endif
 #endif
   }
 
 
   void MeshDistributor::createLocalMappings(DofIndexMap &rankDofsNewLocalIndex,
-					       DofIndexMap &rankOwnedDofsNewLocalIndex,
-					       DofIndexMap &rankDofsNewGlobalIndex)
+					    DofIndexMap &rankOwnedDofsNewLocalIndex,
+					    DofIndexMap &rankDofsNewGlobalIndex)
   {
+    FUNCNAME("MeshDistributor::createLocalMappings()");
+
+#if (DEBUG != 0)
+    if (macroElementStructureConsisten) {
+      std::set<const DegreeOfFreedom*> allDofs;
+      debug::getAllDofs(feSpace, allDofs);
+      
+      for (std::set<const DegreeOfFreedom*>::iterator it = allDofs.begin();
+	   it != allDofs.end(); ++it) {
+	TEST_EXIT(rankDofsNewLocalIndex.count(*it) == 1)
+	  ("Missing DOF %d in rankDofsNewLocalIndex!\n", **it);
+	
+	TEST_EXIT(rankDofsNewGlobalIndex.count(*it) == 1)
+	  ("Missing DOF %d in rankDofsNewGlobalIndex!\n", **it);
+	
+	if (isRankDof[**it]) {
+	  TEST_EXIT(rankOwnedDofsNewLocalIndex.count(*it) == 1)
+	    ("Missing DOF %d in rankOwnedDofsNewLocalIndex!\n", **it);
+	}
+      }
+    }
+#endif
+
     mapLocalGlobalDofs.clear();
     mapLocalDofIndex.clear();
 
+    // Iterate over all DOFs in ranks partition.
     for (DofIndexMap::iterator dofIt = rankDofsNewLocalIndex.begin();
 	 dofIt != rankDofsNewLocalIndex.end(); ++dofIt) {
-      DegreeOfFreedom localDof = dofIt->second;
-      DegreeOfFreedom globalDof = rankDofsNewGlobalIndex[dofIt->first];
+      DegreeOfFreedom newLocalIndex = dofIt->second;
+      DegreeOfFreedom newGlobalIndex = rankDofsNewGlobalIndex[dofIt->first];
 
-      *const_cast<DegreeOfFreedom*>(dofIt->first) = localDof;
-      mapLocalGlobalDofs[localDof] = globalDof;
+      *const_cast<DegreeOfFreedom*>(dofIt->first) = newLocalIndex;
+      mapLocalGlobalDofs[newLocalIndex] = newGlobalIndex;
     }
 
     for (DofIndexMap::iterator dofIt = rankOwnedDofsNewLocalIndex.begin();
 	 dofIt != rankOwnedDofsNewLocalIndex.end(); ++dofIt)
-      mapLocalDofIndex[dofIt->second] = *(dofIt->first);
+      mapLocalDofIndex[dofIt->second] = *(dofIt->first);    
   }
 
   
   void MeshDistributor::createDofMemberInfo(DofToPartitions& partitionDofs,
-					       DofContainer& rankOwnedDofs,
-					       DofContainer& rankAllDofs,
-					       DofToRank& boundaryDofs,
-					       DofToBool& vertexDof)
+					    DofContainer& rankOwnedDofs,
+					    DofContainer& rankAllDofs,
+					    DofToRank& boundaryDofs,
+					    DofToBool& isVertexDof)
   {
     partitionDofs.clear();
     rankOwnedDofs.clear();
     rankAllDofs.clear();
     boundaryDofs.clear();
-    vertexDof.clear();
+    isVertexDof.clear();
 
     // === Determine to each dof the set of partitions the dof belongs to. ===
 
@@ -1763,9 +1869,9 @@ namespace AMDiS {
 	partitionDofs[elDofIt.getDofPtr()].insert(partitionVec[element->getIndex()]);
 
 	if (elDofIt.getCurrentPos() == 0) 
-	  vertexDof[elDofIt.getDofPtr()] = true;
+	  isVertexDof[elDofIt.getDofPtr()] = true;
 	else
-	  vertexDof[elDofIt.getDofPtr()] = false;
+	  isVertexDof[elDofIt.getDofPtr()] = false;
       } while (elDofIt.next());
 
       elInfo = stack.traverseNext(elInfo);
@@ -1817,7 +1923,7 @@ namespace AMDiS {
       }
 
       if (!isInRank)
-	vertexDof.erase(it->first);
+	isVertexDof.erase(it->first);
     }
 
     sort(rankAllDofs.begin(), rankAllDofs.end(), cmpDofsByValue);
@@ -1997,7 +2103,7 @@ namespace AMDiS {
       elDofIter.reset(el);
       do {
 	dofMap[elDofIter.getDof()] = elDofIter.getDofPtr();
-      } while(elDofIter.next());      
+      } while (elDofIter.next());      
     }
 
     myIntBoundary.deserialize(in, elIndexMap);
diff --git a/AMDiS/src/parallel/ParallelDomainBase.h b/AMDiS/src/parallel/ParallelDomainBase.h
index 3b291e5d..c287bdb9 100644
--- a/AMDiS/src/parallel/ParallelDomainBase.h
+++ b/AMDiS/src/parallel/ParallelDomainBase.h
@@ -203,7 +203,6 @@ namespace AMDiS {
      */
     void synchVector(SystemVector &vec);
 
-
   protected:
     /** \brief
      * Determines the interior boundaries, i.e. boundaries between ranks, and stores
@@ -276,7 +275,7 @@ namespace AMDiS {
 			     DofContainer& rankOwnedDofs,
 			     DofContainer& rankAllDofs,
 			     DofToRank& boundaryDofs,
-			     DofToBool& vertexDof);
+			     DofToBool& isVertexDof);
 
     /** \brief
      * Checks for all given interior boundaries if the elements fit together on both
@@ -306,13 +305,15 @@ namespace AMDiS {
 			      Element *el, 
 			      GeoIndex subObj,
 			      int ithObj, 
-			      int elType);
+			      int elType,
+			      bool reverseMode);
     
     bool fitElementToMeshCode2(MeshStructure &code, 
 			       TraverseStack &stack,
 			       GeoIndex subObj,
 			       int ithObj, 
-			       int elType);
+			       int elType,
+			       bool reverseMode);
 
     /// Writes a vector of dof pointers to an output stream.
     void serialize(std::ostream &out, DofContainer &data);
@@ -516,6 +517,11 @@ namespace AMDiS {
      */
     long lastMeshChangeIndex;
 
+    /// This variable is true, if the macro elements are consistent with all other
+    /// data structures. Within the initialization and during mesh redistribution this
+    /// may not be the case.
+    bool macroElementStructureConsisten;
+
     friend class ParallelDomainDbg;
   };
 }
diff --git a/AMDiS/src/parallel/ParallelDomainDbg.cc b/AMDiS/src/parallel/ParallelDomainDbg.cc
index 4d0026fe..eeed93ba 100644
--- a/AMDiS/src/parallel/ParallelDomainDbg.cc
+++ b/AMDiS/src/parallel/ParallelDomainDbg.cc
@@ -6,6 +6,7 @@
 #include "FixVec.h"
 #include "StdMpi.h"
 #include "Debug.h"
+#include "MpiHelper.h"
 
 namespace AMDiS {
 
@@ -255,12 +256,19 @@ namespace AMDiS {
     for (RankToDofContainer::iterator it = recvDofs.begin(); it != recvDofs.end(); ++it)    
       stdMpi.recv(it->first);
     stdMpi.startCommunication<int>(MPI_INT);    
-       
+     
+    int foundError = 0;
     for (std::map<int, int>::iterator it = stdMpi.getRecvData().begin();
-	 it != stdMpi.getRecvData().end(); ++it)
-      TEST_EXIT(it->second == static_cast<int>(recvDofs[it->first].size()))
-	("Rank expectes %d DOFs to receive from rank %d, but %d DOFs are received!\n", 
-	 recvDofs[it->first].size(), it->first, it->second);
+	 it != stdMpi.getRecvData().end(); ++it) {
+      if (it->second != static_cast<int>(recvDofs[it->first].size())) {
+	ERROR("Rank expectes %d DOFs to receive from rank %d, but %d DOFs are received!\n", 
+	      recvDofs[it->first].size(), it->first, it->second);
+	foundError = 1;
+      }
+    }
+
+    mpi::globalAdd(foundError);
+    TEST_EXIT(foundError == 0)("Error found on at least one rank!\n");
   }
 
 
@@ -391,4 +399,29 @@ namespace AMDiS {
     }
   }
 
+
+  void ParallelDomainDbg::writeCoordsFile(MeshDistributor &pdb, 
+					  std::string prefix, std::string postfix)
+  {
+    FUNCNAME("ParallelDomainDbg::writeCoordsFile()");
+
+    std::stringstream filename;
+    filename << prefix << "-" << pdb.mpiRank << "." << postfix;
+
+    DOFVector<WorldVector<double> > coords(pdb.feSpace, "tmp");
+    pdb.mesh->getDofIndexCoords(pdb.feSpace, coords);
+
+    std::ofstream file;
+    file.open(filename.str().c_str());
+    file << coords.getUsedSize() << "\n";
+    DOFIterator<WorldVector<double> > it(&coords, USED_DOFS);
+    for (it.reset(); !it.end(); ++it) {
+      file << pdb.mapLocalGlobalDofs[it.getDOFIndex()];
+      for (int i = 0; i < pdb.mesh->getDim(); i++)
+	file << " " << (*it)[i];
+      file << "\n";
+    }
+    file.close();
+  }
+
 }
diff --git a/AMDiS/src/parallel/ParallelDomainDbg.h b/AMDiS/src/parallel/ParallelDomainDbg.h
index 1102dd98..d5523b91 100644
--- a/AMDiS/src/parallel/ParallelDomainDbg.h
+++ b/AMDiS/src/parallel/ParallelDomainDbg.h
@@ -112,6 +112,9 @@ namespace AMDiS {
      * \param[in]  pdb           Parallel problem definition used for debugging.
      */
     static void printBoundaryInfo(MeshDistributor &pdb);
+
+    static void writeCoordsFile(MeshDistributor &pdb, 
+				std::string prefix, std::string postfix);
   };
   
 } // namespace AMDiS
-- 
GitLab