diff --git a/AMDiS/CMakeLists.txt b/AMDiS/CMakeLists.txt
index a6f4ce880dc67d6fbfe8196ad6e8459cc6ade700..af9f197a14da69471080dfa7d09b9c36c861729f 100644
--- a/AMDiS/CMakeLists.txt
+++ b/AMDiS/CMakeLists.txt
@@ -36,6 +36,7 @@ if(CMAKE_CXX_COMPILER MATCHES ".*icpc")
 	set(CMAKE_CXX_FLAGS "-diag-disable 654 -diag-disable 858") 
 endif()
 
+
 SET(ENABLE_PARALLEL_DOMAIN "OFF" CACHE STRING "use parallel domain decomposition. please set to one of: PMTL, PETSC, OFF" )
 option(USE_PETSC_DEV false)
 option(ENABLE_ZOLTAN false)
@@ -43,6 +44,12 @@ option(ENABLE_UMFPACK "Use of UMFPACK solver" false)
 option(ENABLE_PNG "use png reader/writer" false)
 option(ENABLE_BDDCML "Use of BDDCML library" false)
 option(ENABLE_EXTENSIONS "Use extensions" false)
+option(ENABLE_OPENMP "Use OpenMP" false)
+option(ENABLE_OUTPUT "AMDiS output priniting, disable only for debugging!" true)
+
+
+mark_as_advanced(ENABLE_OUTPUT)
+
 
 find_package(Boost 1.42 REQUIRED)
 if(Boost_FOUND)
@@ -307,6 +314,12 @@ if(ENABLE_PNG)
 endif(ENABLE_PNG)
 
 
+if(NOT ENABLE_OUTPUT)
+       message(WARNING "AMDiS cout output disabled!")
+       list(APPEND COMPILEFLAGS "-DSUPPRESS_OUTPUT")
+endif(NOT ENABLE_OUTPUT)
+
+
 if(ENABLE_BDDCML)
 	SET(BDDCML_LINK_LIST "" CACHE STRING "Further libraries to be linked with BDDCML")
 		
@@ -440,6 +453,10 @@ if(ENABLE_EXTENSIONS)
 endif(ENABLE_EXTENSIONS)
 
 
+if(ENABLE_OPENMP)
+	list(APPEND COMPILEFLAGS "-fopenmp")
+endif(ENABLE_OPENMP)
+
 SET(COMPOSITE_SOURCE_DIR ${SOURCE_DIR}/compositeFEM)
 SET(COMPOSITE_FEM_SRC ${COMPOSITE_SOURCE_DIR}/CFE_Integration.cc 
 		      ${COMPOSITE_SOURCE_DIR}/CFE_NormAndErrorFcts.cc 
diff --git a/AMDiS/src/AMDiS_fwd.h b/AMDiS/src/AMDiS_fwd.h
index 9078dfb18a14a4f7eb43393cf1e526b715c64a4f..7afcc8a0efa2c3cd02154a092a63c24909b657a6 100644
--- a/AMDiS/src/AMDiS_fwd.h
+++ b/AMDiS/src/AMDiS_fwd.h
@@ -25,6 +25,7 @@
 #define AMDIS_AMDIS_FWD_INCLUDE
 
 #include <boost/numeric/mtl/mtl.hpp>
+#include "OpenMP.h"
 
 namespace AMDiS {
 
diff --git a/AMDiS/src/Assembler.h b/AMDiS/src/Assembler.h
index fabbb2e00d86df08741fbf61502f0fddf8f2e6e6..367cdfa98033f226adb95b9e9c99735bca176c2e 100644
--- a/AMDiS/src/Assembler.h
+++ b/AMDiS/src/Assembler.h
@@ -252,16 +252,12 @@ namespace AMDiS {
     ///
     ElementMatrix tmpMat;
   
-    /** \brief
-     * Used to check whether \ref initElement() must be called, because
-     * a new Element is visited.
-     */
+    /// Used to check whether \ref initElement() must be called, because
+    /// a new Element is visited.
     Element* lastMatEl;
 
-    /** \brief
-     * Used to check whether \ref initElement() must be called, because
-     * a new Element is visited.
-     */
+    /// Used to check whether \ref initElement() must be called, because
+    /// a new Element is visited.
     Element* lastVecEl;
 
     /// Used to check for new traverse.
diff --git a/AMDiS/src/BasisFunction.h b/AMDiS/src/BasisFunction.h
index 55f681632e7980e80d21342ee6ed3860a3f0e35c..553fd8960d64fd3d4dd62aa8b28e09f3a060f6ac 100644
--- a/AMDiS/src/BasisFunction.h
+++ b/AMDiS/src/BasisFunction.h
@@ -111,23 +111,6 @@ namespace AMDiS {
     virtual int* orderOfPositionIndices(const Element* el, GeoIndex position, 
 					int positionIndex) const = 0;
 
-    /** \brief
-     * Pointer to a function which connects the set of local basis functions
-     * with its global DOFs.
-     * getDOFIndices(el, admin, dof) returns a pointer to a const vector of 
-     * length \ref nBasFcts where the i-th entry is the index of the DOF 
-     * associated to the i-th basis function; arguments are the actual element 
-     * el and the DOF admin admin of the corresponding finite element space 
-     * (these indices depend on all defined DOF admins and thus on the 
-     * corresponding admin); if the last argument dof is NULL, getDOFndices 
-     * has to provide memory for storing this vector, which is overwritten on the
-     * next call of getDOFIndices; if dof is not NULL, dof is a pointer to a 
-     * vector which has to be filled;   
-     */
-    virtual const DegreeOfFreedom* getDOFIndices(const Element*,
-						 const DOFAdmin&, 
-						 DegreeOfFreedom*) const = 0;
-
     /** \brief
      * The second argument 'bound' has to be a pointer to a vector which has 
      * to be filled. Its length is \ref nBasFcts (the number of basis functions
@@ -190,8 +173,7 @@ namespace AMDiS {
      * , indices[n-1] are the local indices of the basis functions where the
      * coefficients have to be calculated, and the i-th entry in the return 
      * vector is then the coefficient of the indices[i]-th basis function; coeff 
-     * may be a pointer to a vector which has to be filled 
-     * (compare the dof argument of \ref getDOFIndices());
+     * may be a pointer to a vector which has to be filled.
      * such a function usually needs vertex coordinate information; thus, all 
      * routines using this function on the elements need the FILL COORDS flag 
      * during mesh traversal.
@@ -285,35 +267,20 @@ namespace AMDiS {
     {}
 
     /// Returns local dof indices of the element for the given fe space.
-    virtual const DegreeOfFreedom *getLocalIndices(const Element *el,
-						   const DOFAdmin *admin,
-						   DegreeOfFreedom *dofPtr) const
-    {
-      return NULL;
-    }
-
-    inline void getLocalIndices(const Element *el,
-				const DOFAdmin *admin,
-				vector<DegreeOfFreedom> &indices) const
-    {
-      FUNCNAME("BasisFunction::getLocalIndices()");
-      
-      TEST_EXIT_DBG(static_cast<int>(indices.size()) >= nBasFcts)
-	("Index vector is too small!\n");
-
-      getLocalIndices(el, admin, &(indices[0]));
-    }
+    virtual void getLocalIndices(const Element *el,
+				 const DOFAdmin *admin,
+				 vector<DegreeOfFreedom> &indices) const
+    {}
 
+    ///
     virtual void getLocalDofPtrVec(const Element *el, 
 				   const DOFAdmin *admin,
 				   vector<const DegreeOfFreedom*>& vec) const
     {}
 
 
-    /** \brief
-     * Evaluates elements value at barycentric coordinates lambda with local 
-     * coefficient vector uh.
-     */
+    /// Evaluates elements value at barycentric coordinates lambda with local 
+    /// coefficient vector uh.
     template<typename T>
     T evalUh(const DimVec<double>& lambda, const mtl::dense_vector<T>& uh) const;
 
diff --git a/AMDiS/src/DOFIndexed.h b/AMDiS/src/DOFIndexed.h
index 494cc41fc74b9f2e11fdc5d17c24e05f8abd0567..bfc0fc885f880367d8a1a2d3269a1244133c8250 100644
--- a/AMDiS/src/DOFIndexed.h
+++ b/AMDiS/src/DOFIndexed.h
@@ -60,28 +60,20 @@ namespace AMDiS {
     virtual void compressDOFIndexed(int first, int last, 
 				    std::vector<DegreeOfFreedom> &newDOF) = 0;
 
-    /** \brief
-     * Performs needed action when a DOF index is freed. Can be overriden in
-     * sub classes. The default behavior is to do nothing.
-     */
+    /// Performs needed action when a DOF index is freed. Can be overriden in
+    /// sub classes. The default behavior is to do nothing.
     virtual void freeDOFContent(int) {}
 
-    /** \brief
-     * Interpolation after refinement. Can be overriden in subclasses.
-     * The default behavior is to do nothing.
-     */
+    /// Interpolation after refinement. Can be overriden in subclasses.
+    /// The default behavior is to do nothing.
     virtual void refineInterpol(RCNeighbourList&, int) {}
 
-    /** \brief
-     * Restriction after coarsening. Can be overriden in subclasses.
-     * The default behavior is to do nothing.
-     */
+    /// Restriction after coarsening. Can be overriden in subclasses.
+    /// The default behavior is to do nothing.
     virtual void coarseRestrict(RCNeighbourList&, int) {}
 
-    /** \brief
-     * Returns the finite element space of this DOFIndexed object. Must be
-     * overriden in sub classes. 
-     */
+    /// Returns the finite element space of this DOFIndexed object. Must be
+    /// overriden in sub classes. 
     virtual const FiniteElemSpace* getFeSpace() const = 0;
   };
 
diff --git a/AMDiS/src/DOFMatrix.cc b/AMDiS/src/DOFMatrix.cc
index 9850d8f2cd8a8824cb9b0c03d4e7b19b27861b8b..20f90cf4cda1f8d72fedf7b6ce07d8f4ee45a0aa 100644
--- a/AMDiS/src/DOFMatrix.cc
+++ b/AMDiS/src/DOFMatrix.cc
@@ -231,16 +231,8 @@ namespace AMDiS {
 	bound ? boundaryManager->getBoundaryCondition(bound[i]) : NULL;
 
       if (condition && condition->isDirichlet()) {	
-	if (condition->applyBoundaryCondition()) {
-
-#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
-	  if (dofMap->isRankDof(rowIndices[i])) {
-	    dirichletDofs.insert(row);
-	  }
-#else
+	if (condition->applyBoundaryCondition())
 	  dirichletDofs.insert(row);
-#endif
-	}
       } else {
 	for (int j = 0; j < nCol; j++) {
 	  DegreeOfFreedom col = colIndices[j];
@@ -497,7 +489,10 @@ namespace AMDiS {
     inserter_type &ins = *inserter;  
     for (std::set<int>::iterator it = dirichletDofs.begin(); 
 	 it != dirichletDofs.end(); ++it)
-      ins[*it][*it] = 1.0;    
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+      if (dofMap->isRankDof(*it))
+#endif
+	ins[*it][*it] = 1.0;    
   }
 
 
diff --git a/AMDiS/src/DOFMatrix.h b/AMDiS/src/DOFMatrix.h
index 2f3b082095271be758a45476525800205b9e9eb6..d000661864cdc5328aa2bf5c811b2e807de0d331 100644
--- a/AMDiS/src/DOFMatrix.h
+++ b/AMDiS/src/DOFMatrix.h
@@ -313,6 +313,11 @@ namespace AMDiS {
       return rowFeSpace->getAdmin()->getUsedSize();
     }
 
+    std::set<DegreeOfFreedom>& getDirichletRows()
+    {
+      return dirichletDofs;
+    }
+
     /// Returns \ref name
     inline string getName() const 
     { 
diff --git a/AMDiS/src/DOFVector.cc b/AMDiS/src/DOFVector.cc
index 57212a3dcda8ba01296b7360aa52d952f98fa97a..9023f6ec429f94ce94028e482637f16804371128 100644
--- a/AMDiS/src/DOFVector.cc
+++ b/AMDiS/src/DOFVector.cc
@@ -79,7 +79,7 @@ namespace AMDiS {
     int dim = mesh->getDim();
     int nBasFcts = basFcts->getNumber();
   
-    DegreeOfFreedom *localIndices = new DegreeOfFreedom[nBasFcts];
+    std::vector<DegreeOfFreedom> localIndices(nBasFcts);
     DimVec<double> lambda(dim, NO_INIT);
   
     ElInfo *elInfo = mesh->createNewElInfo();
@@ -104,7 +104,6 @@ namespace AMDiS {
     } else
       throw(std::runtime_error("Can not eval DOFVector at point p, because point is outside geometry."));
 
-    delete [] localIndices;
     if (oldElInfo == NULL)
       delete elInfo;
 
@@ -124,11 +123,9 @@ namespace AMDiS {
     int dim = mesh->getDim();
     int nBasFcts = basFcts->getNumber();
   
-    DegreeOfFreedom *localIndices = new DegreeOfFreedom[nBasFcts];
-    DimVec<double> lambda(dim, NO_INIT);
-  
+    std::vector<DegreeOfFreedom> localIndices(nBasFcts);
+    DimVec<double> lambda(dim, NO_INIT);  
     ElInfo *elInfo = mesh->createNewElInfo();
-
     WorldVector<double> value(DEFAULT_VALUE, 0.0);
     bool inside = false;
   
@@ -150,7 +147,6 @@ namespace AMDiS {
     } else
       throw(std::runtime_error("Can not eval DOFVector at point p, because point is outside geometry."));
 
-    delete [] localIndices;
     if (oldElInfo == NULL)
       delete elInfo;
 
diff --git a/AMDiS/src/DOFVector.h b/AMDiS/src/DOFVector.h
index a8335726f0fcf59105a90ad9e83be9803016c9e9..e7fc40b349cb5116bb33f31748aa4723b9fcdbe9 100644
--- a/AMDiS/src/DOFVector.h
+++ b/AMDiS/src/DOFVector.h
@@ -237,6 +237,18 @@ namespace AMDiS {
       boundaryManager = bm;
     }
 
+    inline void setDirichletDofValue(DegreeOfFreedom dof,
+				     T value)
+    {
+      dirichletDofValues[dof] = value;
+    }
+
+    map<DegreeOfFreedom, T>& getDirichletValues()
+    {
+      return dirichletDofValues;
+    }
+
+
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
     void setDofMap(FeSpaceDofMap& m)
     {
@@ -249,17 +261,6 @@ namespace AMDiS {
 
       return dofMap->isRankDof(dof);
     }
-
-    inline void setDirichletDofValue(DegreeOfFreedom dof,
-				     T value)
-    {
-      dirichletDofValues[dof] = value;
-    }
-
-    map<DegreeOfFreedom, T>& getDirichletValues()
-    {
-      return dirichletDofValues;
-    }
 #endif
 
   protected:
@@ -290,10 +291,10 @@ namespace AMDiS {
     /// Dimension of the mesh this DOFVectorBase belongs to
     int dim;
 
+    map<DegreeOfFreedom, T> dirichletDofValues;
+
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
     FeSpaceDofMap *dofMap;
-
-    map<DegreeOfFreedom, T> dirichletDofValues;
 #endif
   };
 
diff --git a/AMDiS/src/DOFVector.hh b/AMDiS/src/DOFVector.hh
index 39ecb551407ed2488f7969748c491d35ebc57ef2..e0cc38656d999a782bd9ca37c2ca5dc28774e228 100644
--- a/AMDiS/src/DOFVector.hh
+++ b/AMDiS/src/DOFVector.hh
@@ -1374,9 +1374,9 @@ namespace AMDiS {
     TEST_EXIT_DBG(feSpace->getMesh() == el->getMesh())
       ("Element is defined on a different mesh than the DOF vector!\n");
 
+    std::vector<int> localIndices(nBasFcts);
     const DOFAdmin* admin = feSpace->getAdmin();
-    const DegreeOfFreedom *localIndices = 
-      feSpace->getBasisFcts()->getLocalIndices(el, admin, NULL);   
+    feSpace->getBasisFcts()->getLocalIndices(el, admin, localIndices);
 
     for (int i = 0; i < nBasFcts; i++)
       d[i] = (*this)[localIndices[i]];
diff --git a/AMDiS/src/DirichletBC.cc b/AMDiS/src/DirichletBC.cc
index face0ddd3ece92c35d86f11a294aeeb2b101cd39..38952e597980ab43e29916470a1b187f9eb2c5f8 100644
--- a/AMDiS/src/DirichletBC.cc
+++ b/AMDiS/src/DirichletBC.cc
@@ -65,7 +65,6 @@ namespace AMDiS {
 
     for (int i = 0; i < nBasFcts; i++) {
 
-#if 1
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
       if (vector->isRankDof(dofIndices[i]))
 #endif
@@ -80,29 +79,10 @@ namespace AMDiS {
 	    else
 	      ERROR_EXIT("There is something wrong!\n");
 	  }
-
+	  vector->setDirichletDofValue(dofIndices[i], value);
 	  (*vector)[dofIndices[i]] = value;
 	}
-#else
-      if (localBound[i] == boundaryType) {
-	double value = 0.0;
-	if (f) {
-          elInfo->coordToWorld(*(basFcts->getCoords(i)), worldCoords);
-	  value = (*f)(worldCoords);
-	}
-	if (dofVec)
-	  value = (*dofVec)[dofIndices[i]];
-
-#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
-	vector->setDirichletDofValue(dofIndices[i], value);
-#else
-	(*vector)[dofIndices[i]] = value;
-#endif
-      }
-#endif
-
     }
-
   }
 
 }
diff --git a/AMDiS/src/FirstOrderAssembler.cc b/AMDiS/src/FirstOrderAssembler.cc
index 4359539fe4a1275a59ce0760255a682f8e05b7f4..1c5760543ddcc25b96a4ee1050a92bc5b6591f39 100644
--- a/AMDiS/src/FirstOrderAssembler.cc
+++ b/AMDiS/src/FirstOrderAssembler.cc
@@ -22,11 +22,15 @@
 
 namespace AMDiS {
 
-  std::vector<SubAssembler*> FirstOrderAssembler::optimizedSubAssemblersGrdPhi;
-  std::vector<SubAssembler*> FirstOrderAssembler::optimizedSubAssemblersGrdPsi;
+  ThreadPrivate<vector<SubAssembler*> > 
+  FirstOrderAssembler::optimizedSubAssemblersGrdPhi;
+  ThreadPrivate<vector<SubAssembler*> >
+  FirstOrderAssembler::optimizedSubAssemblersGrdPsi;
 
-  std::vector<SubAssembler*> FirstOrderAssembler::standardSubAssemblersGrdPhi;
-  std::vector<SubAssembler*> FirstOrderAssembler::standardSubAssemblersGrdPsi;
+  ThreadPrivate<vector<SubAssembler*> >
+  FirstOrderAssembler::standardSubAssemblersGrdPhi;
+  ThreadPrivate<vector<SubAssembler*> >
+  FirstOrderAssembler::standardSubAssemblersGrdPsi;
 
 
   FirstOrderAssembler::FirstOrderAssembler(Operator *op,
@@ -51,16 +55,16 @@ namespace AMDiS {
 							    FirstOrderType type,
 							    bool optimized)
   {
-    std::vector<SubAssembler*> *subAssemblers =
+    vector<SubAssembler*> &subAssemblers =
       optimized ?
       (type == GRD_PSI ? 
-       &optimizedSubAssemblersGrdPsi : 
-       &optimizedSubAssemblersGrdPhi) :
+       optimizedSubAssemblersGrdPsi.get() : 
+       optimizedSubAssemblersGrdPhi.get()) :
       (type == GRD_PSI ? 
-       &standardSubAssemblersGrdPsi :
-       &standardSubAssemblersGrdPhi);
+       standardSubAssemblersGrdPsi.get() :
+       standardSubAssemblersGrdPhi.get());
     
-    std::vector<OperatorTerm*> opTerms = 
+    vector<OperatorTerm*> opTerms = 
       (type == GRD_PSI) ? op->firstOrderGrdPsi : op->firstOrderGrdPhi;
 
     // check if a assembler is needed at all
@@ -72,13 +76,13 @@ namespace AMDiS {
     FirstOrderAssembler *newAssembler;
 
     // check if a new assembler is needed
-    for (unsigned int i = 0; i < subAssemblers->size(); i++) {
-      std::vector<OperatorTerm*> assTerms = *((*subAssemblers)[i]->getTerms());
+    for (unsigned int i = 0; i < subAssemblers.size(); i++) {
+      vector<OperatorTerm*> assTerms = *(subAssemblers[i]->getTerms());
     
       sort(assTerms.begin(), assTerms.end());   
 
-      if (opTerms == assTerms && (*subAssemblers)[i]->getQuadrature() == quad)
-	return dynamic_cast<FirstOrderAssembler*>((*subAssemblers)[i]);
+      if (opTerms == assTerms && subAssemblers[i]->getQuadrature() == quad)
+	return dynamic_cast<FirstOrderAssembler*>(subAssemblers[i]);
     }
 
     // check if all terms are pw_const
@@ -110,7 +114,7 @@ namespace AMDiS {
        }
     }
 
-    subAssemblers->push_back(newAssembler);
+    subAssemblers.push_back(newAssembler);
     return newAssembler;
   }
 
@@ -130,7 +134,7 @@ namespace AMDiS {
     mtl::dense_vector<double> grdPsi(dim + 1, 0.0);
     int nPoints = quadrature->getNumPoints();
     Lb.resize(nPoints);
-    std::vector<double> phival(nCol);
+    vector<double> phival(nCol);
 
     for (int iq = 0; iq < nPoints; iq++) {
       Lb[iq].change_dim(dim + 1);
diff --git a/AMDiS/src/FirstOrderAssembler.h b/AMDiS/src/FirstOrderAssembler.h
index 298522537ae005ca712722e9fef513dce202fad8..61f2aaae476647c04dd7915bbcd973f52ce7a996 100644
--- a/AMDiS/src/FirstOrderAssembler.h
+++ b/AMDiS/src/FirstOrderAssembler.h
@@ -23,11 +23,14 @@
 #ifndef AMDIS_FIRST_ORDER_ASSEMBLER_H
 #define AMDIS_FIRST_ORDER_ASSEMBLER_H
 
+#include <vector>
 #include "AMDiS_fwd.h"
 #include "SubAssembler.h"
 
 namespace AMDiS {
 
+  using namespace std;
+
   /**
    * \ingroup Assembler
    * 
@@ -62,19 +65,19 @@ namespace AMDiS {
 
   protected:
     /// Vector of DimMats for calculation in function calculateElementMatrix().
-    std::vector<mtl::dense_vector<double> > Lb;
+    vector<mtl::dense_vector<double> > Lb;
 
     /// List of all yet created optimized zero order assemblers for grdPsi.
-    static std::vector<SubAssembler*> optimizedSubAssemblersGrdPsi;
+    static ThreadPrivate<vector<SubAssembler*> > optimizedSubAssemblersGrdPsi;
 
     /// List of all yet created standard zero order assemblers for grdPsi.
-    static std::vector<SubAssembler*> standardSubAssemblersGrdPsi;
+    static ThreadPrivate<vector<SubAssembler*> > standardSubAssemblersGrdPsi;
 
     /// List of all yet created optimized zero order assemblers for grdPhi.
-    static std::vector<SubAssembler*> optimizedSubAssemblersGrdPhi;
+    static ThreadPrivate<vector<SubAssembler*> > optimizedSubAssemblersGrdPhi;
 
     /// List of all yet created standard zero order assemblers for grdPhi.
-    static std::vector<SubAssembler*> standardSubAssemblersGrdPhi;
+    static ThreadPrivate<vector<SubAssembler*> > standardSubAssemblersGrdPhi;
   };
 
 
diff --git a/AMDiS/src/Global.cc b/AMDiS/src/Global.cc
index 1b8499423fcbe3860e8efef0fbbf42e40a05ede1..55ad68b6e69b1cd0ed6ce9aea3f0c023476c055a 100644
--- a/AMDiS/src/Global.cc
+++ b/AMDiS/src/Global.cc
@@ -29,7 +29,7 @@ namespace AMDiS {
   bool Msg::outputMainRank = false;
 #endif
 
-  const char *Msg::oldFuncName = NULL;
+  ThreadPrivate<const char *> Msg::oldFuncName(NULL);
   std::ostream* Msg::out = NULL;
   std::ostream* Msg::error = NULL;
   int Global::dimOfWorld = 0;
@@ -125,14 +125,14 @@ namespace AMDiS {
     if (!out) 
       out = &std::cout;
 
-    if (funcName &&  oldFuncName != funcName) {
+    if (funcName &&  oldFuncName.get() != funcName) {
       PRINT_LINE((*out), funcName << ":" << std::endl);
     } else if (!funcName) {
       PRINT_LINE((*out), "*unknown function*" << std::endl);
     }
     PRINT_LINE((*out), "               ");
 
-    oldFuncName = funcName;
+    oldFuncName.set(funcName);
   }
 
 
@@ -145,16 +145,16 @@ namespace AMDiS {
 
     std::stringstream oss;
 
-    if (funcName && oldFuncName != funcName) {
+    if (funcName && oldFuncName.get() != funcName) {
       oss << funcName << ": ";
     } else if (!funcName) {
       if (line-old_line > 5) 
 	oss << "*unknown function*";
     }
 
-    if (oldFuncName != funcName) {
+    if (oldFuncName.get() != funcName) {
       oss << "ERROR in " << file << ", line " << line << std::endl;;
-      oldFuncName = funcName;
+      oldFuncName.set(funcName);
     } else if (line - old_line > 5)
       oss << "ERROR in " << file << ", line " << line << "\n" << std::endl;
 
@@ -207,15 +207,15 @@ namespace AMDiS {
 
     std::stringstream oss;
 
-    if (funcName  &&  oldFuncName != funcName) {
+    if (funcName  &&  oldFuncName.get() != funcName) {
       oss << funcName << ": ";
     } else if (!funcName) {
       oss << "*unknown function*";
     }
 
-    if (oldFuncName != funcName) {
+    if (oldFuncName.get() != funcName) {
       oss << "WARNING in " << file << ", line " << line << std::endl;
-      oldFuncName = funcName;
+      oldFuncName.set(funcName);
     } else if (line - old_line > 5) {
       oss << "WARNING in " << file << ", line " << line << std::endl;
     }
@@ -244,6 +244,7 @@ namespace AMDiS {
 
   void Msg::print(const char *format, ...)
   {
+#ifndef SUPPRESS_OUTPUT
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
     if (outputMainRank && MPI::COMM_WORLD.Get_rank() != 0)
       return;
@@ -259,6 +260,7 @@ namespace AMDiS {
     vsprintf(buff, format, arg);
     (*out) << buff;
     va_end(arg);
+#endif
   }
 
 
diff --git a/AMDiS/src/Global.h b/AMDiS/src/Global.h
index abfb3fbddc6d7593417582d5bb7b46aceadbd1d1..d11c33c9fa8a215f265a40cee768957b4b769a72 100644
--- a/AMDiS/src/Global.h
+++ b/AMDiS/src/Global.h
@@ -60,6 +60,7 @@
 #include <boost/algorithm/string/trim.hpp>
 #include "boost/tuple/tuple.hpp"
 #include "AMDiS_fwd.h"
+#include "OpenMP.h"
 
 namespace AMDiS {
 
@@ -100,10 +101,15 @@ namespace AMDiS {
   /// Returns the dimension of GeoIndex ind for dimension dim
 #define DIM_OF_INDEX(ind, dim) ((static_cast<int>(ind) == 0) ? dim : static_cast<int>(ind) - 1)
 
+
+#if SUPPRESS_OUTPUT
+#define PRINT_LINE(stream, line)
+#else
 #if HAVE_PARALLEL_DOMAIN_AMDIS
 #define PRINT_LINE(stream, line) stream << "[" << MPI::COMM_WORLD.Get_rank() << "] " << line
 #else
 #define PRINT_LINE(stream, line) stream << line
+#endif
 #endif
 
   /// Calculates factorial of i
@@ -298,7 +304,7 @@ namespace AMDiS {
 
     /// Remember funcName to avoid multiple output of funcName within the same
     /// function call
-    static const char *oldFuncName;
+    static ThreadPrivate<const char*> oldFuncName;
 
     /// Global info level
     static int msgInfo;
diff --git a/AMDiS/src/Lagrange.cc b/AMDiS/src/Lagrange.cc
index 21d597780e3f4f1f6049849ae69e1f67006beaf5..064cae81d76bec559e81b0851a3a5dde4c67fedb 100644
--- a/AMDiS/src/Lagrange.cc
+++ b/AMDiS/src/Lagrange.cc
@@ -391,7 +391,9 @@ namespace AMDiS {
     }
   }
 
-  Lagrange::Phi::~Phi() { 
+
+  Lagrange::Phi::~Phi() 
+  { 
     delete [] vertices; 
   }
 
@@ -701,14 +703,6 @@ namespace AMDiS {
   }
 
 
-  const DegreeOfFreedom *Lagrange::getDOFIndices(const Element *el, 
-						 const DOFAdmin& admin,
-						 DegreeOfFreedom *idof) const
-  {
-    WARNING("depricated: use getLocalIndices() instead\n");
-    return getLocalIndices(el, &admin, idof);
-  }
-
   int* Lagrange::orderOfPositionIndices(const Element* el, 
 					GeoIndex position, 
 					int positionIndex) const
@@ -887,32 +881,16 @@ namespace AMDiS {
   }
 
 
-  const DegreeOfFreedom *Lagrange::getLocalIndices(const Element* el,
-						   const DOFAdmin *admin,
-						   DegreeOfFreedom *indices) const
+  void Lagrange::getLocalIndices(const Element *el, 
+				 const DOFAdmin *admin,
+				 std::vector<DegreeOfFreedom>& dofs) const
   {
-    static DegreeOfFreedom *localVec = NULL;
-    static int localVecSize = 0;
+    if (static_cast<int>(dofs.size()) < nBasFcts)
+      dofs.resize(nBasFcts);
 
     const DegreeOfFreedom **dof = el->getDof();
-
-    int nrDOFs, n0, node0, num = 0;
     GeoIndex posIndex;
-    DegreeOfFreedom* result;
-
-    if (indices) {
-      result = indices;
-    } else {
-      if (localVec && nBasFcts > localVecSize) {
-	delete [] localVec;
-	localVec = new DegreeOfFreedom[nBasFcts];
-      }
-      if (!localVec)
-	localVec = new DegreeOfFreedom[nBasFcts];
-
-      localVecSize = nBasFcts;
-      result = localVec;
-    }
+    int nrDOFs, n0, node0, num = 0;
 
     for (int pos = 0, j = 0; pos <= dim; pos++) {
       posIndex = INDEX_OF_DIM(pos, dim);
@@ -927,20 +905,19 @@ namespace AMDiS {
 	  const int *indi = orderOfPositionIndices(el, posIndex, i);
 
 	  for (int k = 0; k < nrDOFs; k++)
-	    result[j++] = dof[node0][n0 + indi[k]];  
+	    dofs[j++] = dof[node0][n0 + indi[k]];
 	}
       }
     }
-
-    return result;
   }
 
+
   void Lagrange::getLocalDofPtrVec(const Element *el, 
 				   const DOFAdmin *admin,
-				   std::vector<const DegreeOfFreedom*>& vec) const
+				   std::vector<const DegreeOfFreedom*>& dofs) const 
   {
-    if (static_cast<int>(vec.size()) < nBasFcts)
-      vec.resize(nBasFcts);
+    if (static_cast<int>(dofs.size()) < nBasFcts)
+      dofs.resize(nBasFcts);
 
     const DegreeOfFreedom **dof = el->getDof();
     GeoIndex posIndex;
@@ -959,12 +936,13 @@ namespace AMDiS {
 	  const int *indi = orderOfPositionIndices(el, posIndex, i);
 
 	  for (int k = 0; k < nrDOFs; k++)
-	    vec[j++] = &(dof[node0][n0 + indi[k]]);
+	    dofs[j++] = &(dof[node0][n0 + indi[k]]);
 	}
       }
     }
   }
 
+
   void Lagrange::l2ScpFctBas(Quadrature *q,
 			     AbstractFunction<WorldVector<double>, WorldVector<double> >* f,
 			     DOFVector<WorldVector<double> >* fh)
@@ -972,6 +950,7 @@ namespace AMDiS {
     ERROR_EXIT("not yet\n");
   }
 
+
   void Lagrange::l2ScpFctBas(Quadrature *quad,
 			     AbstractFunction<double, WorldVector<double> >* f,
 			     DOFVector<double>* fh)
@@ -991,16 +970,17 @@ namespace AMDiS {
 
     const FastQuadrature *quad_fast = 
       FastQuadrature::provideFastQuadrature(this, *quad, INIT_PHI);
-    double *wdetf_qp = new double[quad->getNumPoints()];
+    vector<double> wdetf_qp(quad->getNumPoints());
     int nPoints = quad->getNumPoints();
     DOFAdmin *admin = fh->getFeSpace()->getAdmin();
     WorldVector<double> x;
+    vector<DegreeOfFreedom> dof;
 
     TraverseStack stack;
     ElInfo *elInfo = stack.traverseFirst(fh->getFeSpace()->getMesh(), -1, 
 					  Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
     while (elInfo) {
-      const DegreeOfFreedom  *dof = getLocalIndices(elInfo->getElement(), admin, NULL);
+      getLocalIndices(elInfo->getElement(), admin, dof);
       double det = elInfo->getDet();
 
       for (int iq = 0; iq < nPoints; iq++) {
@@ -1018,8 +998,6 @@ namespace AMDiS {
 
       elInfo = stack.traverseNext(elInfo);
     }
-
-    delete [] wdetf_qp;
   }
 
 
@@ -1083,7 +1061,8 @@ namespace AMDiS {
     
     Element *el = list->getElement(0);
     const DOFAdmin *admin = drv->getFeSpace()->getAdmin();
-    const DegreeOfFreedom *pdof = basFct->getLocalIndices(el, admin, NULL);
+    vector<DegreeOfFreedom> pdof;
+    basFct->getLocalIndices(el, admin, pdof);
   
     int node = drv->getFeSpace()->getMesh()->getNode(VERTEX);        
     int n0 = admin->getNumberOfPreDofs(VERTEX);
@@ -1127,7 +1106,8 @@ namespace AMDiS {
 
     const DOFAdmin *admin = drv->getFeSpace()->getAdmin();
     Element *el = list->getElement(0);
-    const DegreeOfFreedom *pdof = basFct->getLocalIndices(el, admin, NULL);
+    vector<DegreeOfFreedom> pdof;
+    basFct->getLocalIndices(el, admin, pdof);
   
     int node = drv->getFeSpace()->getMesh()->getNode(VERTEX);        
     int n0 = admin->getNumberOfPreDofs(VERTEX);
@@ -1173,7 +1153,7 @@ namespace AMDiS {
       /*  adjust the value at the midpoint of the common edge of neigh's children */
       /****************************************************************************/
       el = list->getElement(1);
-      pdof = basFct->getLocalIndices(el, admin, NULL);
+      basFct->getLocalIndices(el, admin, pdof);
       
       cdof = el->getChild(0)->getDof(node + 1, n0); 
       (*drv)[cdof] = 
@@ -1193,8 +1173,7 @@ namespace AMDiS {
 
     Element *el = list->getElement(0);
     const DOFAdmin *admin = drv->getFeSpace()->getAdmin();
-
-    DegreeOfFreedom pdof[10];
+    vector<DegreeOfFreedom> pdof(10);
     basFct->getLocalIndices(el, admin, pdof);
 
     int node0 = drv->getFeSpace()->getMesh()->getNode(EDGE);
@@ -1204,7 +1183,8 @@ namespace AMDiS {
     /*  values on child[0]                                                      */
     /****************************************************************************/
 
-    const DegreeOfFreedom *cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
+    vector<DegreeOfFreedom> cdof(10);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
 
     (*drv)[cdof[3]] = ((*drv)[pdof[4]]);
     (*drv)[cdof[6]] = 
@@ -1275,14 +1255,13 @@ namespace AMDiS {
 
     Element *el = list->getElement(0);
     const DOFAdmin *admin = drv->getFeSpace()->getAdmin();
-
-    DegreeOfFreedom *pdof = new DegreeOfFreedom[basFct->getNumber()];
+    vector<DegreeOfFreedom> pdof, cdof;
     basFct->getLocalIndices(el, admin, pdof);
-  
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
+
     /****************************************************************************/
     /*  values on child[0]                                                      */
     /****************************************************************************/
-    const DegreeOfFreedom *cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
 
     (*drv)[cdof[2]] = 
       (-0.0625 * ((*drv)[pdof[0]] + (*drv)[pdof[1]]) 
@@ -1306,7 +1285,7 @@ namespace AMDiS {
     /*  values on child[1]                                                      */
     /****************************************************************************/
 
-    cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cdof);
 
     (*drv)[cdof[5]] =  (*drv)[pdof[8]];
     (*drv)[cdof[6]] =  
@@ -1317,10 +1296,9 @@ namespace AMDiS {
        - 0.125 * (*drv)[pdof[6]] + 0.1875 * (-(*drv)[pdof[7]] + (*drv)[pdof[8]])
        + 0.75 * (*drv)[pdof[9]]);
 
-    if (n <= 1) {
-      delete [] pdof;
+    if (n <= 1)
       return;
-    }
+    
     /****************************************************************************/
     /*  adjust the value on the neihgbour                                       */
     /****************************************************************************/
@@ -1331,7 +1309,7 @@ namespace AMDiS {
     /****************************************************************************/
     /*  values on neigh's child[0]                                              */
     /****************************************************************************/
-    cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
   
     (*drv)[cdof[5]] =  (*drv)[pdof[9]];
     (*drv)[cdof[6]] = 
@@ -1355,8 +1333,6 @@ namespace AMDiS {
       (0.0625 * ((*drv)[pdof[0]] - (*drv)[pdof[1]]) +  0.375 * (*drv)[pdof[3]]
        - 0.125 * (*drv)[pdof[6]] + 0.1875 * (-(*drv)[pdof[7]] + (*drv)[pdof[8]])
        + 0.75  *(*drv)[pdof[9]]);
-
-    delete [] pdof;
   }
 
   void Lagrange::refineInter3_2d(DOFIndexed<double> *drv, 
@@ -1372,13 +1348,13 @@ namespace AMDiS {
     Element *el = list->getElement(0);
     const DOFAdmin *admin = drv->getFeSpace()->getAdmin();
 
-    DegreeOfFreedom pdof[10];
+    vector<DegreeOfFreedom> pdof, cdof;
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
   
     /****************************************************************************/
     /*  values on child[0]                                                      */
     /****************************************************************************/
-    const DegreeOfFreedom *cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
 
     (*drv)[cdof[2]] =
       (-0.0625 * ((*drv)[pdof[0]] + (*drv)[pdof[1]]) 
@@ -1402,7 +1378,7 @@ namespace AMDiS {
     /*  values on child[0]                                                      */
     /****************************************************************************/
 
-    cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cdof);
 
     (*drv)[cdof[5]] = (*drv)[pdof[8]];
     (*drv)[cdof[6]] =  
@@ -1422,11 +1398,11 @@ namespace AMDiS {
 
     el = list->getElement(1);
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
 
     /****************************************************************************/
     /*  values on neigh's child[0]                                              */
     /****************************************************************************/
-    cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
   
     (*drv)[cdof[5]] =  (*drv)[pdof[9]];
     (*drv)[cdof[6]] =  
@@ -1461,25 +1437,19 @@ namespace AMDiS {
     if (n < 1) 
       return;
 
-    Element *el;
-    const DegreeOfFreedom *cd;
-    DegreeOfFreedom pd[20], cdi;
-    int i, typ, lr_set, node0, n0;
-    const DOFAdmin *admin;
-
-    el = list->getElement(0);
-    typ = list->getType(0);
-
-    admin = drv->getFeSpace()->getAdmin();
-
+    DegreeOfFreedom cdi;
+    int i, lr_set, node0, n0;
+    Element *el = list->getElement(0);
+    int typ = list->getType(0);
+    const DOFAdmin * admin = drv->getFeSpace()->getAdmin();
+    vector<DegreeOfFreedom> pd(20), cd(20);
     basFct->getLocalIndices(el, admin, pd);
+    basFct->getLocalIndices(el->getChild(0), admin, cd);
 
     /****************************************************************************/
     /*  values on child[0]                                                      */
     /****************************************************************************/
 
-    cd = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
     (*drv)[cd[3]] = 
       (0.0625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) 
        + 0.5625*((*drv)[pd[4]] + (*drv)[pd[5]]));
@@ -1515,7 +1485,7 @@ namespace AMDiS {
     /*  values on child[1]                                                      */
     /****************************************************************************/
 
-    cd = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cd);
 
     if (typ == 0) {
       /****************************************************************************/
@@ -1578,7 +1548,7 @@ namespace AMDiS {
       /*  values on child[0]                                                      */
       /****************************************************************************/
 
-      cd = basFct->getLocalIndices(el->getChild(0), admin, NULL);
+      basFct->getLocalIndices(el->getChild(0), admin, cd);
 
       switch (lr_set) {
       case 1:
@@ -1626,7 +1596,7 @@ namespace AMDiS {
       /*  values on child[1]                                                      */
       /****************************************************************************/
 
-      cd = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+      basFct->getLocalIndices(el->getChild(1), admin, cd);
 
       if (typ == 0) {
 	switch (lr_set) {
@@ -1679,19 +1649,17 @@ namespace AMDiS {
     if (n < 1) 
       return;
 
-    DegreeOfFreedom *pdof = new DegreeOfFreedom[basFct->getNumber()];
     const DOFAdmin *admin = drv->getFeSpace()->getAdmin();
     Element *el = list->getElement(0);
 
+    vector<DegreeOfFreedom> pdof, cdof;
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
 
     /****************************************************************************/
     /*  values on child[0]                                                      */
     /****************************************************************************/
 
-    const DegreeOfFreedom *cdof = 
-      basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
     (*drv)[cdof[2]] = (*drv)[pdof[10]];
     (*drv)[cdof[3]] = 
       (0.2734375*(*drv)[pdof[0]] - 0.0390625*(*drv)[pdof[1]]
@@ -1732,7 +1700,7 @@ namespace AMDiS {
     /*  values on child[1]                                                      */
     /****************************************************************************/
   
-    cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cdof);
 
     (*drv)[cdof[6]] = 
       (0.0234375*(*drv)[pdof[0]] - 0.0390625*(*drv)[pdof[1]]
@@ -1756,24 +1724,21 @@ namespace AMDiS {
        - 0.03125*(*drv)[pdof[11]] + 0.75*(*drv)[pdof[14]]);
     (*drv)[cdof[14]] = (*drv)[pdof[13]];
 
-    if (n <= 1) {
-      delete [] pdof;
+    if (n <= 1)
       return;
-    }
+
     /****************************************************************************/
     /*   adjust neighbour values                                                */
     /****************************************************************************/
 
     el = list->getElement(1);
-
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
 
     /****************************************************************************/
     /*  values on neighbour's child[0]                                          */
     /****************************************************************************/
 
-    cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
     (*drv)[cdof[6]] = 
       (0.0234375*((*drv)[pdof[0]] + (*drv)[pdof[1]])
        + 0.0625*(-(*drv)[pdof[3]] - (*drv)[pdof[8]])
@@ -1804,7 +1769,7 @@ namespace AMDiS {
     /*  values on neighbour's child[1]                                          */
     /****************************************************************************/
 
-    cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cdof);
 
     (*drv)[cdof[12]] = 
       (0.0390625*(-(*drv)[pdof[0]] - (*drv)[pdof[1]])
@@ -1818,8 +1783,6 @@ namespace AMDiS {
        + 0.09375*(*drv)[pdof[9]] - 0.046875*(*drv)[pdof[10]]
        - 0.03125*(*drv)[pdof[11]] + 0.75*(*drv)[pdof[14]]);
     (*drv)[cdof[14]] = (*drv)[pdof[13]];
-
-    delete [] pdof;
   }
 
   void Lagrange::refineInter4_2d(DOFIndexed<double> *drv, 
@@ -1827,24 +1790,20 @@ namespace AMDiS {
 				 int n, BasisFunction* basFct)
   {
     FUNCNAME("Lagrange::refineInter4_2d");
-    Element *el;
-    DegreeOfFreedom pdof[15];
-    const DegreeOfFreedom *cdof;
-    const DOFAdmin *admin;
 
     if (n < 1) 
       return;
 
-    el = list->getElement(0);
-    admin = drv->getFeSpace()->getAdmin();
+    Element * el = list->getElement(0);
+    const DOFAdmin *admin = drv->getFeSpace()->getAdmin();
+    vector<DegreeOfFreedom> pdof(15), cdof(15);
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
 
     /****************************************************************************/
     /*  values on child[0]                                                      */
     /****************************************************************************/
 
-    cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
     (*drv)[cdof[2]] = (*drv)[pdof[10]];
     (*drv)[cdof[3]] = 
       (0.2734375*(*drv)[pdof[0]] - 0.0390625*(*drv)[pdof[1]]
@@ -1887,7 +1846,7 @@ namespace AMDiS {
     /*  values on child[1]                                                      */
     /****************************************************************************/
   
-    cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cdof);
 
     (*drv)[cdof[6]] = 
       (0.0234375*(*drv)[pdof[0]] - 0.0390625*(*drv)[pdof[1]]
@@ -1919,15 +1878,13 @@ namespace AMDiS {
     /****************************************************************************/
 
     el = list->getElement(1);
-
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
 
     /****************************************************************************/
     /*  values on neighbour's child[0]                                          */
     /****************************************************************************/
 
-    cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
     (*drv)[cdof[6]] = 
       (0.0234375*((*drv)[pdof[0]] + (*drv)[pdof[1]])
        + 0.0625*(-(*drv)[pdof[3]] - (*drv)[pdof[8]])
@@ -1958,7 +1915,7 @@ namespace AMDiS {
     /*  values on neighbour's child[1]                                          */
     /****************************************************************************/
 
-    cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cdof);
 
     (*drv)[cdof[12]] = 
       (0.0390625*(-(*drv)[pdof[0]] - (*drv)[pdof[1]])
@@ -1979,9 +1936,6 @@ namespace AMDiS {
 				 int n, BasisFunction* basFct)
   {
     FUNCNAME("Lagrange::refineInter4_3d");
-    DegreeOfFreedom pd[35];
-    const DegreeOfFreedom *cd;
-    int i, lr_set;
 
     if (n < 1) 
       return;
@@ -1989,15 +1943,14 @@ namespace AMDiS {
     Element *el = list->getElement(0);
     int typ = list->getType(0);
     const DOFAdmin *admin = drv->getFeSpace()->getAdmin();
-
+    vector<DegreeOfFreedom> pd(35), cd(35);
     basFct->getLocalIndices(el, admin, pd);
+    basFct->getLocalIndices(el->getChild(0), admin, cd);
 
     /****************************************************************************/
     /*  values on child[0]                                                      */
     /****************************************************************************/
 
-    cd = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
     (*drv)[cd[3]] = ((*drv)[pd[5]]);
     (*drv)[cd[10]] = 
       (0.2734375*(*drv)[pd[0]] - 0.0390625*(*drv)[pd[1]]
@@ -2090,7 +2043,7 @@ namespace AMDiS {
     /*  values on child[1]                                                      */
     /****************************************************************************/
 
-    cd = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cd);
     if (typ == 0) {
       /****************************************************************************/
       /*  parent of el_type 0                                                     */
@@ -2201,12 +2154,12 @@ namespace AMDiS {
     /*   adjust neighbour values                                                */
     /****************************************************************************/
   
-    for (i = 1; i < n; i++) {
+    for (int i = 1; i < n; i++) {
       el = list->getElement(i);
       typ = list->getType(i);
       basFct->getLocalIndices(el, admin, pd);
 
-      lr_set = 0;
+      int lr_set = 0;
       if (list->getNeighbourElement(i, 0)  &&  list->getNeighbourNr(i, 0) < i)
 	lr_set = 1;
 
@@ -2219,7 +2172,7 @@ namespace AMDiS {
       /*  values on child[0]                                                      */
       /****************************************************************************/
 
-      cd = basFct->getLocalIndices(el->getChild(0), admin, NULL);
+      basFct->getLocalIndices(el->getChild(0), admin, cd);
 
       switch (lr_set) {
       case 1:
@@ -2387,7 +2340,7 @@ namespace AMDiS {
       /*  values on child[1]                                                      */
       /****************************************************************************/
 
-      cd = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+      basFct->getLocalIndices(el->getChild(1), admin, cd);
 
       if (typ == 0) {
 	switch (lr_set) {
@@ -2582,7 +2535,8 @@ namespace AMDiS {
 
     Element *el = list->getElement(0);
     const DOFAdmin *admin  = drv->getFeSpace()->getAdmin();
-    const DegreeOfFreedom *pdof = basFct->getLocalIndices(el, admin, NULL);
+    vector<DegreeOfFreedom> pdof;
+    basFct->getLocalIndices(el, admin, pdof);
 
     /****************************************************************************/
     /*  contributions of dofs located on child[0]                               */
@@ -2615,7 +2569,7 @@ namespace AMDiS {
 
     if (n > 1) {
       el = list->getElement(1);
-      pdof = basFct->getLocalIndices(el, admin, NULL);
+      basFct->getLocalIndices(el, admin, pdof);
       
       /****************************************************************************/
       /*  first set those values not effected by previous element                 */
@@ -2647,28 +2601,21 @@ namespace AMDiS {
     if (n < 1) 
       return;
 
-    Element *el;
-    const DegreeOfFreedom *cdof;
-    DegreeOfFreedom pdof[10], cdofi;
-    int i, lr_set;
-    int node0, n0;
-    const DOFAdmin *admin;
-
-    el = list->getElement(0);
-
-    admin = drv->getFeSpace()->getAdmin();
+    Element *el = list->getElement(0);
+    const DOFAdmin *admin = drv->getFeSpace()->getAdmin();
 
+    vector<DegreeOfFreedom> pdof(10), cdof(10);
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
 
-    node0 = drv->getFeSpace()->getMesh()->getNode(EDGE);
-    n0 = admin->getNumberOfPreDofs(EDGE);
+    int node0 = drv->getFeSpace()->getMesh()->getNode(EDGE);
+    int n0 = admin->getNumberOfPreDofs(EDGE);
+    int i, lr_set;
 
     /****************************************************************************/
     /*  values on child[0]                                                      */
     /****************************************************************************/
 
-    cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
     (*drv)[pdof[0]] += 
       (0.375*(*drv)[cdof[6]] + 0.125*(-(*drv)[cdof[8]] - (*drv)[cdof[9]]));
     (*drv)[pdof[1]] += 
@@ -2689,8 +2636,8 @@ namespace AMDiS {
     /*  values on child[1]                                                      */
     /****************************************************************************/
 
-    cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL);
-    cdofi = el->getChild(1)->getDof(node0 + 2, n0);
+    basFct->getLocalIndices(el->getChild(1), admin, cdof);
+    DegreeOfFreedom cdofi = el->getChild(1)->getDof(node0 + 2, n0);
 
     (*drv)[pdof[0]] += (-0.125*(*drv)[cdofi]);
     (*drv)[pdof[1]] += (0.375*(*drv)[cdofi]);
@@ -2717,7 +2664,7 @@ namespace AMDiS {
       /*  values on child[0]                                                      */
       /****************************************************************************/
 
-      cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
+      basFct->getLocalIndices(el->getChild(0), admin, cdof);
 
       switch (lr_set) {
       case 1:
@@ -2750,19 +2697,20 @@ namespace AMDiS {
     TEST_EXIT(drv->getFeSpace()->getBasisFcts())("No basis functions in fe_space!\n");
 
     int node, n0;
-    DegreeOfFreedom pdof[10], dof9;
+    DegreeOfFreedom dof9;
 
     if (n < 1) 
       return;
 
     Element *el = list->getElement(0);
     const DOFAdmin *admin = drv->getFeSpace()->getAdmin();
+    vector<DegreeOfFreedom> pdof(10), cdof(10);
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
   
     /****************************************************************************/
     /*  values on child[0]                                                      */
     /****************************************************************************/
-    const DegreeOfFreedom *cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
 
     (*drv)[pdof[0]] += 
       (0.0625*(-(*drv)[cdof[2]] + (*drv)[cdof[6]] - (*drv)[cdof[9]])
@@ -2791,7 +2739,7 @@ namespace AMDiS {
     /*  values on child[1]                                                      */
     /****************************************************************************/
 
-    cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cdof);
 
     (*drv)[pdof[0]] += 0.0625*(*drv)[cdof[6]] + 0.0625*(*drv)[cdof[9]];
     (*drv)[pdof[1]] += 0.3125*(*drv)[cdof[6]] - 0.0625*(*drv)[cdof[9]];
@@ -2811,11 +2759,11 @@ namespace AMDiS {
 
     el = list->getElement(1);
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
 
     /****************************************************************************/
     /*  values on neigh's child[0]                                              */
     /****************************************************************************/
-    cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
   
     (*drv)[pdof[0]] += 0.0625*((*drv)[cdof[6]] - (*drv)[cdof[9]]);
     (*drv)[pdof[1]] += 0.0625*((*drv)[cdof[6]] + (*drv)[cdof[9]]);
@@ -2853,23 +2801,22 @@ namespace AMDiS {
     TEST_EXIT(drv->getFeSpace())("No fe_space in dof_real_vec!\n");
     TEST_EXIT(drv->getFeSpace()->getBasisFcts())("No basis functions in fe_space!\n");
 
-    const Element *el;
-    int node, n0;
-    const DegreeOfFreedom *cdof;
-    DegreeOfFreedom pdof[10], dof9;
-    const DOFAdmin *admin;
+    if (n < 1) 
+      return;
 
-    if (n < 1) return;
-    el = list->getElement(0);
 
-    admin = drv->getFeSpace()->getAdmin();
+    int node, n0;
+    DegreeOfFreedom dof9;
 
+    const Element *el = list->getElement(0);
+    const DOFAdmin *admin = drv->getFeSpace()->getAdmin();
+    vector<DegreeOfFreedom> pdof(10), cdof(10);
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
   
     /****************************************************************************/
     /*  values on child[0]                                                      */
     /****************************************************************************/
-    cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
 
     (*drv)[pdof[0]] += 
       (0.0625*(-(*drv)[cdof[2]] + (*drv)[cdof[6]] - (*drv)[cdof[9]])
@@ -2894,7 +2841,7 @@ namespace AMDiS {
     /*  values on child[1]                                                      */
     /****************************************************************************/
 
-    cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cdof);
 
     (*drv)[pdof[0]] += 0.0625*(*drv)[cdof[6]] + 0.0625*(*drv)[cdof[9]];
     (*drv)[pdof[1]] += 0.3125*(*drv)[cdof[6]] - 0.0625*(*drv)[cdof[9]];
@@ -2913,12 +2860,12 @@ namespace AMDiS {
 
     el = list->getElement(1);
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
 
     /****************************************************************************/
     /*  values on neigh's child[0]                                              */
     /****************************************************************************/
-    cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-  
+ 
     (*drv)[pdof[0]] += 0.0625*((*drv)[cdof[6]] - (*drv)[cdof[9]]);
     (*drv)[pdof[1]] += 0.0625*((*drv)[cdof[6]] + (*drv)[cdof[9]]);
     (*drv)[pdof[3]] += -0.25*(*drv)[cdof[6]] - 0.12500*(*drv)[cdof[9]];
@@ -2958,18 +2905,18 @@ namespace AMDiS {
     if (n < 1) 
       return;
 
-    DegreeOfFreedom pd[20], cdi;
+    DegreeOfFreedom cdi;
     const Element *el = list->getElement(0);
     int typ = list->getType(0);
     const DOFAdmin *admin = drv->getFeSpace()->getAdmin();
+    vector<DegreeOfFreedom> pd(20), cd(20);
     basFct->getLocalIndices(el, admin, pd);
+    basFct->getLocalIndices(el->getChild(0), admin, cd);
 
     /****************************************************************************/
     /*  values on child[0]                                                      */
     /****************************************************************************/
 
-    const DegreeOfFreedom *cd = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
     (*drv)[pd[0]] += 
       (0.0625*(-(*drv)[cd[3]] + (*drv)[cd[12]] + (*drv)[cd[14]]
 	       + (*drv)[cd[16]] - (*drv)[cd[17]] - (*drv)[cd[18]]) 
@@ -3010,7 +2957,7 @@ namespace AMDiS {
     /*  values on child[1]                                                      */
     /****************************************************************************/
 
-    cd = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cd);
 
     if (typ == 0) {
       /****************************************************************************/
@@ -3077,7 +3024,7 @@ namespace AMDiS {
       /*  values on child[0]                                                      */
       /****************************************************************************/
 
-      cd = basFct->getLocalIndices(el->getChild(0), admin, NULL);
+      basFct->getLocalIndices(el->getChild(0), admin, cd);
       cdi = cd[16];
 
       switch (lr_set) {
@@ -3145,7 +3092,7 @@ namespace AMDiS {
       /*  values on child[1]                                                      */
       /****************************************************************************/
 
-      cd = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+      basFct->getLocalIndices(el->getChild(1), admin, cd);
 
       if (typ == 0) {
 	switch (lr_set) {
@@ -3212,18 +3159,16 @@ namespace AMDiS {
     if (n < 1) 
       return;
 
-    DegreeOfFreedom pdof[15];
     const Element *el = list->getElement(0);
     const DOFAdmin *admin = drv->getFeSpace()->getAdmin();
-
+    vector<DegreeOfFreedom> pdof(15), cdof(15);
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
 
     /****************************************************************************/
     /*  values on child[0]                                                      */
     /****************************************************************************/
 
-    const DegreeOfFreedom *cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
     (*drv)[pdof[0]] += 
       (0.2734375*(*drv)[cdof[3]]
        + 0.0390625*(-(*drv)[cdof[5]] - (*drv)[cdof[8]] - (*drv)[cdof[13]])
@@ -3266,7 +3211,7 @@ namespace AMDiS {
     /*  values on child[1]                                                      */
     /****************************************************************************/
   
-    cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cdof);
 
     (*drv)[pdof[0]] += 
       (0.0234375*(*drv)[cdof[6]] 
@@ -3299,15 +3244,13 @@ namespace AMDiS {
     /****************************************************************************/
 
     el = list->getElement(1);
-
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
 
     /****************************************************************************/
     /*  values on neighbour's child[0]                                          */
     /****************************************************************************/
 
-    cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
     (*drv)[pdof[0]] += 
       (0.0234375*((*drv)[cdof[6]] + (*drv)[cdof[12]])
        + 0.0390625*(-(*drv)[cdof[8]] - (*drv)[cdof[13]]));
@@ -3346,7 +3289,7 @@ namespace AMDiS {
     /*  values on neighbour's child[1]                                          */
     /****************************************************************************/
 
-    cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cdof);
 
     (*drv)[pdof[0]] += 0.0390625*(-(*drv)[cdof[12]] - (*drv)[cdof[13]]);
     (*drv)[pdof[1]] += -0.0390625*(*drv)[cdof[12]] + 0.0234375*(*drv)[cdof[13]];
@@ -3371,24 +3314,19 @@ namespace AMDiS {
     TEST_EXIT(drv->getFeSpace())("No fe_space in dof_real_vec!\n");
     TEST_EXIT(drv->getFeSpace()->getBasisFcts())("No basis functions in fe_space!\n");
 
-    const Element *el;
-    DegreeOfFreedom pdof[15];
-    const DegreeOfFreedom *cdof;
-    const DOFAdmin *admin;
-
-    if (n < 1) return;
-    el = list->getElement(0);
-
-    admin = drv->getFeSpace()->getAdmin();
+    if (n < 1) 
+      return;
 
+    const Element *el = list->getElement(0);
+    const DOFAdmin *admin = drv->getFeSpace()->getAdmin();
+    vector<DegreeOfFreedom> pdof(15), cdof(15);
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
 
     /****************************************************************************/
     /*  values on child[0]                                                      */
     /****************************************************************************/
 
-    cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
     (*drv)[pdof[0]] += 
       (0.2734375*(*drv)[cdof[3]]
        + 0.0390625*(-(*drv)[cdof[5]] - (*drv)[cdof[8]] - (*drv)[cdof[13]])
@@ -3431,7 +3369,7 @@ namespace AMDiS {
     /*  values on child[1]                                                      */
     /****************************************************************************/
   
-    cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cdof);
 
     (*drv)[pdof[0]] += 
       (0.0234375*(*drv)[cdof[6]] 
@@ -3464,15 +3402,13 @@ namespace AMDiS {
     /****************************************************************************/
 
     el = list->getElement(1);
-
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
 
     /****************************************************************************/
     /*  values on neighbour's child[0]                                          */
     /****************************************************************************/
 
-    cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
     (*drv)[pdof[0]] += 
       (0.0234375*((*drv)[cdof[6]] + (*drv)[cdof[12]])
        + 0.0390625*(-(*drv)[cdof[8]] - (*drv)[cdof[13]]));
@@ -3511,7 +3447,7 @@ namespace AMDiS {
     /*  values on neighbour's child[1]                                          */
     /****************************************************************************/
 
-    cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cdof);
 
     (*drv)[pdof[0]] += 0.0390625*(-(*drv)[cdof[12]] - (*drv)[cdof[13]]);
     (*drv)[pdof[1]] += -0.0390625*(*drv)[cdof[12]] + 0.0234375*(*drv)[cdof[13]];
@@ -3539,19 +3475,17 @@ namespace AMDiS {
     if (n < 1) 
       return;
 
-    DegreeOfFreedom pd[35];
+    vector<DegreeOfFreedom> pd(35), cd(35);
     const Element *el = list->getElement(0);
     int typ = list->getType(0);
     const DOFAdmin *admin = drv->getFeSpace()->getAdmin();
-
     basFct->getLocalIndices(el, admin, pd);
+    basFct->getLocalIndices(el->getChild(0), admin, cd);
 
     /****************************************************************************/
     /*  values on child[0]                                                      */
     /****************************************************************************/
 
-    const DegreeOfFreedom *cd = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
     (*drv)[pd[0]] += 
       (0.2734375*(*drv)[cd[10]]
        + 0.0390625*(-(*drv)[cd[12]] - (*drv)[cd[16]] - (*drv)[cd[19]]
@@ -3661,7 +3595,7 @@ namespace AMDiS {
     /*  values on child[1]                                                      */
     /****************************************************************************/
 
-    cd = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cd);
 
     if (typ == 0) {
       /****************************************************************************/
@@ -3785,6 +3719,7 @@ namespace AMDiS {
       el = list->getElement(i);
       typ = list->getType(i);
       basFct->getLocalIndices(el, admin, pd);
+      basFct->getLocalIndices(el->getChild(0), admin, cd);
 
       int lr_set = 0;
       if (list->getNeighbourElement(i,0) &&  list->getNeighbourNr(i,0) < i)
@@ -3799,8 +3734,6 @@ namespace AMDiS {
       /*  values on child[0]                                                      */
       /****************************************************************************/
 
-      cd = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
       switch (lr_set) {
       case 1:
 	(*drv)[pd[0]] += 
@@ -4013,7 +3946,7 @@ namespace AMDiS {
       /*  values on child[1]                                                      */
       /****************************************************************************/
 
-      cd = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+      basFct->getLocalIndices(el->getChild(1), admin, cd);
 
       if (typ == 0) {
 	switch (lr_set) {
@@ -4473,7 +4406,8 @@ namespace AMDiS {
     const DegreeOfFreedom **pds = el->getDof();
     const DegreeOfFreedom **cds = el->getChild(0)->getDof();
 
-    DegreeOfFreedom pd_o[20], cd, pd;
+    DegreeOfFreedom cd, pd;
+    vector<DegreeOfFreedom> pd_o(20);
     basFct->getLocalIndices(el, admin, pd_o);
     pd = (pds[0][0] < pds[1][0]) ? pds[node_e][n0_e] : pds[node_e][n0_e + 1];
     cd = cds[0][0] < cds[3][0] ? cds[node_e + 2][n0_e + 1] : cds[node_e + 2][n0_e];
@@ -4541,13 +4475,12 @@ namespace AMDiS {
 
     Element *el = list->getElement(0);
     const DOFAdmin *admin = drv->getFeSpace()->getAdmin();
-    DegreeOfFreedom pdof[15];
+    vector<DegreeOfFreedom> pdof(15), cdof(15);
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
 
     // values on child[0]
 
-    const DegreeOfFreedom *cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
     (*drv)[pdof[9]] = (*drv)[cdof[4]];
     (*drv)[pdof[10]] = (*drv)[cdof[2]];
     (*drv)[pdof[12]] = (*drv)[cdof[14]];
@@ -4555,7 +4488,7 @@ namespace AMDiS {
 
     // values on child[1]
   
-    cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cdof);
 
     (*drv)[pdof[11]] = (*drv)[cdof[7]];
     (*drv)[pdof[13]] = (*drv)[cdof[14]];
@@ -4568,17 +4501,16 @@ namespace AMDiS {
     el = list->getElement(1);
 
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
 
     // values on neighbour's child[0]
 
-    cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
     (*drv)[pdof[12]] = (*drv)[cdof[14]];
     (*drv)[pdof[14]] = (*drv)[cdof[7]];
 
     // values on neighbour's child[1]
 
-    cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cdof);
 
     (*drv)[pdof[13]] = (*drv)[cdof[14]];
   }
@@ -4596,13 +4528,12 @@ namespace AMDiS {
 
     const Element *el = list->getElement(0);
     const DOFAdmin *admin = drv->getFeSpace()->getAdmin();
-    DegreeOfFreedom pdof[15];
+    vector<DegreeOfFreedom> pdof(15), cdof(15);
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
 
     // values on child[0]
 
-    const DegreeOfFreedom *cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
     (*drv)[pdof[9]] = (*drv)[cdof[4]];
     (*drv)[pdof[10]] = (*drv)[cdof[2]];
     (*drv)[pdof[12]] = (*drv)[cdof[14]];
@@ -4610,7 +4541,7 @@ namespace AMDiS {
 
     // values on child[1]
   
-    cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cdof);
 
     (*drv)[pdof[11]] = (*drv)[cdof[7]];
     (*drv)[pdof[13]] = (*drv)[cdof[14]];
@@ -4623,17 +4554,16 @@ namespace AMDiS {
     el = list->getElement(1);
 
     basFct->getLocalIndices(el, admin, pdof);
+    basFct->getLocalIndices(el->getChild(0), admin, cdof);
 
     // values on neighbour's child[0]
 
-    cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
     (*drv)[pdof[12]] = (*drv)[cdof[14]];
     (*drv)[pdof[14]] = (*drv)[cdof[7]];
 
     // values on neighbour's child[1]
 
-    cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cdof);
 
     (*drv)[pdof[13]] = (*drv)[cdof[14]];
   }
@@ -4651,15 +4581,13 @@ namespace AMDiS {
 
     const Element* el = list->getElement(0);
     int typ = list->getType(0);
-
     const DOFAdmin *admin = drv->getFeSpace()->getAdmin();
-    DegreeOfFreedom pd[35];
+    vector<DegreeOfFreedom> pd(35), cd(35);
     basFct->getLocalIndices(el, admin, pd);
+    basFct->getLocalIndices(el->getChild(0), admin, cd);
 
     // values on child[0]
 
-    const DegreeOfFreedom *cd = basFct->getLocalIndices(el->getChild(0), admin, NULL);
-
     (*drv)[pd[4]] = (*drv)[cd[11]];
     (*drv)[pd[5]] = (*drv)[cd[3]];
     (*drv)[pd[28]] = (*drv)[cd[27]];
@@ -4670,7 +4598,7 @@ namespace AMDiS {
 
     // values on child[1]
 
-    cd = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+    basFct->getLocalIndices(el->getChild(1), admin, cd);
 
     if (typ == 0) {
       // parent of el_type 0 
@@ -4704,7 +4632,7 @@ namespace AMDiS {
       
       // values on child[0]
       
-      cd = basFct->getLocalIndices(el->getChild(0), admin, NULL);
+      basFct->getLocalIndices(el->getChild(0), admin, cd);
       
       switch (lr_set) {
       case 1:
@@ -4724,7 +4652,7 @@ namespace AMDiS {
 
       // values on child[1]
       
-      cd = basFct->getLocalIndices(el->getChild(1), admin, NULL);
+      basFct->getLocalIndices(el->getChild(1), admin, cd);
       
       if (typ == 0) {
 	switch (lr_set) {
diff --git a/AMDiS/src/Lagrange.h b/AMDiS/src/Lagrange.h
index 52b56780cd5e778b082f47aa98d072a0f6f8ec13..310f7ab90eca813c95206712e42e04e52442885c 100644
--- a/AMDiS/src/Lagrange.h
+++ b/AMDiS/src/Lagrange.h
@@ -73,11 +73,6 @@ namespace AMDiS {
     /// Returns the barycentric coordinates of the i-th basis function.
     DimVec<double> *getCoords(int i) const;
 
-    /// Implements BasisFunction::getDOFIndices
-    const DegreeOfFreedom* getDOFIndices(const Element*,
-					 const DOFAdmin&, 
-					 DegreeOfFreedom*) const;
-
     /// Implements BasisFunction::getBound
     void getBound(const ElInfo*, BoundaryType *) const;
 
@@ -116,13 +111,13 @@ namespace AMDiS {
     }
   
     /// Implements BasisFunction::getLocalIndices().
-    const DegreeOfFreedom *getLocalIndices(const Element *el,
-					   const DOFAdmin *admin,
-					   DegreeOfFreedom *dofs) const;
+    void getLocalIndices(const Element *el,
+			 const DOFAdmin *admin,
+			 std::vector<DegreeOfFreedom> &dofs) const;
 
     void getLocalDofPtrVec(const Element *el, 
 			   const DOFAdmin *admin,
-			   std::vector<const DegreeOfFreedom*>& vec) const;
+			   vector<const DegreeOfFreedom*>& vec) const;
 
     /// Implements BasisFunction::l2ScpFctBas
     void l2ScpFctBas(Quadrature* q,
@@ -154,7 +149,7 @@ namespace AMDiS {
     /// Sets used function pointers
     void setFunctionPointer();
 
-    /// Used by \ref getDOFIndices and \ref getVec
+    /// Used by \ref getVec
     int* orderOfPositionIndices(const Element* el, 
 				GeoIndex position, 
 				int positionIndex) const;
diff --git a/AMDiS/src/OpenMP.h b/AMDiS/src/OpenMP.h
new file mode 100644
index 0000000000000000000000000000000000000000..c1a512e6ec3c58a6bd24a7966d10d2665927eb4c
--- /dev/null
+++ b/AMDiS/src/OpenMP.h
@@ -0,0 +1,103 @@
+// ============================================================================
+// ==                                                                        ==
+// == AMDiS - Adaptive multidimensional simulations                          ==
+// ==                                                                        ==
+// ==  http://www.amdis-fem.org                                              ==
+// ==                                                                        ==
+// ============================================================================
+//
+// Software License for AMDiS
+//
+// Copyright (c) 2010 Dresden University of Technology 
+// All rights reserved.
+// Authors: Simon Vey, Thomas Witkowski et al.
+//
+// This file is part of AMDiS
+//
+// See also license.opensource.txt in the distribution.
+
+
+
+/** \file OpenMP.h */
+
+#ifndef AMDIS_OPENMP_H
+#define AMDIS_OPENMP_H
+
+#ifdef _OPENMP
+#include <omp.h>
+#include <vector>
+#endif
+
+namespace AMDiS {
+
+  using namespace std;
+  
+#ifdef _OPENMP
+
+  template<typename T>
+  class ThreadPrivate {
+  public:
+    ThreadPrivate()
+      : data(omp_get_max_threads())
+    {}
+
+    ThreadPrivate(T val)
+      : data(omp_get_max_threads(), val)
+    {}
+
+    inline T& get()
+    {
+#if (DEBUG != 0)
+      if (omp_get_thread_num() >= data.size()) {
+	cout << "Error in ThreadPrivate::get()!\n";
+	exit(0);
+      }
+#endif
+      return data[omp_get_thread_num()];
+    }
+
+    inline void set(T& val)
+    {
+#if (DEBUG != 0)
+      if (omp_get_thread_num() >= data.size()) {
+	cout << "Error in ThreadPrivate::set()!\n";
+	exit(0);
+      }
+#endif
+      data[omp_get_thread_num()] = val;
+    }
+
+  private:
+    vector<T> data;
+  };
+
+#else
+
+  template<typename T>
+  class ThreadPrivate {
+  public:
+    ThreadPrivate() {}
+
+    ThreadPrivate(T val)
+      : data(val)
+    {}
+
+    inline T& get()
+    {
+      return data;
+    }
+
+    inline void set(T& val)
+    {
+      data = val;
+    }
+
+  private:
+    T data;
+  };
+
+#endif
+
+}
+
+#endif
diff --git a/AMDiS/src/Operator.cc b/AMDiS/src/Operator.cc
index f0d5ca7cf749b9acf19ee144aab416c993b326cd..7f192f36160c13e9e3f0032ac69d5fb240c16385 100644
--- a/AMDiS/src/Operator.cc
+++ b/AMDiS/src/Operator.cc
@@ -19,70 +19,16 @@
 
 namespace AMDiS {
 
-  const Flag Operator::MATRIX_OPERATOR = 1;
-  const Flag Operator::VECTOR_OPERATOR = 2;
-
-
-  int Operator::getQuadratureDegree(int order, FirstOrderType firstOrderType) 
-  {
-    std::vector<OperatorTerm*>* terms = NULL;
-
-    switch(order) {
-    case 0:
-      terms = &zeroOrder;
-      break;
-    case 1:
-      if (firstOrderType == GRD_PHI)
-	terms = &firstOrderGrdPhi;
-      else 
-	terms = &firstOrderGrdPsi;
-      break;
-    case 2:
-      terms = &secondOrder;
-      break;
-    }
-
-    const BasisFunction *psi = rowFeSpace->getBasisFcts();
-    const BasisFunction *phi = colFeSpace->getBasisFcts();
-
-    int psiDegree = psi->getDegree();
-    int phiDegree = phi->getDegree();
-    int maxTermDegree = 0;
-
-    for (int i = 0; i < static_cast<int>(terms->size()); i++) {
-      OperatorTerm *term = (*terms)[i];
-      maxTermDegree = std::max(maxTermDegree, term->degree);
-    }
-   
-    return psiDegree + phiDegree - order + maxTermDegree;
-  }
-
-
-  Operator::Operator(Flag operatorType,
-		     const FiniteElemSpace *row,
-		     const FiniteElemSpace *col)
-  {
-    FUNCNAME("Operator::Operator()");
-
-    std::cout << "\n\n\n============== ERROR MESSAGE ===============\n";
-    std::cout << "You make use of the obsolete constructor Operator::Operator(Flag, FiniteElemSpace*, FiniteElemSpace*). Please\n";
-    std::cout << "make use of the new constructor Operator::Operatpr(FiniteElemSpace*, FiniteElemSpace*). So you have just to\n";
-    std::cout << "remove the MATRIX_OPERATOR/VECTOR_OPERATOR values from the constuctor call.\n\n\n";    
-
-    exit(0);
-  }
-
-
   Operator::Operator(const FiniteElemSpace *row, const FiniteElemSpace *col)
     : rowFeSpace(row), 
       colFeSpace(col ? col : row),
       fillFlag(Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | 
 	       Mesh::FILL_DET | Mesh::FILL_GRD_LAMBDA),
       needDualTraverse(false),
+      assembler(NULL),
       uhOld(NULL),
       optimized(true)
   {
-    assembler = NULL;
     secondOrder.resize(0);
     firstOrderGrdPsi.resize(0);
     firstOrderGrdPhi.resize(0);
@@ -104,10 +50,10 @@ namespace AMDiS {
 				  ElementMatrix& userMat, 
 				  double factor)
   {
-    if (!assembler)
+    if (!assembler.get())
       initAssembler(NULL, NULL, NULL, NULL);
 
-    assembler->calculateElementMatrix(elInfo, userMat, factor);
+    assembler.get()->calculateElementMatrix(elInfo, userMat, factor);
   }
 
 
@@ -117,13 +63,13 @@ namespace AMDiS {
 				  ElementMatrix& userMat, 
 				  double factor)
   {
-    if (!assembler)
+    if (!assembler.get())
       initAssembler(NULL, NULL, NULL, NULL);
 
-    assembler->calculateElementMatrix(rowElInfo, colElInfo, 
-				      smallElInfo, largeElInfo,
-				      rowColFeSpaceEqual,
-				      userMat, factor);
+    assembler.get()->calculateElementMatrix(rowElInfo, colElInfo, 
+					    smallElInfo, largeElInfo,
+					    rowColFeSpaceEqual,
+					    userMat, factor);
   }
 
 
@@ -131,10 +77,10 @@ namespace AMDiS {
 				  ElementVector& userVec, 
 				  double factor)
   {
-    if (!assembler)
+    if (!assembler.get())
       initAssembler(NULL, NULL, NULL, NULL);
 
-    assembler->calculateElementVector(elInfo, userVec, factor);
+    assembler.get()->calculateElementVector(elInfo, userVec, factor);
   }
 
 
@@ -143,12 +89,12 @@ namespace AMDiS {
 				  ElementVector& userVec,
 				  double factor)
   {
-    if (!assembler)
+    if (!assembler.get())
       initAssembler(NULL, NULL, NULL, NULL);
 
-    assembler->calculateElementVector(mainElInfo, auxElInfo, 
-				      smallElInfo, largeElInfo,
-				      userVec, factor);
+    assembler.get()->calculateElementVector(mainElInfo, auxElInfo, 
+					    smallElInfo, largeElInfo,
+					    userVec, factor);
   }
 
 
@@ -157,34 +103,74 @@ namespace AMDiS {
 			       Quadrature *quad1GrdPhi,
 			       Quadrature *quad0) 
   {    
-    if (optimized)
-      assembler = new OptimizedAssembler(this, quad2, quad1GrdPsi, quad1GrdPhi, quad0,
-					 rowFeSpace, colFeSpace);
-    else
-      assembler = new StandardAssembler(this, quad2, quad1GrdPsi, quad1GrdPhi, quad0,
-					rowFeSpace, colFeSpace);	
+    if (optimized) {
+      Assembler *aptr = 
+	new OptimizedAssembler(this, quad2, quad1GrdPsi, quad1GrdPhi, 
+			       quad0, rowFeSpace, colFeSpace);
+      assembler.set(aptr);
+    } else {
+      Assembler *aptr = 
+	new StandardAssembler(this, quad2, quad1GrdPsi, quad1GrdPhi, 
+			      quad0, rowFeSpace, colFeSpace);
+      assembler.set(aptr);
+    }
+  }
+
+
+  int Operator::getQuadratureDegree(int order, FirstOrderType firstOrderType) 
+  {
+    std::vector<OperatorTerm*>* terms = NULL;
+
+    switch(order) {
+    case 0:
+      terms = &zeroOrder;
+      break;
+    case 1:
+      if (firstOrderType == GRD_PHI)
+	terms = &firstOrderGrdPhi;
+      else 
+	terms = &firstOrderGrdPsi;
+      break;
+    case 2:
+      terms = &secondOrder;
+      break;
+    }
+
+    const BasisFunction *psi = rowFeSpace->getBasisFcts();
+    const BasisFunction *phi = colFeSpace->getBasisFcts();
+
+    int psiDegree = psi->getDegree();
+    int phiDegree = phi->getDegree();
+    int maxTermDegree = 0;
+
+    for (int i = 0; i < static_cast<int>(terms->size()); i++) {
+      OperatorTerm *term = (*terms)[i];
+      maxTermDegree = std::max(maxTermDegree, term->degree);
+    }
+   
+    return psiDegree + phiDegree - order + maxTermDegree;
   }
 
 
   void Operator::finishAssembling()
   {
-    if (assembler)
-      assembler->finishAssembling();
+    if (assembler.get())
+      assembler.get()->finishAssembling();
   }
 
 
-  Assembler *Operator::getAssembler() 
+  Assembler* Operator::getAssembler() 
   {
-    if (!assembler)
+    if (!assembler.get())
       initAssembler(NULL, NULL, NULL, NULL);    
 
-    return assembler;
+    return assembler.get();
   }
 
 
   void Operator::setAssembler(Assembler *a)
   {
-    assembler = a; 
+    assembler.set(a);
   }
 
 
diff --git a/AMDiS/src/Operator.h b/AMDiS/src/Operator.h
index 8af1747e1264bb70ed0208aa6b4e8a32838e6bfe..068265c6bb9351e3bc9bb8dd8bc63eed28f06b50 100644
--- a/AMDiS/src/Operator.h
+++ b/AMDiS/src/Operator.h
@@ -53,12 +53,6 @@ namespace AMDiS {
   class Operator
   {
   public:
-    /// Obsolete consructor. Calling this constructor yields an error. Will be removed
-    /// in on of the next revisions.
-    Operator(Flag operatorType,
-	     const FiniteElemSpace *rowFeSpace,
-	     const FiniteElemSpace *colFeSpace = NULL);
-
     /// Constructs an empty Operator of type operatorType for the given FiniteElemSpace.
     Operator(const FiniteElemSpace *rowFeSpace,
 	     const FiniteElemSpace *colFeSpace = NULL);
@@ -94,8 +88,7 @@ namespace AMDiS {
     void addTerm(ZeroOrderTerm *term);
 
     /// Adds a FirstOrderTerm to the Operator
-    void addTerm(FirstOrderTerm *term,
-      FirstOrderType type);
+    void addTerm(FirstOrderTerm *term, FirstOrderType type);
 
     /// Adds a SecondOrderTerm to the Operator
     void addTerm(SecondOrderTerm *term);
@@ -315,13 +308,6 @@ namespace AMDiS {
       return zeroOrder.size() != 0;
     }
 
-  public:
-    /// Constant type flag for matrix operators. Obsolete, will be removed!
-    static const Flag MATRIX_OPERATOR;
-
-    /// Constant type flag for vector operators. Obsolete, will be removed!
-    static const Flag VECTOR_OPERATOR;
-
   protected:
     /// FiniteElemSpace for matrix rows and element vector
     const FiniteElemSpace *rowFeSpace;
@@ -347,7 +333,7 @@ namespace AMDiS {
     /// Calculates the element matrix and/or the element vector. It is
     /// created especially for this Operator, when \ref getElementMatrix()
     /// or \ref getElementVector is called for the first time.
-    Assembler* assembler;
+    ThreadPrivate<Assembler*> assembler;
 
     /// List of all second order terms
     vector<OperatorTerm*> secondOrder;
diff --git a/AMDiS/src/ProblemStat.cc b/AMDiS/src/ProblemStat.cc
index fc3a905813a369c19bd2f95858078ddeb0e1b2a8..ece5db9b64a2dc3d5422a4e1a52eb9c1d8585dbc 100644
--- a/AMDiS/src/ProblemStat.cc
+++ b/AMDiS/src/ProblemStat.cc
@@ -1247,9 +1247,8 @@ namespace AMDiS {
       }          
     } 
 
-    OperatorPos opPos = {i, j, factor, estFactor, Operator::MATRIX_OPERATOR};
+    OperatorPos opPos = {i, j, factor, estFactor};
     operators[op].push_back(opPos);
-    opFlags[op].setFlag(Operator::MATRIX_OPERATOR);
   }
 
 
@@ -1284,9 +1283,8 @@ namespace AMDiS {
       }    
     }
 
-    OperatorPos opPos = {i, -1, factor, estFactor, Operator::VECTOR_OPERATOR};
+    OperatorPos opPos = {i, -1, factor, estFactor};
     operators[op].push_back(opPos);
-    opFlags[op].setFlag(Operator::VECTOR_OPERATOR);
   }
 
 
diff --git a/AMDiS/src/ProblemStat.h b/AMDiS/src/ProblemStat.h
index 4fd293e238cca5284d6d18df6392a54240f6614d..707e3b87dbefa97c16ca25e9ccc8e8b5d35cb046 100644
--- a/AMDiS/src/ProblemStat.h
+++ b/AMDiS/src/ProblemStat.h
@@ -45,7 +45,6 @@ namespace AMDiS {
   {
     int row, col;
     double *factor, *estFactor;
-    Flag operatorType;
   };
 
 
@@ -656,8 +655,6 @@ namespace AMDiS {
     bool writeAsmInfo;
 
     map<Operator*, vector<OperatorPos> > operators;
-
-    map<Operator*, Flag> opFlags;
   };
 
 #ifndef HAVE_PARALLEL_DOMAIN_AMDIS
diff --git a/AMDiS/src/Quadrature.cc b/AMDiS/src/Quadrature.cc
index c8f72b5675875a871d6c191221bf36103cbb3347..53169448ff78c6960a9c99dd9c27c00326c5bc59 100644
--- a/AMDiS/src/Quadrature.cc
+++ b/AMDiS/src/Quadrature.cc
@@ -1463,9 +1463,9 @@ namespace AMDiS {
 
     double result = 0.0;
     // calculate weighted sum over all quadrature-points
-    for (int i = 0; i < n_points; i++) {
+    for (int i = 0; i < n_points; i++)
       result += w[i] * (*f)((*lambda)[i]);
-    }
+
     return result;
   }
 
@@ -1476,31 +1476,35 @@ namespace AMDiS {
   {
     FUNCNAME("FastQuadrature::provideFastQuuadrature()");
 
-    FastQuadrature *quad_fast;
-
-    list<FastQuadrature*>::iterator fast = fastQuadList.begin();
-           
-    for (fast = fastQuadList.begin(); fast != fastQuadList.end(); fast++)
-      if ((*fast)->basisFunctions == bas_fcts && (*fast)->quadrature == &quad)  
-	break;
-    
-    if (fast != fastQuadList.end() && ((*fast)->init_flag & init_flag) == init_flag) {
-      quad_fast = *fast;
-    } else {
-      if (fast == fastQuadList.end()) {
-	quad_fast = 
-	  new FastQuadrature(const_cast<BasisFunction*>(bas_fcts), 
-			     const_cast<Quadrature*>(&quad), 0);
-	
-	fastQuadList.push_front(quad_fast);
-	
-	max_points = std::max(max_points, quad.getNumPoints());
+    FastQuadrature *quad_fast = NULL;
+
+#pragma omp critical
+    {
+      list<FastQuadrature*>::iterator fast = fastQuadList.begin(); 
+      for (; fast != fastQuadList.end(); fast++)
+	if ((*fast)->basisFunctions == bas_fcts && 
+	    (*fast)->quadrature == &quad)  
+	  break;
+      
+      if (fast != fastQuadList.end() && 
+	  ((*fast)->init_flag & init_flag) == init_flag) {
+	quad_fast = *fast;
       } else {
-	quad_fast = (*fast);
+	if (fast == fastQuadList.end()) {
+	  quad_fast = 
+	    new FastQuadrature(const_cast<BasisFunction*>(bas_fcts), 
+			       const_cast<Quadrature*>(&quad), 0);
+	  
+	  fastQuadList.push_front(quad_fast);
+	  
+	  max_points = std::max(max_points, quad.getNumPoints());
+	} else {
+	  quad_fast = (*fast);
+	}
       }
+      
+      quad_fast->init(init_flag);  
     }
-    
-    quad_fast->init(init_flag);  
 
     return quad_fast;
   }
diff --git a/AMDiS/src/SecondOrderAssembler.cc b/AMDiS/src/SecondOrderAssembler.cc
index 9dd029e05bcd89121c7049f90a58113b6884e271..9b446d0ffb9e5d563b419c6099f76133ab3f0905 100644
--- a/AMDiS/src/SecondOrderAssembler.cc
+++ b/AMDiS/src/SecondOrderAssembler.cc
@@ -22,8 +22,12 @@
 
 namespace AMDiS {
 
-  std::vector<SubAssembler*> SecondOrderAssembler::optimizedSubAssemblers; 
-  std::vector<SubAssembler*> SecondOrderAssembler::standardSubAssemblers;
+  ThreadPrivate<vector<SubAssembler*> > 
+  SecondOrderAssembler::optimizedSubAssemblers;
+  
+  ThreadPrivate<vector<SubAssembler*> > 
+  SecondOrderAssembler::standardSubAssemblers;
+
 
   SecondOrderAssembler::SecondOrderAssembler(Operator *op,
 					     Assembler *assembler,
@@ -44,23 +48,21 @@ namespace AMDiS {
 
     SecondOrderAssembler *newAssembler;
 
-    std::vector<SubAssembler*> *subAssemblers =
-      optimized ?
-      &optimizedSubAssemblers :
-      &standardSubAssemblers;
+    vector<SubAssembler*> &subAssemblers =
+      optimized ? optimizedSubAssemblers.get() : standardSubAssemblers.get();
 
-    std::vector<OperatorTerm*> opTerms = op->zeroOrder;
+    vector<OperatorTerm*> opTerms = op->zeroOrder;
 
     sort(opTerms.begin(), opTerms.end());
 
     // check if a new assembler is needed
-    for (unsigned int i = 0; i < subAssemblers->size(); i++) {
-      std::vector<OperatorTerm*> assTerms = *((*subAssemblers)[i]->getTerms());
+    for (unsigned int i = 0; i < subAssemblers.size(); i++) {
+      vector<OperatorTerm*> assTerms = *(subAssemblers[i]->getTerms());
     
       sort(assTerms.begin(), assTerms.end());
 
-      if (opTerms == assTerms && (*subAssemblers)[i]->getQuadrature() == quad)	
-	return dynamic_cast<SecondOrderAssembler*>((*subAssemblers)[i]);
+      if (opTerms == assTerms && subAssemblers[i]->getQuadrature() == quad)	
+	return dynamic_cast<SecondOrderAssembler*>(subAssemblers[i]);
     }
 
     // check if all terms are pw_const
@@ -83,7 +85,7 @@ namespace AMDiS {
       }
     }
 
-    subAssemblers->push_back(newAssembler);
+    subAssemblers.push_back(newAssembler);
 
     return newAssembler;
   }
@@ -286,7 +288,7 @@ namespace AMDiS {
 
     int nPoints = quadrature->getNumPoints();
 
-    std::vector<mtl::dense2D<double> > LALt(nPoints);
+    vector<mtl::dense2D<double> > LALt(nPoints);
     for (int iq = 0; iq < nPoints; iq++) {
       LALt[iq].change_dim(dim + 1, dim + 1);
       LALt[iq] = 0.0;
diff --git a/AMDiS/src/SecondOrderAssembler.h b/AMDiS/src/SecondOrderAssembler.h
index 8fc6bc6ed26c9eb9b43284b914ace191d74eb61e..140deae3ab8410b15fb2bfe6c6889a09a5b12388 100644
--- a/AMDiS/src/SecondOrderAssembler.h
+++ b/AMDiS/src/SecondOrderAssembler.h
@@ -65,10 +65,10 @@ namespace AMDiS {
 
   protected:
     /// List of all yet created optimized second order assemblers.
-    static vector<SubAssembler*> optimizedSubAssemblers;
+    static ThreadPrivate<vector<SubAssembler*> > optimizedSubAssemblers;
 
     /// List of all yet created standard second order assemblers.
-    static vector<SubAssembler*> standardSubAssemblers;
+    static ThreadPrivate<vector<SubAssembler*> > standardSubAssemblers;
   };
 
 
diff --git a/AMDiS/src/SubAssembler.cc b/AMDiS/src/SubAssembler.cc
index 92ab6acfb7e7a95e5ebb309a503d3b6dc2f1ef8e..4a596bb012eb87ff660db6a5fa153d3ecf117f25 100644
--- a/AMDiS/src/SubAssembler.cc
+++ b/AMDiS/src/SubAssembler.cc
@@ -93,8 +93,11 @@ namespace AMDiS {
     if (!quadFast) {
       quadFast = FastQuadrature::provideFastQuadrature(psi, *quadrature, updateFlag);
     } else {
-      if (!quadFast->initialized(updateFlag))
-	quadFast->init(updateFlag);
+#pragma omp critical 
+      {
+	if (!quadFast->initialized(updateFlag))
+	  quadFast->init(updateFlag);
+      }
     }
 
     return quadFast;
diff --git a/AMDiS/src/UmfPackSolver.h b/AMDiS/src/UmfPackSolver.h
index 74461e3aa6fd6a35b1753c74281d9034bc43222f..3a6643a635c095893b0df7d535bd682182de78e1 100644
--- a/AMDiS/src/UmfPackSolver.h
+++ b/AMDiS/src/UmfPackSolver.h
@@ -92,7 +92,7 @@ namespace AMDiS {
         double residual = two_norm(r);
         oem.setResidual(residual);
         oem.setErrorCode(code);
-        std::cout << "UmfPackSolver: ||b-Ax|| = " << residual << "\n";
+        MSG("UmfPackSolver: ||b-Ax|| = %e\n", residual);
 	TEST_EXIT(residual <= oem.getTolerance())("Tolerance tol = %e could not be reached!\n Set tolerance by '->solver->tolerance:' \n", oem.getTolerance());	
       }
       return code;
diff --git a/AMDiS/src/ZeroOrderAssembler.cc b/AMDiS/src/ZeroOrderAssembler.cc
index a83b09023074249c389fe7c38f6e8ddc3e67ec47..853724edd42a4eef925501ee61b737c06dfbb610 100644
--- a/AMDiS/src/ZeroOrderAssembler.cc
+++ b/AMDiS/src/ZeroOrderAssembler.cc
@@ -22,8 +22,12 @@
 
 namespace AMDiS {
 
-  std::vector<SubAssembler*> ZeroOrderAssembler::optimizedSubAssemblers;
-  std::vector<SubAssembler*> ZeroOrderAssembler::standardSubAssemblers;
+  ThreadPrivate<vector<SubAssembler*> > 
+  ZeroOrderAssembler::optimizedSubAssemblers;
+  
+  ThreadPrivate<vector<SubAssembler*> >
+  ZeroOrderAssembler::standardSubAssemblers;
+
 
   ZeroOrderAssembler::ZeroOrderAssembler(Operator *op,
 					 Assembler *assembler,
@@ -44,22 +48,22 @@ namespace AMDiS {
 
     ZeroOrderAssembler *newAssembler;
 
-    std::vector<SubAssembler*> *subAssemblers =
-      optimized ? &optimizedSubAssemblers : &standardSubAssemblers;
+    vector<SubAssembler*> subAssemblers =
+      optimized ? optimizedSubAssemblers.get() : standardSubAssemblers.get();
 
-    std::vector<OperatorTerm*> opTerms = op->zeroOrder;
+    vector<OperatorTerm*> opTerms = op->zeroOrder;
 
     sort(opTerms.begin(), opTerms.end());
 
     // check if a new assembler is needed
     if (quad) {
-      for (int i = 0; i < static_cast<int>(subAssemblers->size()); i++) {
-	std::vector<OperatorTerm*> assTerms = *((*subAssemblers)[i]->getTerms());
+      for (int i = 0; i < static_cast<int>(subAssemblers.size()); i++) {
+	vector<OperatorTerm*> assTerms = *(subAssemblers[i]->getTerms());
 
 	sort(assTerms.begin(), assTerms.end());
 
-	if (opTerms == assTerms && (*subAssemblers)[i]->getQuadrature() == quad)
-	  return dynamic_cast<ZeroOrderAssembler*>((*subAssemblers)[i]);
+	if (opTerms == assTerms && subAssemblers[i]->getQuadrature() == quad)
+	  return dynamic_cast<ZeroOrderAssembler*>(subAssemblers[i]);
       }
     }
  
@@ -82,7 +86,8 @@ namespace AMDiS {
      	newAssembler = new FastQuadZOA(op, assembler, quad);      
     }
 
-    subAssemblers->push_back(newAssembler);
+    subAssemblers.push_back(newAssembler);
+
     return newAssembler;
   }
 
@@ -102,9 +107,9 @@ namespace AMDiS {
 
     int nPoints = quadrature->getNumPoints();
     ElementVector c(nPoints, 0.0);
-    std::vector<double> phival(nCol);
+    vector<double> phival(nCol);
 
-    for (std::vector<OperatorTerm*>::iterator termIt = terms.begin(); 
+    for (vector<OperatorTerm*>::iterator termIt = terms.begin(); 
 	 termIt != terms.end(); ++termIt)
       (static_cast<ZeroOrderTerm*>((*termIt)))->getC(elInfo, nPoints, c);
 
@@ -151,7 +156,7 @@ namespace AMDiS {
     int nPoints = quadrature->getNumPoints();
     ElementVector c(nPoints, 0.0);
 
-    std::vector<OperatorTerm*>::iterator termIt;
+    vector<OperatorTerm*>::iterator termIt;
     for (termIt = terms.begin(); termIt != terms.end(); ++termIt)
       (static_cast<ZeroOrderTerm*>((*termIt)))->getC(elInfo, nPoints, c);
 
@@ -190,7 +195,7 @@ namespace AMDiS {
       c.change_dim(nPoints);
     c = 0.0;
 
-    for (std::vector<OperatorTerm*>::iterator termIt = terms.begin(); 
+    for (vector<OperatorTerm*>::iterator termIt = terms.begin(); 
 	 termIt != terms.end(); ++termIt)
       (static_cast<ZeroOrderTerm*>((*termIt)))->getC(elInfo, nPoints, c);
 
@@ -240,7 +245,7 @@ namespace AMDiS {
     }
 
     ElementVector c(nPoints, 0.0);
-    std::vector<OperatorTerm*>::iterator termIt;
+    vector<OperatorTerm*>::iterator termIt;
     for (termIt = terms.begin(); termIt != terms.end(); ++termIt)
       (static_cast<ZeroOrderTerm*>((*termIt)))->getC(elInfo, nPoints, c);
 
@@ -313,7 +318,7 @@ namespace AMDiS {
       firstCall = false;      
     }
 
-    std::vector<OperatorTerm*>::iterator termIt;
+    vector<OperatorTerm*>::iterator termIt;
 
     ElementVector c(1, 0.0);
     for (termIt = terms.begin(); termIt != terms.end(); ++termIt)
diff --git a/AMDiS/src/ZeroOrderAssembler.h b/AMDiS/src/ZeroOrderAssembler.h
index 703479fadaa88d2e7392615e3de2fb5629d5de74..43970c64b54835acb8dc964051f9bc6a3ef01d23 100644
--- a/AMDiS/src/ZeroOrderAssembler.h
+++ b/AMDiS/src/ZeroOrderAssembler.h
@@ -29,6 +29,8 @@
 
 namespace AMDiS {
 
+  using namespace std;
+
   /**
    * \ingroup Assembler
    * 
@@ -63,10 +65,10 @@ namespace AMDiS {
 
   protected:
     /// List of all yet created optimized SubAssembler objects.
-    static std::vector<SubAssembler*> optimizedSubAssemblers;
+    static ThreadPrivate<vector<SubAssembler*> > optimizedSubAssemblers;
 
     /// List of all yet created standard SubAssembler objects.
-    static std::vector<SubAssembler*> standardSubAssemblers;
+    static ThreadPrivate<vector<SubAssembler*> > standardSubAssemblers;
   };
 
 
diff --git a/AMDiS/src/compositeFEM/CompositeFEMMethods.cc b/AMDiS/src/compositeFEM/CompositeFEMMethods.cc
index a6df47aa38489034dcc3d6d0df88b1e9a22ee534..5ea0c82adb7ccb1323ce4b72b6cfb8c95c746052 100644
--- a/AMDiS/src/compositeFEM/CompositeFEMMethods.cc
+++ b/AMDiS/src/compositeFEM/CompositeFEMMethods.cc
@@ -41,6 +41,7 @@ void CompositeFEMMethods::setPosLsToVal(DOFVector<double> *dof,
   }
 }
 
+
 void CompositeFEMMethods::setPosLsToFct(DOFVector<double> *dof,
 					const AbstractFunction<double, WorldVector<double> > *fct,
 					const DOFVector<double> *lsFct_dof)
@@ -48,12 +49,12 @@ void CompositeFEMMethods::setPosLsToFct(DOFVector<double> *dof,
   const BasisFunction *basisFcts = dof->getFeSpace()->getBasisFcts();
   const DOFAdmin *admin = dof->getFeSpace()->getAdmin();
   const int dim = dof->getFeSpace()->getMesh()->getDim();
-  const DegreeOfFreedom *locInd;
 
   TraverseStack stack;
   ElInfo *elInfo = stack.traverseFirst(dof->getFeSpace()->getMesh(), -1, 
 				       Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
   ElementVector locVec(basisFcts->getNumber());
+  std::vector<DegreeOfFreedom> locInd(basisFcts->getNumber());
 
   while (elInfo) {
     const Element *el = elInfo->getElement();
@@ -62,7 +63,7 @@ void CompositeFEMMethods::setPosLsToFct(DOFVector<double> *dof,
     lsFct_dof->getLocalVector(el, locVec);
 
     // Get dof indices of vertices.
-    locInd = basisFcts->getLocalIndices(el, admin, NULL);
+    basisFcts->getLocalIndices(el, admin, locInd);
 
     for (int i = 0; i <= dim; i++) {
       // Is vertex in domain with positive level set function values ?
@@ -74,6 +75,7 @@ void CompositeFEMMethods::setPosLsToFct(DOFVector<double> *dof,
   }
 }
 
+
 void CompositeFEMMethods::printBoundaryElements(const std::string fn_str,
 						ElementLevelSet *elLS,
 						FiniteElemSpace *feSpace)
@@ -95,7 +97,7 @@ void CompositeFEMMethods::printBoundaryElements(const std::string fn_str,
   WorldVector<double> coord;
 
   const int nBasFcts = feSpace->getBasisFcts()->getNumber();
-  DegreeOfFreedom *locInd = new DegreeOfFreedom[nBasFcts];
+  std::vector<DegreeOfFreedom> locInd(nBasFcts);
 
   ElInfo *loc_elInfo = stack.traverseFirst(feSpace->getMesh(),
 					   -1, 
@@ -105,10 +107,9 @@ void CompositeFEMMethods::printBoundaryElements(const std::string fn_str,
   while (loc_elInfo) {
 
     // Get local indices of vertices.
-    feSpace->getBasisFcts()->getLocalIndices(
-	  const_cast<Element *>(loc_elInfo->getElement()),
-	  const_cast<DOFAdmin *>(feSpace->getAdmin()),
-	  locInd); 
+    feSpace->getBasisFcts()->getLocalIndices(const_cast<Element *>(loc_elInfo->getElement()),
+					     const_cast<DOFAdmin *>(feSpace->getAdmin()),
+					     locInd);
 
     // Get element status.
     elStatus = elLS->createElementLevelSet(loc_elInfo);
@@ -140,8 +141,6 @@ void CompositeFEMMethods::printBoundaryElements(const std::string fn_str,
 
   }  // end of: mesh traverse
 
-  delete [] locInd;
-
   boundaryOut << "\nNumber of boundary elements: \t" << boundEl_cntr << "\n";
 
   boundaryOut.close();
diff --git a/AMDiS/src/compositeFEM/CompositeFEMOperator.cc b/AMDiS/src/compositeFEM/CompositeFEMOperator.cc
index cb572ba3d7d335f90e4e01ea68afd7a7e615f715..2c8c32e7a00a289c9ec59638cd551dff5e4ee430 100644
--- a/AMDiS/src/compositeFEM/CompositeFEMOperator.cc
+++ b/AMDiS/src/compositeFEM/CompositeFEMOperator.cc
@@ -119,9 +119,9 @@ void CompositeFEMOperator::getElementMatrix(const ElInfo *elInfo,
 			   subElementAssembler->getNCol());
   set_to_zero(subPolMat2);
 
-  if (!assembler) {
-    assembler =
-      new StandardAssembler(this, NULL, NULL, NULL, NULL, rowFeSpace, colFeSpace);
+  if (!assembler.get()) {
+    Assembler *aptr = new StandardAssembler(this, NULL, NULL, NULL, NULL, rowFeSpace, colFeSpace);
+    assembler.set(aptr);
   }
 
   if (elLS->getLevelSetDomain() == 
@@ -132,7 +132,7 @@ void CompositeFEMOperator::getElementMatrix(const ElInfo *elInfo,
     elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_INTERIOR);
   }
 
-  assembler->calculateElementMatrix(elInfo, elMat, 1.0);
+  assembler.get()->calculateElementMatrix(elInfo, elMat, 1.0);
   subElementAssembler->getSubPolytopeMatrix(subPolytope,
 					    subElementAssembler,
 					    elInfo,
@@ -244,17 +244,16 @@ void CompositeFEMOperator::getElementVector(const ElInfo *elInfo,
 					    elInfo,
 					    subPolVec1);  
 
-  /**
-   * Integration on second subpolytope produced by the intersection.
-   */
+  // Integration on second subpolytope produced by the intersection.
   ElementVector elVec(subElementAssembler->getNRow());
   set_to_zero(elVec);
   ElementVector subPolVec2(subElementAssembler->getNRow());
   set_to_zero(subPolVec2);
 
-  if (!assembler)
-    assembler = 
-      new StandardAssembler(this, NULL, NULL, NULL, NULL, rowFeSpace, colFeSpace);
+  if (!assembler.get()) {
+    Assembler *aptr = new StandardAssembler(this, NULL, NULL, NULL, NULL, rowFeSpace, colFeSpace);
+    assembler.set(aptr);      
+  }
 
   if (elLS->getLevelSetDomain() == 
       ElementLevelSet::LEVEL_SET_INTERIOR) {
@@ -263,7 +262,7 @@ void CompositeFEMOperator::getElementVector(const ElInfo *elInfo,
     elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_INTERIOR);
   }
 
-  assembler->calculateElementVector(elInfo, elVec, 1.0);
+  assembler.get()->calculateElementVector(elInfo, elVec, 1.0);
   subElementAssembler->getSubPolytopeVector(subPolytope,
 					    subElementAssembler,
 					    elInfo,
diff --git a/AMDiS/src/compositeFEM/CompositeFEMOperator.h b/AMDiS/src/compositeFEM/CompositeFEMOperator.h
index b7346873487b10b868bfa43fd303ec4c817f0e37..a1330d29fd0c1c9899833a0c2af584db7f078658 100644
--- a/AMDiS/src/compositeFEM/CompositeFEMOperator.h
+++ b/AMDiS/src/compositeFEM/CompositeFEMOperator.h
@@ -55,11 +55,10 @@ class CompositeFEMOperator : public Operator
 {
 public:
   /// Constructor.
-  CompositeFEMOperator(Flag operatorType_,
-		       ElementLevelSet *elLS_,
+  CompositeFEMOperator(ElementLevelSet *elLS_,
 		       const FiniteElemSpace *rowFeSpace_,
 		       const FiniteElemSpace *colFeSpace_ = NULL)
-    : Operator(operatorType_, rowFeSpace_, colFeSpace_),
+    : Operator(rowFeSpace_, colFeSpace_),
       elLS(elLS_),
       subElementAssembler(NULL),
       elStatus(ElementLevelSet::LEVEL_SET_UNDEFINED)
diff --git a/AMDiS/src/compositeFEM/PenaltyOperator.h b/AMDiS/src/compositeFEM/PenaltyOperator.h
index 79b88c4a3abac9830f88b5455ac098915ef523aa..da31a3ee6b44ac998fd562c53bd2eab34ee2f157 100644
--- a/AMDiS/src/compositeFEM/PenaltyOperator.h
+++ b/AMDiS/src/compositeFEM/PenaltyOperator.h
@@ -41,13 +41,12 @@ class PenaltyOperator : public Operator
 {
 public:
   /// Constructor.
-  PenaltyOperator(Flag operatorType_,
-		  ElementLevelSet *elLS_,
+  PenaltyOperator(ElementLevelSet *elLS_,
 		  double factor_,
 		  bool penaltyCoeffFlag_,
 		  FiniteElemSpace *rowFeSpace_,
 		  FiniteElemSpace *colFeSpace_ = NULL)
-    : Operator(operatorType_, rowFeSpace_, colFeSpace_),
+    : Operator(rowFeSpace_, colFeSpace_),
       elLS(elLS_),
       elStatus(ElementLevelSet::LEVEL_SET_UNDEFINED),
       factor(factor_),
diff --git a/AMDiS/src/io/DataCollector.h b/AMDiS/src/io/DataCollector.h
index c25fc7982ca87bc11417e5fad2f89822526baf4e..e468b95b1f4cc07a1b069348f743d58a9b37639c 100644
--- a/AMDiS/src/io/DataCollector.h
+++ b/AMDiS/src/io/DataCollector.h
@@ -181,10 +181,8 @@ namespace AMDiS {
     /// Stores for each simplex the interpolation points.
     std::vector<std::vector<int> > interpPoints;
 
-    /** \brief
-     * Stores for each DOF a list of its coordinates. If there are now periodic
-     * boundaries than there is also only one coordinate per DOF.
-     */
+    /// Stores for each DOF a list of its coordinates. If there are now periodic
+    /// boundaries than there is also only one coordinate per DOF.
     DOFVector<std::list<WorldVector<double> > > *interpPointCoords;
 
     /// list of coords for each dof
@@ -199,10 +197,8 @@ namespace AMDiS {
     /// Stores a list of vertex infos for each dof.
     DOFVector<std::list<VertexInfo> > *vertexInfos;
 
-    /** \brief
-     * periodicConnections[i][j] stores whether the connection at side j of 
-     * the element with output index i has already been written.
-     */
+    /// periodicConnections[i][j] stores whether the connection at side j of 
+    /// the element with output index i has already been written.
     std::vector<DimVec<bool> > periodicConnections;
 
     /// Stores if element data was collected before.
@@ -217,9 +213,6 @@ namespace AMDiS {
     /// Pointer to a function which decides whether an element is considered.
     bool (*writeElem)(ElInfo*);
 
-    /// Temporary variable used in functions addValueData() and addInterpData().
-    DegreeOfFreedom *localDOFs;
-      
     /// Temporary variable used in functions addValueData() and addInterpData().
     BasisFunction *basisFcts;
 
diff --git a/AMDiS/src/io/DataCollector.hh b/AMDiS/src/io/DataCollector.hh
index f253913c7fc6a9e93528e3e9afee1f6404e0d93a..5dab35394b74b441d78118759f7f7b83c4875672 100644
--- a/AMDiS/src/io/DataCollector.hh
+++ b/AMDiS/src/io/DataCollector.hh
@@ -138,12 +138,10 @@ namespace AMDiS {
 
     basisFcts = const_cast<BasisFunction*>(feSpace->getBasisFcts());
     nBasisFcts = basisFcts->getNumber();
-    localDOFs = new DegreeOfFreedom[nBasisFcts];
   
-    TraverseStack stack;
-
     // Traverse elements to add value information and to mark
     // interpolation points.
+    TraverseStack stack;
     ElInfo *elInfo = stack.traverseFirst(mesh, level, 
 					 traverseFlag | Mesh::FILL_COORDS);
     while (elInfo) {
@@ -171,7 +169,6 @@ namespace AMDiS {
       }
     }
    
-    delete [] localDOFs;
     valueDataCollected = true;
   }
 
@@ -299,9 +296,10 @@ namespace AMDiS {
   {
     FUNCNAME("DataCollector<T>::addValueData()");
     
-    WorldVector<double> vertexCoords;
+    vector<DegreeOfFreedom> localDOFs(basisFcts->getNumber());
     basisFcts->getLocalIndices(elInfo->getElement(), localAdmin, localDOFs);
 
+    WorldVector<double> vertexCoords;
     // First, traverse all DOFs at the vertices of the element, determine
     // their coordinates and add them to the corresponding entry in dofCoords.
     for (int i = 0; i < mesh->getGeo(VERTEX); i++) {
@@ -358,6 +356,7 @@ namespace AMDiS {
   {
     FUNCNAME("DataCollector<T>::addInterpData()");
     
+    vector<DegreeOfFreedom> localDOFs(basisFcts->getNumber());
     basisFcts->getLocalIndices(elInfo->getElement(), localAdmin, localDOFs);
 
     std::vector<int> elemInterpPoints(0);
diff --git a/AMDiS/src/io/GNUPlotWriter.cc b/AMDiS/src/io/GNUPlotWriter.cc
index 211c4f4a7e892d97e40981f6ecbf95f743de9fc8..c6f0484d9b77684aef21d0d1936077c616d1f645 100644
--- a/AMDiS/src/io/GNUPlotWriter.cc
+++ b/AMDiS/src/io/GNUPlotWriter.cc
@@ -40,7 +40,7 @@ namespace AMDiS {
     int dow = Global::getGeo(WORLD);
     const BasisFunction *basFcts = feSpace_->getBasisFcts();
     int numFcts = basFcts->getNumber();
-    DegreeOfFreedom *localDOFs = new DegreeOfFreedom[numFcts];
+    std::vector<DegreeOfFreedom> localDOFs(numFcts);
 
     TraverseStack stack;
     ElInfo *elInfo = stack.traverseFirst(mesh, -1, 
@@ -56,8 +56,6 @@ namespace AMDiS {
       elInfo = stack.traverseNext(elInfo);
     }
 
-    delete [] localDOFs;
-
     FILE *file = NULL;
     if (!(file = fopen(filename_.c_str(), "w")))
       ERROR("could not open file %s for writing\n", filename_.c_str());
diff --git a/AMDiS/src/io/PovrayWriter.cc b/AMDiS/src/io/PovrayWriter.cc
index 244eb26428b6ea0ca065016f76e40cd9ea2617cd..585bab629d70c9548177468b6905b22bae22e47b 100644
--- a/AMDiS/src/io/PovrayWriter.cc
+++ b/AMDiS/src/io/PovrayWriter.cc
@@ -26,9 +26,10 @@ using namespace std;
 namespace AMDiS {
 
   /* destructor */
-  PovrayWriter::~PovrayWriter(){
+  PovrayWriter::~PovrayWriter()
+  {
     // free the memory for the bounding box
-    if(bBox==NULL){
+    if (bBox==NULL) {
       delete bBox;
       bBox = NULL;
     }
@@ -46,7 +47,7 @@ namespace AMDiS {
     DOFVector<double> *values = dataCollector->getValues();
     const FiniteElemSpace *feSpace = dataCollector->getFeSpace();
     const BasisFunction *basFcts = feSpace->getBasisFcts();
-    DegreeOfFreedom *dofs = new DegreeOfFreedom[basFcts->getNumber()];
+    std::vector<DegreeOfFreedom> dofs(basFcts->getNumber());
 
     /* create an 'iterator' */ 
     TraverseStack stack;
@@ -93,8 +94,6 @@ namespace AMDiS {
       out << endl;
     }
     out << "\t}" << endl; // end of texture_list
-
-    delete [] dofs;
   }
 
   // provides the bounding box of the mesh
diff --git a/AMDiS/src/parallel/PetscSolver.cc b/AMDiS/src/parallel/PetscSolver.cc
index 58b2be7afd11ca40361c965b5dd641f0d3e4d047..904f8cba3122e40d64ba8b3442d5f48f299dd4a4 100644
--- a/AMDiS/src/parallel/PetscSolver.cc
+++ b/AMDiS/src/parallel/PetscSolver.cc
@@ -88,4 +88,72 @@ namespace AMDiS {
     VecScatterDestroy(&scatter);
   }
 
+
+  bool PetscSolver::testMatrixSymmetric(Mat mat, bool advancedTest)
+  {
+    FUNCNAME("PetscSolver::testMatrixSymmetric()");
+
+    Mat matTrans;
+    MatTranspose(mat, MAT_INITIAL_MATRIX, &matTrans);
+
+    if (advancedTest) {
+      int rowStart, rowEnd;
+      MatGetOwnershipRange(mat, &rowStart, &rowEnd);
+
+      PetscInt nCols, nColsTrans;
+      const PetscInt *cols, *colsTrans;
+      const PetscScalar *vals, *valsTrans;
+
+      for (int i = rowStart; i < rowEnd; i++) {
+	bool isSym = true;
+	MatGetRow(mat, i, &nCols, &cols, &vals);
+	MatGetRow(matTrans, i, &nColsTrans, &colsTrans, &valsTrans);
+
+	if (nCols != nColsTrans) {
+	  MSG("Symmetric test fails: mat row %d: %d nnz   mat col %d: %d nnz\n",
+	      i, nCols, i, nColsTrans);
+	  isSym = false;
+	} else {
+	  for (int j = 0; j < nCols; j++) {
+	    if (cols[j] != colsTrans[j]) {
+	      if (cols[j] > colsTrans[j]) {
+		MSG("mat[%d][%d] does not exists: mat[%d][%d] = %e\n", 
+		    i, colsTrans[j],
+		    colsTrans[j], i, valsTrans[j]);
+	      } else {
+		MSG("mat[%d][%d] does not exists: mat[%d][%d] = %e\n", 
+		    cols[j], i,
+		    i, cols[j], vals[j]);
+	      }
+	      isSym = false;
+	    } else {
+	      double n = fabs(vals[j] - valsTrans[j]);
+	      if (n > 1e-10) {
+		MSG("value diff:  mat[%d][%d] = %e   mat[%d][%d] = %e\n",
+		    i, cols[j], vals[j], colsTrans[j], i, valsTrans[j]);
+
+		isSym = false;
+	      }
+	    }
+	  }
+	}
+
+	MatRestoreRow(mat, i, &nCols, &cols, &vals);
+	MatRestoreRow(matTrans, i, &nColsTrans, &colsTrans, &valsTrans);
+	
+	if (!isSym)
+	  return false;
+      }
+    } 
+      
+    MatAXPY(matTrans, -1.0, mat, DIFFERENT_NONZERO_PATTERN);
+    double norm1, norm2;
+    MatNorm(matTrans, NORM_FROBENIUS, &norm1);
+    MatNorm(matTrans, NORM_INFINITY, &norm2);
+    MatDestroy(&matTrans);
+    
+    MSG("Matrix norm test: %e %e\n", norm1, norm2);
+    
+    return (norm1 < 1e-10 && norm2 < 1e-10);
+  }
 }
diff --git a/AMDiS/src/parallel/PetscSolver.h b/AMDiS/src/parallel/PetscSolver.h
index 1156591395c071d95cd2c443ec475197fbb715b0..2a541b8f0e72fbec2a539154717f8f2bd9c68db9 100644
--- a/AMDiS/src/parallel/PetscSolver.h
+++ b/AMDiS/src/parallel/PetscSolver.h
@@ -141,6 +141,8 @@ namespace AMDiS {
     void copyVec(Vec& originVec, Vec& destVec, 
 		 vector<int>& originIndex, vector<int>& destIndex);
 
+    /// Run test, if matrix is symmetric.
+    bool testMatrixSymmetric(Mat mat, bool advancedTest = false);
   protected:
     /// PETSc solver object
     KSP kspInterior;
diff --git a/AMDiS/src/parallel/PetscSolverFeti.cc b/AMDiS/src/parallel/PetscSolverFeti.cc
index d0d091cdfdfb20fadec83b962258d01ab7e0b7a7..64bdc7e27b2000d1dd258194fb7367bd2b3e57d8 100644
--- a/AMDiS/src/parallel/PetscSolverFeti.cc
+++ b/AMDiS/src/parallel/PetscSolverFeti.cc
@@ -25,6 +25,32 @@ namespace AMDiS {
 
   using namespace std;
 
+  PetscErrorCode KSPMonitorFeti(KSP ksp, PetscInt n, PetscReal rnorm, void *dummy)
+  {    
+    Vec            Br,v,w;
+    Mat            A;
+
+    KSPGetOperators(ksp, &A, PETSC_NULL, PETSC_NULL);
+    MatGetVecs(A, &w, &v);
+    KSPBuildResidual(ksp, v, w, &Br);
+
+    Vec nest0, nest1;
+    VecNestGetSubVec(Br, 0, &nest0);
+    VecNestGetSubVec(Br, 1, &nest1);
+
+    PetscScalar norm0, norm1;
+    VecNorm(nest0, NORM_2, &norm0);
+    VecNorm(nest1, NORM_2, &norm1);
+
+    VecDestroy(&v);
+    VecDestroy(&w);
+
+    PetscPrintf(PETSC_COMM_WORLD, "%3D KSP Component residual norm [%1.12e %1.12e] and relative [%1.12e]\n",
+		norm0, norm1, rnorm);
+
+    return 0;
+  }
+
   PetscSolverFeti::PetscSolverFeti()
     : PetscSolver(),
       schurPrimalSolver(0),
@@ -122,6 +148,27 @@ namespace AMDiS {
   }
 
 
+  void PetscSolverFeti::createDirichletData(Matrix<DOFMatrix*> &mat)
+  {
+    FUNCNAME("PetscSolverFeti::createDirichletData()");
+
+    int nComponents = mat.getSize();
+    for (int i = 0; i < nComponents; i++) {
+      DOFMatrix* dofMat = mat[i][i];
+      if (!dofMat)
+	continue;
+      
+      const FiniteElemSpace *feSpace = dofMat->getRowFeSpace();
+      std::set<DegreeOfFreedom>& dRows = dofMat->getDirichletRows();
+      if (dirichletRows.count(feSpace)) {
+	WARNING("Implement test that for all components dirichlet rows are equal!\n");
+      } else {
+	dirichletRows[feSpace] = dRows;
+      }
+    }
+  }
+
+
   void PetscSolverFeti::createFetiData()
   {
     FUNCNAME("PetscSolverFeti::createFetiData()");
@@ -235,9 +282,9 @@ namespace AMDiS {
 	    lagrangeMap[feSpace].nRankDofs, 
 	    lagrangeMap[feSpace].nOverallDofs);
 
-	TEST_EXIT_DBG(localDofMap[feSpace].size() + primalDofMap[feSpace].size() == 
-		      static_cast<unsigned int>(feSpace->getAdmin()->getUsedDofs()))
-	  ("Should not happen!\n");	
+// 	TEST_EXIT_DBG(localDofMap[feSpace].size() + primalDofMap[feSpace].size() == 
+// 		      static_cast<unsigned int>(feSpace->getAdmin()->getUsedDofs()))
+// 	  ("Should not happen!\n");	
       }
     }
 
@@ -272,15 +319,11 @@ namespace AMDiS {
     DofIndexSet primals;
     for (DofContainerSet::iterator it = vertices.begin(); 
 	 it != vertices.end(); ++it) {
-      if (meshLevel == 0) {
-	MSG("WARNING: Modified primal detection algorithm!\n");
+      if (dirichletRows[feSpace].count(**it))
+	continue;
 
-	double e = 1e-3;
-	WorldVector<double> c;
-	feSpace->getMesh()->getDofIndexCoords(*it, feSpace, c);
-
-	if (fabs(c[0]) > e && fabs(c[1]) > e && fabs(c[0] - 1.0) > e && fabs(c[1] - 1.0) > e)
-	  primals.insert(**it);
+      if (meshLevel == 0) {
+	primals.insert(**it);
       } else {
 	double e = 1e-8;
 	WorldVector<double> c;
@@ -318,16 +361,22 @@ namespace AMDiS {
 
     DofContainer allBoundaryDofs;
     meshDistributor->getAllBoundaryDofs(feSpace, meshLevel, allBoundaryDofs);
-
+    
     for (DofContainer::iterator it = allBoundaryDofs.begin();
-	 it != allBoundaryDofs.end(); ++it)
-      if (!isPrimal(feSpace, **it))
-	if (meshLevel == 0) {
+	 it != allBoundaryDofs.end(); ++it) {
+      if (dirichletRows[feSpace].count(**it))
+	continue;
+
+      if (isPrimal(feSpace, **it))
+	continue;
+
+      if (meshLevel == 0) {
+	dualDofMap[feSpace].insertRankDof(**it);
+      } else {
+	if (meshDistributor->getDofMapSd()[feSpace].isRankDof(**it))
 	  dualDofMap[feSpace].insertRankDof(**it);
- 	} else {
- 	  if (meshDistributor->getDofMapSd()[feSpace].isRankDof(**it))
- 	    dualDofMap[feSpace].insertRankDof(**it);
- 	}	  
+      }	  
+    }
   }
 
   
@@ -342,11 +391,15 @@ namespace AMDiS {
     meshDistributor->getAllBoundaryDofs(feSpace, meshLevel, allBoundaryDofs);
 
     for (DofContainer::iterator it = allBoundaryDofs.begin();
-	 it != allBoundaryDofs.end(); ++it)
+	 it != allBoundaryDofs.end(); ++it) {
+      if (dirichletRows[feSpace].count(**it))
+	continue;      
+      
       if (meshDistributor->getDofMap()[feSpace].isRankDof(**it))
 	interfaceDofMap[feSpace].insertRankDof(**it);
       else
-	interfaceDofMap[feSpace].insertNonRankDof(**it);
+	interfaceDofMap[feSpace].insertNonRankDof(**it);      
+    }
   }
 
 
@@ -503,41 +556,44 @@ namespace AMDiS {
 
     int nLocalInterior = 0;    
     for (int i = 0; i < admin->getUsedSize(); i++) {
-      if (admin->isDofFree(i) == false && 
-	  isPrimal(feSpace, i) == false &&
-	  isDual(feSpace, i) == false &&
-	  isInterface(feSpace, i) == false) {
-	if (meshLevel == 0) {
-	  localDofMap[feSpace].insertRankDof(i, nLocalInterior);
+      if (admin->isDofFree(i) ||
+	  isPrimal(feSpace, i) ||
+	  isDual(feSpace, i) ||
+	  isInterface(feSpace, i) ||
+	  dirichletRows[feSpace].count(i))
+	continue;      
 
-	  if (fetiPreconditioner == FETI_DIRICHLET)
-	    interiorDofMap[feSpace].insertRankDof(i, nLocalInterior);
-	  
-	  nLocalInterior++;	  
-	} else {
-	  if (meshDistributor->getDofMapSd()[feSpace].isRankDof(i))
-	    localDofMap[feSpace].insertRankDof(i);
-	  else
-	    localDofMap[feSpace].insertNonRankDof(i);
-
-	  TEST_EXIT_DBG(fetiPreconditioner == FETI_NONE)
-	    ("Not yet implemnted!\n");
-	}
+      if (meshLevel == 0) {
+	localDofMap[feSpace].insertRankDof(i, nLocalInterior);
+	
+	if (fetiPreconditioner == FETI_DIRICHLET)
+	  interiorDofMap[feSpace].insertRankDof(i, nLocalInterior);
+	
+	nLocalInterior++;	
+      } else {
+	if (meshDistributor->getDofMapSd()[feSpace].isRankDof(i))
+	  localDofMap[feSpace].insertRankDof(i);
+	else
+	  localDofMap[feSpace].insertNonRankDof(i);
+	
+	TEST_EXIT_DBG(fetiPreconditioner == FETI_NONE)
+	  ("Not yet implemnted!\n");	
       }
     }
     
     // === And finally, add the global indicies of all dual nodes. ===
 
     for (DofMap::iterator it = dualDofMap[feSpace].getMap().begin();
-	 it != dualDofMap[feSpace].getMap().end(); ++it)
-      if (meshLevel == 0)
+	 it != dualDofMap[feSpace].getMap().end(); ++it) {
+      if (meshLevel == 0) {
 	localDofMap[feSpace].insertRankDof(it->first);
-      else {
+      } else {
 	if (meshDistributor->getDofMapSd()[feSpace].isRankDof(it->first))
 	  localDofMap[feSpace].insertRankDof(it->first);
 	else 
 	  localDofMap[feSpace].insertNonRankDof(it->first);
       }
+    }
   }
 
 
@@ -687,7 +743,7 @@ namespace AMDiS {
 
 	VecAssemblyBegin(tmpVec);
 	VecAssemblyEnd(tmpVec);
-	
+
 	subdomain->solve(tmpVec, tmpVec);
 
 	PetscScalar *tmpValues;
@@ -810,6 +866,8 @@ namespace AMDiS {
     KSPSetFromOptions(ksp_feti);
 
 
+
+
     // === Create FETI-DP preconditioner object. ===
 
     if (fetiPreconditioner != FETI_NONE || stokesMode) {
@@ -1458,8 +1516,12 @@ namespace AMDiS {
 
     initialize(feSpaces);
 
+    createDirichletData(*mat);
+
     createFetiData();
 
+    dirichletRows.clear();
+
    
     // === Create matrices for the FETI-DP method. ===
 
@@ -1470,6 +1532,14 @@ namespace AMDiS {
   
     subdomain->fillPetscMatrix(mat);
 
+    //    MSG("MATRIX IS SYM: %d\n", testMatrixSymmetric(subdomain->getMatInterior(), true));
+
+//     if (MPI::COMM_WORLD.Get_rank() == 0)
+//       MatView(subdomain->getMatInterior(), PETSC_VIEWER_STDOUT_SELF);
+
+//     AMDiS::finalize();
+//     exit(0);
+
     if (printTimings) {
       MPI::COMM_WORLD.Barrier();
       MSG("FETI-DP timing 02: %.5f seconds (creation of interior matrices)\n",
@@ -1488,6 +1558,11 @@ namespace AMDiS {
     
     // === Create matrices for FETI-DP preconditioner. ===    
     createPreconditionerMatrix(mat);
+
+    //    MSG("DUALS MATRIX IS SYM: %d\n", testMatrixSymmetric(mat_duals_duals, true));
+
+//     AMDiS::finalize();
+//     exit(0);
     
     // === Create and fill PETSc matrix for Lagrange constraints. ===
     createMatLagrange(feSpaces);
diff --git a/AMDiS/src/parallel/PetscSolverFeti.h b/AMDiS/src/parallel/PetscSolverFeti.h
index 3313bab362b41aa15be5aba3328639e40c874528..affcf1ec141604fa6dd02834eb9399cb8d5c5aa7 100644
--- a/AMDiS/src/parallel/PetscSolverFeti.h
+++ b/AMDiS/src/parallel/PetscSolverFeti.h
@@ -72,11 +72,6 @@ namespace AMDiS {
     /// spaces of all components.
     void initialize(vector<const FiniteElemSpace*> feSpaces);
 
-    /// After mesh changes, or if the solver is called the first time, this
-    /// function creates all information about primal nodes, dual nodes and
-    /// lagrange constraints.    
-    void createFetiData();
-
     int getNumberOfPrimals()
     {
       return primalDofMap.getOverallDofs();
@@ -103,6 +98,14 @@ namespace AMDiS {
     }
 
   protected:
+    ///
+    void createDirichletData(Matrix<DOFMatrix*> &mat);
+
+    /// After mesh changes, or if the solver is called the first time, this
+    /// function creates all information about primal nodes, dual nodes and
+    /// lagrange constraints.    
+    void createFetiData();
+
     /// Defines which boundary nodes are primal. Creates global index of
     /// the primal variables.
     void createPrimals(const FiniteElemSpace *feSpace);
@@ -167,6 +170,7 @@ namespace AMDiS {
 			 Vec &vec_sol_primal,
 			 SystemVector &vec);
 
+    ///
     void recoverInterfaceSolution(Vec& vecInterface, 
 				  SystemVector &vec);
 
@@ -322,6 +326,8 @@ namespace AMDiS {
     const FiniteElemSpace* pressureFeSpace;
 
     int pressureComponent;
+
+    map<const FiniteElemSpace*, std::set<DegreeOfFreedom> > dirichletRows;
   };
 
 }
diff --git a/AMDiS/src/parallel/PetscSolverFetiOperators.cc b/AMDiS/src/parallel/PetscSolverFetiOperators.cc
index 582053c82bcbf37bd514bfa845e8480d39d8ebda..a3bae20089123975698c5daecc2eed5c8c7ace01 100644
--- a/AMDiS/src/parallel/PetscSolverFetiOperators.cc
+++ b/AMDiS/src/parallel/PetscSolverFetiOperators.cc
@@ -288,6 +288,7 @@ namespace AMDiS {
 
   PetscErrorCode petscApplyFetiInterfaceLumpedPrecon(PC pc, Vec xvec, Vec yvec)
   {
+    FUNCNAME("precon");
     // Get data for the preconditioner
     void *ctx;
     PCShellGetContext(pc, &ctx);
@@ -301,16 +302,20 @@ namespace AMDiS {
     VecNestGetSubVec(yvec, 1, &y_lagrange);
 
 #if 0
-    MatMult(data->subSolver->getMatCoarse(0, 1), x_interface, data->tmp_primal);
-    KSPSolve(data->ksp_primal, data->tmp_primal, data->tmp_primal);
-    MatMult(data->subSolver->getMatCoarse(1, 0), data->tmp_primal, y_interface);
+//     MatMult(data->subSolver->getMatCoarse(0, 1), x_interface, data->tmp_primal);
+//     KSPSolve(data->ksp_primal, data->tmp_primal, data->tmp_primal);
+//     MatMult(data->subSolver->getMatCoarse(1, 0), data->tmp_primal, y_interface);
 
     MatMult(data->subSolver->getMatInteriorCoarse(1), x_interface, data->tmp_vec_b0);
     MatMultTranspose(*(data->mat_lagrange_scaled), x_lagrange, data->tmp_vec_b1);
     VecAXPY(data->tmp_vec_b0, 1.0, data->tmp_vec_b1);
+
+    //MatMultTranspose(*(data->mat_lagrange_scaled), x_lagrange, data->tmp_vec_b0);
 #else 
     VecCopy(x_interface, y_interface);
-    VecScale(y_interface, 1024.0);
+    double scaleFactor = 1.0;
+    Parameters::get("scal", scaleFactor);
+    VecScale(y_interface, scaleFactor);
     //    VecPointwiseMult(y_interface, x_interface, data->h2vec);
 
     MatMultTranspose(*(data->mat_lagrange_scaled), x_lagrange, data->tmp_vec_b0);
@@ -358,10 +363,10 @@ namespace AMDiS {
     MatMult(*(data->mat_lagrange_scaled), data->tmp_vec_b0, y_lagrange);
 
 #if 0
-    Vec tmp_interface;
-    VecDuplicate(y_interface, &tmp_interface);
-    MatMult(data->subSolver->getMatCoarseInterior(1), data->tmp_vec_b0, tmp_interface);
-    VecAXPY(y_interface, 1.0, tmp_interface);
+//     Vec tmp_interface;
+//     VecDuplicate(y_interface, &tmp_interface);
+    MatMult(data->subSolver->getMatCoarseInterior(1), data->tmp_vec_b0, y_interface);
+    //    VecAXPY(y_interface, 1.0, tmp_interface);
 #endif
 
     return 0;
diff --git a/AMDiS/src/parallel/PetscSolverGlobalMatrix.cc b/AMDiS/src/parallel/PetscSolverGlobalMatrix.cc
index 55e96dacf0309364e68eda993f30ea60b5efcca6..24b2da760256dc4949da42397b5f4b77397da489 100644
--- a/AMDiS/src/parallel/PetscSolverGlobalMatrix.cc
+++ b/AMDiS/src/parallel/PetscSolverGlobalMatrix.cc
@@ -158,6 +158,10 @@ namespace AMDiS {
 	    bool isColCoarse = 
 	      isCoarseSpace(colComponent, feSpaces[colComponent], col(*icursor));
 
+	    if (isColCoarse == false)
+	      if ((*interiorMap)[dofMat->getColFeSpace()].isSet(col(*icursor)) == false)
+		continue;
+
 	    if (isColCoarse == isRowCoarse) {
 	      cols.push_back(col(*icursor));
 	      values.push_back(value(*icursor));
@@ -183,13 +187,16 @@ namespace AMDiS {
 	      for (unsigned int i = 0; i < colsOther.size(); i++)
 		colsOther[i] = 
 		  interiorMap->getMatIndex(colComponent, colsOther[i]) + 
-		  rStartInterior;
+		  rStartInterior;	      
 
 	      MatSetValues(getMatCoarseInteriorByComponent(rowComponent), 
 			   1, &rowIndex, colsOther.size(),
  			   &(colsOther[0]), &(valuesOther[0]), ADD_VALUES);
 	    }
 	  } else {
+	    if ((*interiorMap)[dofMat->getRowFeSpace()].isSet(*cursor) == false)
+	      continue;
+
 	    int localRowIndex = 
 	      (subdomainLevel == 0 ? 
 	       interiorMap->getLocalMatIndex(rowComponent, *cursor) :
@@ -682,6 +689,9 @@ namespace AMDiS {
 	int index = rowCoarseSpace->getMatIndex(nRowVec, dofIt.getDOFIndex());
 	VecSetValue(vecCoarse, index, *dofIt, ADD_VALUES);
       } else {
+	if ((*interiorMap)[feSpace].isSet(dofIt.getDOFIndex()) == false)
+	  continue;
+
 	// Calculate global row index of the DOF.
 	DegreeOfFreedom globalRowDof = 
 	  (*interiorMap)[feSpace][dofIt.getDOFIndex()].global;
diff --git a/AMDiS/src/reinit/HL_SignedDistTraverse.cc b/AMDiS/src/reinit/HL_SignedDistTraverse.cc
index a0bb681f81a5cef93a8c3abe210dde7afb7cc661..9359890e1c43e720a55bebb445815ac6874e7188 100644
--- a/AMDiS/src/reinit/HL_SignedDistTraverse.cc
+++ b/AMDiS/src/reinit/HL_SignedDistTraverse.cc
@@ -52,10 +52,9 @@ void HL_SignedDistTraverse::initializeBoundary()
       ((VelocityExtFromVelocityField *)velExt)->setElInfo(elInfo);    
     
     // Get local indices of vertices.
-    feSpace->getBasisFcts()->getLocalIndices(
-			     const_cast<Element*>(elInfo->getElement()),
-			     const_cast<DOFAdmin*>(feSpace->getAdmin()),
-			     &(locInd[0])); 
+    feSpace->getBasisFcts()->getLocalIndices(const_cast<Element*>(elInfo->getElement()),
+					     const_cast<DOFAdmin*>(feSpace->getAdmin()),
+					     locInd); 
     
     // Get element status.
     elStatus = elLS->createElementLevelSet(elInfo);
@@ -161,10 +160,9 @@ void HL_SignedDistTraverse::HL_elementUpdate(ElInfo *elInfo)
   if (static_cast<int>(locInd.size()) < nBasFcts)
     locInd.resize(nBasFcts);
   
-  feSpace->getBasisFcts()->getLocalIndices(
-			   const_cast<Element *>(elInfo->getElement()),
-			   const_cast<DOFAdmin *>(feSpace->getAdmin()),
-			   &(locInd[0])); 
+  feSpace->getBasisFcts()->getLocalIndices(const_cast<Element *>(elInfo->getElement()),
+					   const_cast<DOFAdmin *>(feSpace->getAdmin()),
+					   locInd);
   
   // ===== Hopf-Lax element update for each vertex of element. =====
   for (int i = 0; i <= dim; i++) {