diff --git a/AMDiS/CMakeLists.txt b/AMDiS/CMakeLists.txt
index dbc3584056314922e7d570e04158031a1eba2e3d..cb9fbf9146880bd382074a9258aec9ad2bd48c4c 100644
--- a/AMDiS/CMakeLists.txt
+++ b/AMDiS/CMakeLists.txt
@@ -122,6 +122,7 @@ SET(AMDIS_SRC ${SOURCE_DIR}/AdaptBase.cc
 	      ${SOURCE_DIR}/MacroElement.cc
 	      ${SOURCE_DIR}/Marker.cc
 	      ${SOURCE_DIR}/MatrixVector.cc
+# 	      ${SOURCE_DIR}/Test_MatrixVectorOperations.cc
 	      ${SOURCE_DIR}/Mesh.cc
 	      ${SOURCE_DIR}/MeshStructure.cc
 	      ${SOURCE_DIR}/Operator.cc
@@ -175,6 +176,7 @@ SET(AMDIS_SRC ${SOURCE_DIR}/AdaptBase.cc
               ${SOURCE_DIR}/io/detail/Arh2Writer.cc
 	      ${SOURCE_DIR}/io/DofWriter.cc
 	      ${SOURCE_DIR}/io/ElementFileWriter.cc
+	      ${SOURCE_DIR}/io/FileWriterInterface.cc
 	      ${SOURCE_DIR}/io/FileWriter.cc
 	      ${SOURCE_DIR}/io/GNUPlotWriter.cc
 	      ${SOURCE_DIR}/io/MacroInfo.cc
@@ -433,9 +435,7 @@ if(ENABLE_EXTENSIONS)
 	      ${EXTENSIONS_DIR}/POperators.cc
 	      ${EXTENSIONS_DIR}/SingularDirichletBC2.cc
 	      ${EXTENSIONS_DIR}/time/ExtendedRosenbrockStationary.cc
-	      ${EXTENSIONS_DIR}/pugixml/src/pugixml.cpp
-	      ${EXTENSIONS_DIR}/preconditioner/PhaseFieldCrystal_.cc
-	      ${EXTENSIONS_DIR}/preconditioner/CahnHilliard_.cc)
+	      ${EXTENSIONS_DIR}/pugixml/src/pugixml.cpp)
 	      
       if(ENABLE_SEQ_PETSC)
 	list(APPEND EXTENSIONS_SRC
@@ -510,11 +510,15 @@ if(ENABLE_EXTENSIONS)
 		  ${EXTENSIONS_DIR}/base_problems/CahnHilliard.cc
 		  ${EXTENSIONS_DIR}/base_problems/CahnHilliard_RB.cc
 		  ${EXTENSIONS_DIR}/base_problems/CahnHilliardNavierStokes.cc
-    # 	      ${EXTENSIONS_DIR}/base_problems/DiffuseDomainFsi.cc
+		  ${EXTENSIONS_DIR}/base_problems/CahnHilliardNavierStokes_RB.cc
+		  ${EXTENSIONS_DIR}/base_problems/CahnHilliardNavierStokes_TwoPhase.cc
+		  ${EXTENSIONS_DIR}/base_problems/CahnHilliardNavierStokes_TwoPhase_RB.cc
+		  ${EXTENSIONS_DIR}/base_problems/DiffuseDomainFsi.cc
 		  ${EXTENSIONS_DIR}/base_problems/LinearElasticity.cc
 		  ${EXTENSIONS_DIR}/base_problems/LinearElasticityPhase.cc
-    # 	      ${EXTENSIONS_DIR}/base_problems/NavierStokes_Chorin.cc
+# 		  ${EXTENSIONS_DIR}/base_problems/NavierStokes_Chorin.cc
 		  ${EXTENSIONS_DIR}/base_problems/NavierStokesCahnHilliard.cc
+# 		  ${EXTENSIONS_DIR}/base_problems/NavierStokesPhase_Chorin.cc
 		  ${EXTENSIONS_DIR}/base_problems/NavierStokesPhase_TaylorHood.cc
 		  ${EXTENSIONS_DIR}/base_problems/NavierStokes_TaylorHood.cc
 		  ${EXTENSIONS_DIR}/base_problems/NavierStokes_TaylorHood_RB.cc
@@ -524,7 +528,10 @@ if(ENABLE_EXTENSIONS)
 		  ${EXTENSIONS_DIR}/base_problems/PhaseFieldCrystal_Phase.cc
 		  ${EXTENSIONS_DIR}/base_problems/PhaseFieldCrystal_RB.cc
 		  ${EXTENSIONS_DIR}/base_problems/PolarizationField.cc
-		  ${EXTENSIONS_DIR}/base_problems/QuasiCrystal.cc)
+		  ${EXTENSIONS_DIR}/base_problems/QuasiCrystal.cc
+		  ${EXTENSIONS_DIR}/base_problems/QuasiCrystal_RB.cc
+# 		  ${EXTENSIONS_DIR}/base_problems/VacancyPhaseFieldCrystal.cc
+		  )
 	list(APPEND COMPILEFLAGS "-DHAVE_BASE_PROBLEMS=1")
 	list(APPEND AMDIS_INCLUDE_DIRS ${EXTENSIONS_DIR}/base_problems)
 	if(WIN32)
@@ -635,6 +642,11 @@ INSTALL(FILES ${HEADERS}
 	DESTINATION include/amdis/)
 list(APPEND deb_add_dirs "include/amdis")
 
+FILE(GLOB HEADERS "${SOURCE_DIR}/config/*.h*")
+INSTALL(FILES ${HEADERS} 
+	DESTINATION include/amdis/config/)
+list(APPEND deb_add_dirs "include/amdis/config")
+
 FILE(GLOB HEADERS "${SOURCE_DIR}/*.hh")
 INSTALL(FILES ${HEADERS} 
 	DESTINATION include/amdis/)
diff --git a/AMDiS/src/AMDiS.h b/AMDiS/src/AMDiS.h
index 36d4cbca42ce71b87f28b5c38e4f9e3627586091..c9030f3008b9dd14f0f9ccaea12e7360e97d2378 100644
--- a/AMDiS/src/AMDiS.h
+++ b/AMDiS/src/AMDiS.h
@@ -76,6 +76,7 @@
 #include "Marker.h"
 // #include "MathFunctions.h"
 #include "MatrixVector.h"
+#include "MatrixVectorOperations.h"
 #include "Mesh.h"
 #include "MeshStructure.h"
 #include "ComponentTraverseInfo.h"
diff --git a/AMDiS/src/Assembler.cc b/AMDiS/src/Assembler.cc
index addc88debb83ea7146af443dd5323dc1f9d59bb7..b73de0b3d1860ea175e8245003603734086a3760 100644
--- a/AMDiS/src/Assembler.cc
+++ b/AMDiS/src/Assembler.cc
@@ -64,7 +64,7 @@ namespace AMDiS {
     Element *el = elInfo->getElement();
 
     if (el != lastMatEl || !operat->isOptimized()) {
-      initElement(elInfo);
+      initElement(elInfo, elInfo);
 
       if (rememberElMat)
 	set_to_zero(elementMatrix);
@@ -123,12 +123,14 @@ namespace AMDiS {
     }
  
     ElementMatrix& mat = rememberElMat ? elementMatrix : userMat;
-
+    
     if (secondOrderAssembler) {
+      // calculate element matrices always on smallest element
       secondOrderAssembler->calculateElementMatrix(smallElInfo, mat);
 
+      // smallElInfo stores refinement-relation to largeElInfo
       ElementMatrix &m = 
-	smallElInfo->getSubElemGradCoordsMat(rowFeSpace->getBasisFcts()->getDegree());
+	smallElInfo->getSubElemGradCoordsMat(rowFeSpace->getBasisFcts()->getDegree());  // muste be moved to next if-else block when generalized for multiple polynomial degrees
       
       if (!rowColFeSpaceEqual) {
 	if (smallElInfo == colElInfo)
@@ -321,14 +323,7 @@ namespace AMDiS {
       calculateElementMatrix(elInfo, elementMatrix);
     }
 
-    // vec += elementMatrix*uhOldLoc;
-    for (int i = 0; i < nRow; i++) {
-      double val = 0.0;
-      for (int j = 0; j < nCol; j++)
-	val += elementMatrix[i][j] * uhOldLoc[j];
-      
-      vec[i] += val;
-    }   
+    vec += elementMatrix*uhOldLoc;
   }
 
 
@@ -358,15 +353,10 @@ namespace AMDiS {
     if (mainElInfo->getElement() != lastMatEl) {
       set_to_zero(elementMatrix);
       calculateElementMatrix(mainElInfo, auxElInfo, smallElInfo, largeElInfo, 
-			     false, elementMatrix);    
+			     rowFeSpace == operat->uhOld->getFeSpace(), elementMatrix);  
     }
 
-    for (int i = 0; i < nBasFcts; i++) {
-      double val = 0.0;
-      for (int j = 0; j < nBasFcts; j++)
- 	val += elementMatrix[i][j] * uhOldLoc[j];
-      vec[i] += val;
-    }   
+    vec += elementMatrix * uhOldLoc;
   }
 
 
diff --git a/AMDiS/src/BallProject.h b/AMDiS/src/BallProject.h
index 020056834f14da6593dfd4d03f99c663e681a700..6bbef335b3bb6c38b260f9bab4de823cc0d8f244 100644
--- a/AMDiS/src/BallProject.h
+++ b/AMDiS/src/BallProject.h
@@ -25,6 +25,8 @@
 #ifndef AMDIS_BALLPROJECT_H
 #define AMDIS_BALLPROJECT_H
 
+#include "MatrixVectorOperations.h"
+
 namespace AMDiS {
 
   /** \brief
diff --git a/AMDiS/src/Cholesky.cc b/AMDiS/src/Cholesky.cc
index 92c5353285e4551fd17003cdf80d90378ff42588..618f4f05d8fbb33e7b58de0b1b653bc08487bdb7 100644
--- a/AMDiS/src/Cholesky.cc
+++ b/AMDiS/src/Cholesky.cc
@@ -20,6 +20,7 @@
 
 
 #include "Cholesky.h"
+#include "MatrixVectorOperations.h"
 
 namespace AMDiS {
 
diff --git a/AMDiS/src/Config.h b/AMDiS/src/Config.h
new file mode 100644
index 0000000000000000000000000000000000000000..a9f7415bf27bef60f5597a16af0fe483a98f7480
--- /dev/null
+++ b/AMDiS/src/Config.h
@@ -0,0 +1,38 @@
+#pragma once
+
+/** \brief current AMDiS version */
+#ifndef AMDIS_VERSION
+#define AMDIS_VERSION  "AMDiS: Version 0.9.1"
+#endif
+
+#include <boost/config.hpp>
+
+#define CACHE_LINE 16
+
+#if defined(__clang__)					// Clang/LLVM.
+  #include "config/Config_clang.h"
+  
+#elif defined(__ICC) || defined(__INTEL_COMPILER)	// Intel ICC/ICPC. 
+  #include "config/Config_intel.h"
+  
+#elif defined(__GNUC__) || defined(__GNUG__)		// GNU GCC/G++.
+  #include "config/Config_gcc.h"
+  
+#elif defined(__HP_cc) || defined(__HP_aCC)
+  error: not supported compiler
+  
+#elif defined(__IBMC__) || defined(__IBMCPP__)
+  error: not supported compiler
+  
+#elif defined(_MSC_VER)					// Microsoft Visual Studio. 
+  #include "config/Config_msc.h"
+  
+#elif defined(__PGI)					// Portland Group PGCC/PGCPP.
+  error: not supported compiler
+//   #include "Config_pgi.h"  
+
+#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+  error: not supported compiler
+#endif
+
+#include "config/Config_defaults.h"
\ No newline at end of file
diff --git a/AMDiS/src/CylinderProject.h b/AMDiS/src/CylinderProject.h
index a2214551b1a771bb0d2f203f7d0847729bf5fb6d..07c1ba75982aadc5bad328427d32d112b1f53276 100644
--- a/AMDiS/src/CylinderProject.h
+++ b/AMDiS/src/CylinderProject.h
@@ -25,6 +25,8 @@
 #ifndef AMDIS_CYLINDERPROJECT_H
 #define AMDIS_CYLINDERPROJECT_H
 
+#include "MatrixVectorOperations.h"
+
 namespace AMDiS {
 
   /** \brief
diff --git a/AMDiS/src/DOFVector.h b/AMDiS/src/DOFVector.h
index 3de444693e9b989082039acf1a298fc6dfa6c3f8..49e6125d4a3dbe02b7e3494b2416e663c93f387f 100644
--- a/AMDiS/src/DOFVector.h
+++ b/AMDiS/src/DOFVector.h
@@ -350,10 +350,10 @@ namespace AMDiS {
     {}
 
     /// Constructs a DOFVector with name n belonging to FiniteElemSpace f
-    DOFVector(const FiniteElemSpace* f, std::string n, bool addToSynch = true); 
+    DOFVector(const FiniteElemSpace* f, std::string n, bool addToSynch = false); 
 
     /// Initialization.
-    void init(const FiniteElemSpace* f, std::string n, bool addToSynch = true);
+    void init(const FiniteElemSpace* f, std::string n, bool addToSynch = false);
 
     /// Copy Constructor
     DOFVector(const DOFVector& rhs) : DOFVectorBase<T>()
diff --git a/AMDiS/src/DOFVector.hh b/AMDiS/src/DOFVector.hh
index 11338d36e5cbc20c2c6f7e164bd9962d7440f16e..f01c6ee9fb0095a0293066c127b13e76e0cf0b4a 100644
--- a/AMDiS/src/DOFVector.hh
+++ b/AMDiS/src/DOFVector.hh
@@ -130,7 +130,7 @@ namespace AMDiS {
       (this->feSpace->getAdmin())->addDOFIndexed(this);
     this->boundaryManager = new BoundaryManager(f);
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
-    if ( Parallel::MeshDistributor::globalMeshDistributor != NULL) 
+    if (addToSynch && Parallel::MeshDistributor::globalMeshDistributor != NULL) 
       Parallel::MeshDistributor::globalMeshDistributor->addInterchangeVector(this);
 #endif
   }
diff --git a/AMDiS/src/DualTraverse.h b/AMDiS/src/DualTraverse.h
index 64d84f0a35d875e51ed8acc49f0cf75be4c43893..b5b2c2c9fc653d25404923e984f6111771e8c72e 100644
--- a/AMDiS/src/DualTraverse.h
+++ b/AMDiS/src/DualTraverse.h
@@ -37,10 +37,10 @@ namespace AMDiS {
    */
   struct DualElInfo 
   {
-    ElInfo *rowElInfo;
-    ElInfo *colElInfo;
-    ElInfo *smallElInfo;
-    ElInfo *largeElInfo;
+    ElInfo *rowElInfo;    ///< elInfo related to testfunction
+    ElInfo *colElInfo;    ///< elInfo related to trialfunction
+    ElInfo *smallElInfo;  ///< the smaller element of (rowElInfo, colElInfo) with refinementPath relative to largeElInfo
+    ElInfo *largeElInfo;  ///< the larger element of (rowElInfo, colElInfo)
   };
 
   /// Parallel traversal of two meshes. 
diff --git a/AMDiS/src/ElInfo.h b/AMDiS/src/ElInfo.h
index 4fb5d6a49fce5300ea1e6420d1e7250671fc6319..f4dc850f70bf98cbc18c282ed31b1289c89f2479 100644
--- a/AMDiS/src/ElInfo.h
+++ b/AMDiS/src/ElInfo.h
@@ -252,7 +252,7 @@ namespace AMDiS {
 
     virtual mtl::dense2D<double>& getSubElemGradCoordsMat(int degree) const 
     {
-      return subElemGradMatrices[degree][std::make_pair(refinementPathLength, refinementPath)];
+      return getSubElemCoordsMat(degree);
     }
 
     /** \} */ 
diff --git a/AMDiS/src/ElInfo1d.cc b/AMDiS/src/ElInfo1d.cc
index d1e9b076e9b4dfb0e867969257d18c9251518847..cb11ff1aa17d839dbeaf8dbf4c5001265bf53541 100644
--- a/AMDiS/src/ElInfo1d.cc
+++ b/AMDiS/src/ElInfo1d.cc
@@ -367,22 +367,7 @@ namespace AMDiS {
 
   mtl::dense2D<double>& ElInfo1d::getSubElemGradCoordsMat(int degree) const
   {
-    FUNCNAME("ElInfo1d::getSubElemGradCoordsMat()");
-
-    TEST_EXIT(degree == 1)("Not supported for basis functions with degree > 1!\n");
-
-    using namespace mtl;
-
-    if (subElemGradMatrices[degree].count(std::make_pair(refinementPathLength, refinementPath)) == 0) {
-      dense2D<double> mat(mat_d1);
-
-      for (int i = 0; i < refinementPathLength; i++)
-	mat *= 0.5;
-
-      subElemGradMatrices[1][std::make_pair(refinementPathLength, refinementPath)] = mat;
-    }
-
-    return subElemGradMatrices[degree][std::make_pair(refinementPathLength, refinementPath)];
+    return getSubElemCoordsMat(degree);
   }
 
 
diff --git a/AMDiS/src/ElInfo2d.cc b/AMDiS/src/ElInfo2d.cc
index 83864e3d261467058c105ae6b5cfb082306f0526..99b9ccf69149a8d0bdca91a3fbe108256235dd30 100644
--- a/AMDiS/src/ElInfo2d.cc
+++ b/AMDiS/src/ElInfo2d.cc
@@ -66,64 +66,64 @@ namespace AMDiS {
 
 
 
-  double ElInfo2d::mat_d3_left_val[10][10] = {{0.0, 1.0, -0.0625, 0.3125, 0.0, 0.0, 0.0625, 0.0, 0.0, -0.0625},
-					      {0.0, 0.0, -0.0625, 0.0625, 0.0, 0.0, 0.0625, 0.0, 0.0, 0.0625},
+  double ElInfo2d::mat_d3_left_val[10][10] = {{0.0,  1.0, -6.25e-02,  3.125e-01,  0.0,  0.0,  6.25e-02,  0.0,  0.0, -6.25e-02},
+					      {0.0,  0.0, -6.25e-02,  6.25e-02,  0.0,  0.0,  6.25e-02,  0.0,  0.0, 6.25e-02},
 					      {1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
-					      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.25, 0.0, 0.0, -0.125},
+					      {0.0,  0.0,  0.0,  0.0,  0.0,  0.0, -2.5e-01,  0.0,  0.0, -0.125},
 					      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0},
 					      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 1.0, 0.0, 0.0},
-					      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.25, 0.0, 1.0, 0.375},
-					      {0.0, 0.0, 0.5625, 0.9375, 1.0, 0.0, -0.0625, 0.0, 0.0, 0.1875},
-					      {0.0, 0.0, 0.5625, -0.3125, 0.0, 0.0, -0.0625, 0.0, 0.0, 0.0},
-					      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.5, 0.0, 0.0, 0.75}};
+					      {0.0,  0.0,  0.0,  0.0,  0.0,  0.0, -2.5e-01,  0.0,  1.0, 0.375},
+					      {0.0,  0.0,  5.625e-01,  9.375e-01,  1.0,  0.0, -6.25e-02,  0.0,  0.0, 1.875e-01},
+					      {0.0,  0.0,  5.625e-01, -3.125e-01,  0.0,  0.0, -6.25e-02,  0.0,  0.0, -1.875e-01},
+					      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.5, 0.0, 0.0, 7.5e-01}};
   mtl::dense2D<double> ElInfo2d::mat_d3_left(mat_d3_left_val);
 
-  double ElInfo2d::mat_d3_right_val[10][10] = {{0.0, 0.0, -0.0625, 0.0625, 0.0, 0.0, 0.0625, 0.0, 0.0, 0.0625},
-					       {1.0, 0.0, -0.0625, 0.0625, 0.0, 0.0, 0.3125, 0.0, 0.0, -0.0625},
-					       {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
-					       {0.0, 0.0, 0.0, -0.25, 0.0, 0.0, 0.0, 1.0, 0.0, 0.375},
-					       {0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
-					       {0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
-					       {0.0, 0.0, 0.0, -0.25, 0.0, 0.0, 0.0, 0.0, 0.0, -0.125},
-					       {0.0, 0.0, 0.5625, -0.0625, 0.0, 0.0, -0.3125, 0.0, 0.0, -0.1875},
-					       {0.0, 0.0, 0.5625, -0.0625, 0.0, 1.0, 0.9375, 0.0, 0.0, 0.1875},
-					       {0.0, 0.0, 0.0, 0.5, 1.0, 0.0, 0.0, 0.0, 0.0, 0.75}};
+  double ElInfo2d::mat_d3_right_val[10][10] = {{0.0,  0.0, -6.25e-02,  6.25e-02,  0.0,  0.0,  6.25e-02,  0.0,  0.0, 6.25e-02},
+					      {1.0,  0.0, -6.25e-02,  6.25e-02,  0.0,  0.0,  3.125e-01,  0.0,  0.0, -6.25e-02},
+					      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+					      {0.0,  0.0,  0.0, -2.5e-01,  0.0,  0.0,  0.0,  1.0,  0.0, 0.375},
+					      {0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
+					      {0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+					      {0.0,  0.0,  0.0, -2.5e-01,  0.0,  0.0,  0.0,  0.0,  0.0, -0.125},
+					      {0.0,  0.0,  5.625e-01, -6.25e-02,  0.0,  0.0, -3.125e-01,  0.0,  0.0, -1.875e-01},
+					      {0.0,  0.0,  5.625e-01, -6.25e-02,  0.0,  1.0,  9.375e-01,  0.0,  0.0, 1.875e-01},
+					      {0.0, 0.0, 0.0, 0.5, 1.0, 0.0, 0.0, 0.0, 0.0, 7.5e-01}};
   mtl::dense2D<double> ElInfo2d::mat_d3_right(mat_d3_right_val);
 
 
 
-  double ElInfo2d::mat_d4_left_val[15][15] = {{0.0, 1.0, 0.0, 2.734375e-01, 0.0, -3.90625e-02, 2.34375e-02, 0.0, -3.90625e-02, 0.0, 0.0, 0.0, 2.34375e-02, -3.90625e-02, 0.0},
-					      {0.0, 0.0, 0.0, -3.90625e-02, 0.0, 2.34375e-02, 2.34375e-02, 0.0, -3.90625e-02, 0.0, 0.0, 0.0, -3.90625e-02, -3.90625e-02, 0.0},
+  double ElInfo2d::mat_d4_left_val[15][15] = {{0.0,  1.0,  0.0,  2.734375e-01,  0.0, -3.906250e-02,  2.343750e-02,  0.0, -3.906250e-02,  0.0,  0.0,  0.0,  2.343750e-02, -3.906250e-02, 0.0},
+					      {0.0,  0.0,  0.0, -3.906250e-02,  0.0,  2.343750e-02,  2.343750e-02,  0.0, -3.906250e-02,  0.0,  0.0,  0.0, -3.906250e-02, -3.906250e-02, 0.0},
 					      {1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
-					      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -6.25e-02, 0.0, 1.875e-01, 0.0, 0.0, 0.0, 1.25e-01, 6.25e-02, 0.0},
-					      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -3.75e-01, 0.0, 0.0, 0.0, -1.25e-01, 0.0, 0.0},
-					      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.e-01, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
-					      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.e-01, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
-					      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -3.75e-01, 0.0, 1.0, 0.0, 3.75e-01, 0.0, 0.0},
-					      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -6.25e-02, 0.0, 1.875e-01, 0.0, 0.0, 1.0, -1.25e-01, 3.125e-01, 0.0},
-					      {0.0, 0.0, 0.0, 1.09375e+00, 1.0, 4.6875e-01, -9.375e-02, 0.0, 3.125e-02, 0.0, 0.0, 0.0, -3.125e-02, 1.5625e-01, 0.0},
-					      {0.0, 0.0, 1.0, -5.46875e-01, 0.0, 7.03125e-01, 1.40625e-01, 0.0, 1.5625e-02, 0.0, 0.0, 0.0, -4.6875e-02, -2.34375e-01, 0.0},
-					      {0.0, 0.0, 0.0, 2.1875e-01, 0.0, -1.5625e-01, -9.375e-02, 0.0, 3.125e-02, 0.0, 0.0, 0.0, 9.375e-02, 1.5625e-01, 0.0},
-					      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.625e-01, 0.0, -1.875e-01, 0.0, 0.0, 0.0, 3.75e-01, 9.375e-01, 1.0},
-					      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.625e-01, 0.0, -1.875e-01, 0.0, 0.0, 0.0, -3.75e-01, -3.125e-01, 0.0},
+					      {0.0,  0.0,  0.0,  0.0,  0.0,  0.0, -6.25e-02,  0.0,  1.875e-01,  0.0,  0.0,  0.0,  0.125,  6.25e-02, 0.0},
+					      {0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0, -0.375,  0.0,  0.0,  0.0, -0.125,  0.0, 0.0},
+					      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+					      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+					      {0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0, -0.375,  0.0,  1.0,  0.0,  0.375,  0.0, 0.0},
+					      {0.0,  0.0,  0.0,  0.0,  0.0,  0.0, -6.25e-02,  0.0,  1.875e-01,  0.0,  0.0,  1.0, -0.125,  3.125e-01, 0.0},
+					      {0.0,  0.0,  0.0,  1.093750e+00,  1.0,  4.687500e-01, -9.375e-02,  0.0,  3.125e-02,  0.0,  0.0,  0.0, -3.125e-02,  1.562500e-01, 0.0},
+					      {0.0,  0.0,  1.0, -5.468750e-01,  0.0,  7.031250e-01,  1.406250e-01,  0.0,  1.562500e-02,  0.0,  0.0,  0.0, -4.687500e-02, -2.343750e-01, 0.0},
+					      {0.0,  0.0,  0.0,  2.187500e-01,  0.0, -1.562500e-01, -9.375e-02,  0.0,  3.125e-02,  0.0,  0.0,  0.0,  9.375e-02,  1.562500e-01, 0.0},
+					      {0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  5.625e-01,  0.0, -1.875e-01,  0.0,  0.0,  0.0,  0.375,  9.375e-01, 1.0},
+					      {0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  5.625e-01,  0.0, -1.875e-01,  0.0,  0.0,  0.0, -0.375, -3.125e-01, 0.0},
 					      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 7.5e-01, 0.0, 0.0, 0.0, 7.5e-01, 0.0, 0.0}};
   mtl::dense2D<double> ElInfo2d::mat_d4_left(mat_d4_left_val);
 
-  double ElInfo2d::mat_d4_right_val[15][15] = {{0.0, 0.0, 0.0, -3.90625e-02, 0.0, 2.34375e-02, 2.34375e-02, 0.0, -3.90625e-02, 0.0, 0.0, 0.0, -3.90625e-02, -3.90625e-02, 0.0},
-					       {1.0, 0.0, 0.0, -3.90625e-02, 0.0, 2.34375e-02, -3.90625e-02, 0.0, 2.734375e-01, 0.0, 0.0, 0.0, -3.90625e-02, 2.34375e-02, 0.0},
-					       {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
-					       {0.0, 0.0, 0.0, 1.875e-01, 0.0, -6.25e-02, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 3.125e-01, -1.25e-01, 0.0},
-					       {0.0, 0.0, 0.0, -3.75e-01, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 3.75e-01, 0.0},
-					       {0.0, 0.0, 0.0, 5.0e-01, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
-					       {0.0, 0.0, 0.0, 5.0e-01, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
-					       {0.0, 0.0, 0.0, -3.75e-01, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.25e-01, 0.0},
-					       {0.0, 0.0, 0.0, 1.875e-01, 0.0, -6.25e-02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 6.25e-02, 1.25e-01, 0.0},
-					       {0.0, 0.0, 0.0, 3.125e-02, 0.0, -9.375e-02, -1.5625e-01, 0.0, 2.1875e-01, 0.0, 0.0, 0.0, 1.5625e-01, 9.375e-02, 0.0},
-					       {0.0, 0.0, 1.0, 1.5625e-02, 0.0, 1.40625e-01, 7.03125e-01, 0.0, -5.46875e-01, 0.0, 0.0, 0.0, -2.34375e-01, -4.6875e-02, 0.0},
-					       {0.0, 0.0, 0.0, 3.125e-02, 0.0, -9.375e-02, 4.6875e-01, 1.0, 1.09375e+00, 0.0, 0.0, 0.0, 1.5625e-01, -3.125e-02, 0.0},
-					       {0.0, 0.0, 0.0, -1.875e-01, 0.0, 5.625e-01, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -3.125e-01, -3.75e-01, 0.0},
-					       {0.0, 0.0, 0.0, -1.875e-01, 0.0, 5.625e-01, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 9.375e-01, 3.75e-01, 1.0},
-					       {0.0, 0.0, 0.0, 7.5e-01, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 7.5e-01, 0.0}};
+  double ElInfo2d::mat_d4_right_val[15][15] = {{0.0,  0.0,  0.0, -3.906250e-02,  0.0,  2.343750e-02,  2.343750e-02,  0.0, -3.906250e-02,  0.0,  0.0,  0.0, -3.906250e-02, -3.906250e-02, 0.0},
+						{1.0,  0.0,  0.0, -3.906250e-02,  0.0,  2.343750e-02, -3.906250e-02,  0.0,  2.734375e-01,  0.0,  0.0,  0.0, -3.906250e-02,  2.343750e-02, 0.0},
+						{0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+						{0.0,  0.0,  0.0,  1.875e-01,  0.0, -6.25e-02,  0.0,  0.0,  0.0,  1.0,  0.0,  0.0,  3.125e-01, -0.125, 0.0},
+						{0.0,  0.0,  0.0, -0.375,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  1.0,  0.0,  0.0,  0.375, 0.0},
+						{0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
+						{0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+						{0.0,  0.0,  0.0, -0.375,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0, -0.125, 0.0},
+						{0.0,  0.0,  0.0,  1.875e-01,  0.0, -6.25e-02,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  6.25e-02,  0.125, 0.0},
+						{0.0,  0.0,  0.0,  3.125e-02,  0.0, -9.375e-02, -1.562500e-01,  0.0,  2.187500e-01,  0.0,  0.0,  0.0,  1.562500e-01,  9.375e-02, 0.0},
+						{0.0,  0.0,  1.0,  1.562500e-02,  0.0,  1.406250e-01,  7.031250e-01,  0.0, -5.468750e-01,  0.0,  0.0,  0.0, -2.343750e-01, -4.687500e-02, 0.0},
+						{0.0,  0.0,  0.0,  3.125e-02,  0.0, -9.375e-02,  4.687500e-01,  1.0,  1.093750e+00,  0.0,  0.0,  0.0,  1.562500e-01, -3.125e-02, 0.0},
+						{0.0,  0.0,  0.0, -1.875e-01,  0.0,  5.625e-01,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0, -3.125e-01, -0.375, 0.0},
+						{0.0,  0.0,  0.0, -1.875e-01,  0.0,  5.625e-01,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  9.375e-01,  0.375, 1.0},
+						{0.0, 0.0, 0.0, 7.5e-01, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 7.5e-01, 0.0}};
   mtl::dense2D<double> ElInfo2d::mat_d4_right(mat_d4_right_val);
 
 
@@ -873,39 +873,6 @@ namespace AMDiS {
 
   mtl::dense2D<double>& ElInfo2d::getSubElemGradCoordsMat(int degree) const
   {
-    FUNCNAME("ElInfo2d::getSubElemGradCoordsMat()");
-
-    TEST_EXIT(degree == 1)("Not supported for basis functions with degree > 1!\n");
-
-    using namespace mtl;
-
-    if (subElemGradMatrices[degree].count(std::make_pair(refinementPathLength, refinementPath)) == 0) {
-      dense2D<double> mat(3, 3), tmpMat(3, 3);
-      mat = 1;
-
-      double test_left[3][3] = {{0.0, 0.0, 0.5},
-				{-0.5, -0.5, 0.0},
-				{1.0, 0.0, 0.0}};
-      double test_right[3][3] = {{0.0, 0.0, 0.5},
-				 {0.5, -0.5, 0.0},
-				 {0.0, 1.0, 0.0}};
-      
-      mtl::dense2D<double> mat_left(test_left);
-      mtl::dense2D<double> mat_right(test_right);
-
-
-      for (int i = 0; i < refinementPathLength; i++)
-	if (refinementPath & (1 << i)) {
-	  tmpMat = mat_right * mat;
-	  mat = tmpMat;
-	} else  {
-	  tmpMat = mat_left * mat;
-	  mat = tmpMat;
-	}
-
-      subElemGradMatrices[1][std::make_pair(refinementPathLength, refinementPath)] = mat;
-    }
-
-    return subElemGradMatrices[degree][std::make_pair(refinementPathLength, refinementPath)];
+    return getSubElemCoordsMat(degree);
   }
 }
diff --git a/AMDiS/src/ElInfo3d.cc b/AMDiS/src/ElInfo3d.cc
index f12d656a35b67b2e6d68089081a8b4ed43a2edbd..df70e11ddf8199aca87b75ce7727012901baef8b 100644
--- a/AMDiS/src/ElInfo3d.cc
+++ b/AMDiS/src/ElInfo3d.cc
@@ -824,11 +824,7 @@ namespace AMDiS {
 
   mtl::dense2D<double>& ElInfo3d::getSubElemGradCoordsMat(int degree) const
   {
-    FUNCNAME("ElInfo3d::getSubElemGradCoordsMat()");
-
-    ERROR_EXIT("Not yet implemented!\n");
-
-    return subElemGradMatrices[degree][std::make_pair(refinementPathLength, refinementPath)];
+    return getSubElemCoordsMat(degree);
   }
 
 }
diff --git a/AMDiS/src/Expressions.h b/AMDiS/src/Expressions.h
index a1ea58e15e2b6e32a4ff99eeaeecce0cebfb29d5..cc5771fff66ab2c259d3e0d0c664f7a25a25f1f0 100644
--- a/AMDiS/src/Expressions.h
+++ b/AMDiS/src/Expressions.h
@@ -28,6 +28,7 @@
 #include "AMDiS_fwd.h"
 #include "OperatorTerm.h"
 #include "Functors.h"
+#include "MatrixVectorOperations.h"
 
 #include <boost/static_assert.hpp>
 #include <boost/type_traits.hpp>
@@ -94,6 +95,7 @@
 
 namespace AMDiS {
 
+/// helper class to adopt the correct OperatorTerm based on the term order
 template<int Order>
 struct GetTerm {
   typedef typename boost::mpl::if_c<Order == 0, ZeroOrderTerm, 
@@ -103,19 +105,27 @@ struct GetTerm {
 	  >::type >::type >::type type;
 };
 
-
+/// basic interface for OperatorTerms based on expressions
 template<typename Term, int Order = -1>
 struct GenericOperatorTerm : public GetTerm<Order>::type
 {
   typedef typename GetTerm<Order>::type super;
   
+  /// Expression term stored as copy
   Term term;
+  
+  /// constructor
+  /// adds all feSpaces provided by the expression term to auxFeSpaces liste
   GenericOperatorTerm(const Term& term_)
     : super(term_.getDegree()), term(term_) 
   {
     term.insertFeSpaces(this->auxFeSpaces);
+#ifndef NDEBUG
+    test_auxFeSpaces(this->auxFeSpaces);
+#endif
   }
 
+  /// calls initElement() for \ref term
   void initElement(const ElInfo* elInfo,
 		   SubAssembler* subAssembler,
 		   Quadrature *quad)
@@ -123,6 +133,7 @@ struct GenericOperatorTerm : public GetTerm<Order>::type
     term.initElement(this, elInfo, subAssembler, quad, NULL);
   }
 
+  /// calls initElement() for \ref term
   void initElement(const ElInfo* smallElInfo,
 		   const ElInfo* largeElInfo,
 		   SubAssembler* subAssembler,
@@ -130,9 +141,22 @@ struct GenericOperatorTerm : public GetTerm<Order>::type
   {
     term.initElement(this, smallElInfo, largeElInfo, subAssembler, quad, NULL);
   }
-};
-
 
+  /// test for only one mesh allowed in expressions
+  template<typename FeSpaceList>
+  void test_auxFeSpaces(FeSpaceList const& auxFeSpaces)
+  {
+    typedef typename FeSpaceList::const_iterator fe_iter;
+    if (auxFeSpaces.size() > 0) {
+      Mesh* mesh0 = (*auxFeSpaces.begin())->getMesh();
+      for (fe_iter it = auxFeSpaces.begin(); it != auxFeSpaces.end(); it++) {
+	if ((*it)->getMesh() != mesh0) {
+	  ERROR_EXIT("Only one mesh allowed in expression.\n");
+	}
+      }
+    }
+  }
+};
 
 template<typename Term>
 struct GenericOperatorTerm<Term, -1> : public GenericOperatorTerm<Term, -2>
@@ -687,7 +711,7 @@ template<typename Term>
 inline typename boost::enable_if<typename traits::is_expr<Term>::type, typename Term::value_type>::type
 max(Term term)
 {
-  typename Term::value_type value0 = -1.e25;
+  typename Term::value_type value0 = std::numeric_limits<typename Term::value_type>::min();
   value0 = accumulate(term, functors::max<typename Term::value_type>(), value0);
   
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
@@ -701,7 +725,7 @@ template<typename Term>
 inline typename boost::enable_if<typename traits::is_expr<Term>::type, typename Term::value_type>::type
 min(Term term)
 {
-  typename Term::value_type value0 = 1.e25;
+  typename Term::value_type value0 = std::numeric_limits<typename Term::value_type>::max();
   value0 = accumulate(term, functors::min<typename Term::value_type>(), value0);
   
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
@@ -715,7 +739,7 @@ template<typename Term>
 inline typename boost::enable_if<typename traits::is_expr<Term>::type, typename Term::value_type>::type
 abs_max(Term term)
 {
-  typename Term::value_type value0 = 0.0;
+  typename Term::value_type value0 = 0;
   value0 = accumulate(term, functors::abs_max<typename Term::value_type>(), value0);
   
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
@@ -729,7 +753,7 @@ template<typename Term>
 inline typename boost::enable_if<typename traits::is_expr<Term>::type, typename Term::value_type>::type
 abs_min(Term term)
 {
-  typename Term::value_type value0 = 1.e25;
+  typename Term::value_type value0 = std::numeric_limits<typename Term::value_type>::max();
   value0 = accumulate(term, functors::abs_min<typename Term::value_type>(), value0);
   
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
@@ -744,19 +768,61 @@ abs_min(Term term)
 template<typename T, typename Term>
 inline typename boost::enable_if<
   typename boost::mpl::and_<typename traits::is_expr<Term>::type, 
-			    typename boost::is_convertible<typename Term::value_type, T>::type
+			    typename traits::is_convertible<typename Term::value_type, T>::type
 			    >::type
   >::type
 transformDOF(Term term, DOFVector<T>* result);
 
+/// Assign an expression to a DOFVector (using multi-mesh if term and result vector are on different meshes)
+template<typename T, typename Term>
+inline typename boost::enable_if<
+  typename boost::mpl::and_<typename traits::is_expr<Term>::type, 
+			    typename traits::is_convertible<typename Term::value_type, T>::type
+			    >::type
+  >::type
+transformDOF_mm(Term term, DOFVector<T>* result);
+
 /// Assign an expression to a DOFVector
 template<typename T, typename Term>
 typename boost::enable_if<
   typename boost::mpl::and_<typename traits::is_expr<Term>::type, 
-			    typename boost::is_convertible<typename Term::value_type, T>::type
+			    typename traits::is_convertible<typename Term::value_type, T>::type
 			    >::type,
   DOFVector<T>& >::type
-operator<<(DOFVector<T>& result, const Term& term);
+operator<<(DOFVector<T>& result, const Term& term)
+{
+  transformDOF(term, &result);
+  return result;
+}
+
+
+/// Assign a constant value to a DOFVector
+// template<typename T, typename S>
+// typename boost::enable_if<
+//   typename boost::mpl::or_<
+//     typename boost::mpl::and_<
+//       typename traits::is_scalar<T>::type,       
+//       typename traits::is_scalar<S>::type,
+//       typename boost::is_convertible<S, T>::type
+//       >::type,
+//     typename boost::mpl::and_<
+//       typename traits::is_vector<T>::type,       
+//       typename traits::is_vector<S>::type,
+//       typename boost::is_convertible<typename S::value_type, typename T::value_type>::type
+//       >::type,
+//     typename boost::mpl::and_<
+//       typename traits::is_matrix<T>::type,       
+//       typename traits::is_matrix<S>::type,
+//       typename boost::is_convertible<typename S::value_type, typename T::value_type>::type
+//       >::type
+//     >::type,
+//   DOFVector<T>& // return type
+//   >::type
+// operator<<(DOFVector<T>& result, const S& value)
+// {
+//   result.set(value);
+//   return result;
+// }
 
 // -----------------------------------------------------------------------------
 
@@ -764,7 +830,11 @@ operator<<(DOFVector<T>& result, const Term& term);
 template<typename Term>
 typename boost::enable_if<typename traits::is_expr<Term>::type, 
 			  std::ostream& >::type
-operator<<(std::ostream& result, const Term& term);
+operator<<(std::ostream& result, const Term& term)
+{
+  result << term.str();
+  return result;
+}
 
 } // end namespace AMDiS
 
diff --git a/AMDiS/src/Expressions.hh b/AMDiS/src/Expressions.hh
index 22c4fb163be3fb4d2c2b02191735eed8927364d1..7d7c7c65404925d8966edbb3ae4fa329d6ba9fd5 100644
--- a/AMDiS/src/Expressions.hh
+++ b/AMDiS/src/Expressions.hh
@@ -23,36 +23,6 @@
 /** \file Expressions.hh */
 
 namespace AMDiS {
-  
-#if 0
-namespace detail {
-  
-  template<typename Term, typename T, typename Enable = void>
-  struct GenericOperatorTerm { };
-  
-  template<typename Term, typename T>
-  struct GenericOperatorTerm<Term, T, typename boost::enable_if<traits::is_scalar<T> >::type> { 
-    typedef GenericZeroOrderTerm<Term> type;
-  };
-  
-  template<typename Term, typename T>
-  struct GenericOperatorTerm<Term, T, typename boost::enable_if<traits::is_vector<T> >::type> { 
-    typedef GenericFirstOrderTerm_b<Term> type;
-  };
-  
-  template<typename Term, typename T >
-  struct GenericOperatorTerm<Term, T, typename boost::enable_if<traits::is_matrix<T> >::type> { 
-    typedef GenericSecondOrderTerm_A<Term, true> type;
-  };
-  
-} // end namespace detail
-
-template<typename Term>
-struct GenericOperatorTerm { 
-  typedef typename detail::GenericOperatorTerm<Term, typename Term::value_type>::type type;
-};
-#endif
-
 
 template<typename Term>
 inline typename boost::enable_if<typename traits::is_expr<Term>::type, typename Term::value_type>::type
@@ -139,32 +109,38 @@ accumulate(Term term, Functor f, typename Term::value_type value0)
 template<typename T, typename Term>
 inline typename boost::enable_if<
   typename boost::mpl::and_<typename traits::is_expr<Term>::type, 
-			    typename boost::is_convertible<typename Term::value_type, T>::type
+			    typename traits::is_convertible<typename Term::value_type, T>::type
 			    >::type
   >::type
 transformDOF(Term term, DOFVector<T>* result)
 {
-  typedef typename Term::value_type TOut;
-  TOut tmp; nullify(tmp);
+  GenericOperatorTerm<Term> ot(term);
+  std::set<const FiniteElemSpace*> feSpaces = ot.getAuxFeSpaces();
   
+  Mesh* mesh = result->getFeSpace()->getMesh();
+  if (feSpaces.size() > 0 && mesh != (*feSpaces.begin())->getMesh())
+    return transformDOF_mm(term, result);
+  
+  
+  typedef typename Term::value_type TOut;
   DOFVector<TOut> temp(result->getFeSpace(), "temp");
   DOFVector<int> assigned(result->getFeSpace(), "assigned");
   
-  GenericOperatorTerm<Term> ot(term);
-  Mesh* mesh = result->getFeSpace()->getMesh();
-  
   const FiniteElemSpace* resultFeSpace = temp.getFeSpace();
   const BasisFunction *basisFcts = resultFeSpace->getBasisFcts();  
   int nBasisFcts = basisFcts->getNumber();
   
-  assigned.set(0);
-  temp.set(tmp);
-  
   std::vector<DegreeOfFreedom> localIndices(nBasisFcts);
   TraverseStack stack;
   ElInfo *elInfo = stack.traverseFirst(mesh, -1,
 					Mesh::CALL_LEAF_EL | 
 					Mesh::FILL_COORDS | Mesh::FILL_GRD_LAMBDA);
+  term.initElement(&ot, elInfo, NULL, NULL, basisFcts);
+  
+  
+  TOut tmp(term(0)); nullify(tmp);
+  assigned.set(0);
+  temp.set(tmp);
   
   while (elInfo) {
     term.initElement(&ot, elInfo, NULL, NULL, basisFcts);
@@ -187,31 +163,88 @@ transformDOF(Term term, DOFVector<T>* result)
   DOFIterator<T> resultIter(result, USED_DOFS);
   DOFIterator<int> assignedIter(&assigned, USED_DOFS);
   for (tempIter.reset(), resultIter.reset(), assignedIter.reset(); !resultIter.end(); ++tempIter, ++resultIter, ++assignedIter) {
-    *resultIter = (*tempIter) * (1.0/static_cast<double>(*assignedIter));
+    *resultIter = (*tempIter);
+    *resultIter/= (*assignedIter);
   }
 }
 
 
+
+// works only for nodal basis functions!
 template<typename T, typename Term>
-typename boost::enable_if<
+inline typename boost::enable_if<
   typename boost::mpl::and_<typename traits::is_expr<Term>::type, 
-			    typename boost::is_convertible<typename Term::value_type, T>::type
-			    >::type,
-  DOFVector<T>& >::type
-operator<<(DOFVector<T>& result, const Term& term)
+			    typename traits::is_convertible<typename Term::value_type, T>::type
+			    >::type
+  >::type
+transformDOF_mm(Term term, DOFVector<T>* result)
 {
-  transformDOF(term, &result);
-  return result;
-}
+  typedef typename Term::value_type TOut;
+  
+  GenericOperatorTerm<Term> ot(term);
+  std::set<const FiniteElemSpace*> feSpaces = ot.getAuxFeSpaces();
+  
+  Mesh* mesh1 = result->getFeSpace()->getMesh();
+  Mesh* mesh2 = (*feSpaces.begin())->getMesh();
+  
+  DOFVector<TOut> temp(result->getFeSpace(), "temp");
+  DOFVector<int> assigned(result->getFeSpace(), "assigned");
+  
+  const FiniteElemSpace* resultFeSpace = temp.getFeSpace();
+  const BasisFunction *basisFcts = resultFeSpace->getBasisFcts();  
+  int nBasisFcts = basisFcts->getNumber();
+    
+  std::vector<DegreeOfFreedom> localIndices(nBasisFcts);
+  mtl::dense_vector<TOut> vecLocalCoeffs(nBasisFcts);
 
+  DimVec<double> *lambda = NULL;
+  DimVec<double> *lambda_1 = new DimVec<double>;
+  WorldVector<double> coords;
+	  
+  DualTraverse dualTraverse;
+  DualElInfo dualElInfo;
+  
+  Flag assembleFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_GRD_LAMBDA;
+  bool cont = dualTraverse.traverseFirst(mesh1, mesh2, -1, -1, 
+					  assembleFlag, assembleFlag, dualElInfo);
+  term.initElement(&ot, dualElInfo.colElInfo, NULL, NULL, basisFcts);
+  
+  TOut tmp(term(0)); nullify(tmp);
+  assigned.set(0);
+  temp.set(tmp);
+  
+  while (cont) {      
+    term.initElement(&ot, dualElInfo.colElInfo, NULL, NULL, basisFcts);
+    basisFcts->getLocalIndices(dualElInfo.rowElInfo->getElement(), resultFeSpace->getAdmin(), localIndices);
+    
+    for (int i = 0; i < nBasisFcts; i++)
+      vecLocalCoeffs[i] = term(i);
+    
+    for (int i = 0; i < nBasisFcts; i++) {
+      lambda = basisFcts->getCoords(i);
+      dualElInfo.rowElInfo->coordToWorld(*lambda, coords);
+      int inside = dualElInfo.colElInfo->worldToCoord(coords, lambda_1);
+      if (inside < 0) {
+	temp[localIndices[i]] += basisFcts->evalUh(*lambda_1, vecLocalCoeffs);
+	assigned[localIndices[i]]++;
+      }
+    }
+    cont = dualTraverse.traverseNext(dualElInfo);
+  }
 
-template<typename Term>
-typename boost::enable_if<typename traits::is_expr<Term>::type, 
-			  std::ostream& >::type
-operator<<(std::ostream& result, const Term& term)
-{
-  result << term.str();
-  return result;
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+  Parallel::MeshDistributor::globalMeshDistributor->synchAddVector(temp);
+  Parallel::MeshDistributor::globalMeshDistributor->synchAddVector(assigned);
+#endif
+  
+  
+  DOFIterator<TOut> tempIter(&temp, USED_DOFS);
+  DOFIterator<T> resultIter(result, USED_DOFS);
+  DOFIterator<int> assignedIter(&assigned, USED_DOFS);
+  for (tempIter.reset(), resultIter.reset(), assignedIter.reset(); !resultIter.end(); ++tempIter, ++resultIter, ++assignedIter) {
+    *resultIter = (*tempIter);
+    *resultIter/= (*assignedIter);
+  }
 }
 
 } // end namespace AMDiS
diff --git a/AMDiS/src/FirstOrderTerm.h b/AMDiS/src/FirstOrderTerm.h
index 3915ee6ffede5e236bce29562f4b7ea5ae001f76..a3439635c8ff6b477f7d27f0070a43705124b3f1 100644
--- a/AMDiS/src/FirstOrderTerm.h
+++ b/AMDiS/src/FirstOrderTerm.h
@@ -31,6 +31,7 @@
 #include "AbstractFunction.h"
 #include "ElInfo.h"
 #include "traits/size.hpp"
+#include "MatrixVectorOperations.h"
 
 namespace AMDiS {
 
diff --git a/AMDiS/src/FixVec.h b/AMDiS/src/FixVec.h
index 3828213ae4c46202ff52d98637be201539b31c57..c8986d4ead16f4739aaa38e8a96a459ed204d8dc 100644
--- a/AMDiS/src/FixVec.h
+++ b/AMDiS/src/FixVec.h
@@ -69,7 +69,7 @@ namespace AMDiS {
       : Vector<T>(calcSize(dim))
     {
       TEST_EXIT_DBG(initType == VALUE_LIST)("wrong initType or wrong initializer\n");
-      setValues(ini);
+      this->setValues(ini);
     }
 
     /// constructor with default value initialisation. initType must be
@@ -144,7 +144,7 @@ namespace AMDiS {
     /// constructs a VectorOfFixVecs via an value list.  dim is passed to 
     /// FixVec's constructors. size_ is the number of contained FixVecs. initType
     /// must be VALUE_LIST. ini contains the initialisation values.
-    VectorOfFixVecs(int d, int s, InitType initType, const FixVecType* ini)
+    VectorOfFixVecs(int d, int s, InitType initType, FixVecType const* ini)
       : size(s),
 	dim(d)
     {
@@ -341,7 +341,7 @@ namespace AMDiS {
     {}
 
     /// Calls the corresponding constructor of FixVec
-    DimVec(int dim, InitType initType, T* ini)
+    DimVec(int dim, InitType initType, T const* ini)
       : FixVec<T,PARTS>(dim, initType, ini)
     {}
 
@@ -378,7 +378,7 @@ namespace AMDiS {
     }
 
     /// Calls the corresponding constructor of VectorOfFixVecs
-    DimMat(int dim, InitType initType, T* ini)
+    DimMat(int dim, InitType initType, T const* ini)
       : Matrix<T>(dim + 1, dim + 1)
     {
       TEST_EXIT_DBG(initType == VALUE_LIST)("wrong initType or wrong initializer\n");
@@ -396,28 +396,61 @@ namespace AMDiS {
   class WorldVector : public FixVec<T, WORLD>
   {
   public:
+    typedef WorldVector       self;
+    typedef FixVec<T, WORLD>  super;
+  
     /// Calls the corresponding constructor of AlgoVec
     WorldVector() 
-      : FixVec<T, WORLD>(Global::getGeo(WORLD), NO_INIT) 
+      : super(Global::getGeo(WORLD), NO_INIT) 
     {}
 
     /// Calls the corresponding constructor of AlgoVec
-    WorldVector(InitType initType, T* ini) 
-      : FixVec<T, WORLD>(Global::getGeo(WORLD), initType, ini)
+    WorldVector(InitType initType, T const* ini) 
+      : super(Global::getGeo(WORLD), initType, ini)
     {}
 
     /// Calls the corresponding constructor of AlgoVec
     WorldVector(InitType initType, const T& ini)
-      : FixVec<T, WORLD>(Global::getGeo(WORLD), initType, ini)
+      : super(Global::getGeo(WORLD), initType, ini)
+    {}
+    
+    
+//     /// Copy constructor for other of different value_type
+//     template <typename S>
+//     WorldVector(Vector<S> const& other)
+//       : super(Global::getGeo(WORLD), NO_INIT) 
+//     {
+//       operator=(other);
+//     }
+//     
+    /// Copy constructor for other of same value_type
+    WorldVector(self const& other)
+      : super(other) 
     {}
+      
+    
+    /// Assignement operator
+    template <typename S>
+    inline self& operator=(const Vector<S>& rhs) 
+    {
+      this->setValues(rhs.getValArray());
+      return *this;
+    }
+    
+    /// Assignement operator
+    inline self& operator=(const self& rhs) 
+    {
+      this->setValues(rhs.getValArray());
+      return *this;
+    }
 
-    /// Sets all entries to d
+    /// Sets all entries to scal
     template <typename S>
-    inline const WorldVector<T>&
-    operator=(const S& d)
+    typename enable_if<boost::is_convertible<S, T>, WorldVector<T> >::type &
+    operator=(S scal)
     {
-      this->set(d);
-      return (*this);
+      this->set(scal);
+      return *this;
     }
 
     /// Sets the arrays value to the geometric midpoint of the points  p1 and p2.
@@ -447,17 +480,20 @@ namespace AMDiS {
   class WorldMatrix : public Matrix<T>
   {
   public:
+    typedef WorldMatrix   self;
+    typedef Matrix<T>     super;
+    
     /// Calls the corresponding constructor of FixVec
     WorldMatrix()
-      : Matrix<T>(Global::getGeo(WORLD), Global::getGeo(WORLD))
+      : super(Global::getGeo(WORLD), Global::getGeo(WORLD))
     {}
 
     /// Calls the corresponding constructor of FixVec
     WorldMatrix(InitType initType, T* ini)
-      : Matrix<T>(Global::getGeo(WORLD), Global::getGeo(WORLD))
+      : super(Global::getGeo(WORLD), Global::getGeo(WORLD))
     {
       TEST_EXIT_DBG(initType == VALUE_LIST)("???\n");
-      setValues(ini);
+      this->setValues(ini);
     }
 
     /** \brief
@@ -465,14 +501,48 @@ namespace AMDiS {
      * to ini
      */
     WorldMatrix(InitType initType, const T& ini)
-      : Matrix<T>(Global::getGeo(WORLD), Global::getGeo(WORLD))
+      : super(Global::getGeo(WORLD), Global::getGeo(WORLD))
     {
       TEST_EXIT_DBG(initType == DEFAULT_VALUE)("wrong initType or wrong initializer\n");
       this->set(ini);
     }
     
-    // import assignment operator from base class
-    using Matrix<T>::operator=;
+//     /// Copy constructor for other of different value_type
+//     template <typename S>
+//     WorldMatrix(Matrix<S> const& other)
+//       : super(Global::getGeo(WORLD), Global::getGeo(WORLD)) 
+//     {
+//       this->setValues(other.getValArray());
+//     }
+//     
+//     /// Copy constructor 
+    WorldMatrix(self const& other)
+      : super(other) 
+    { }
+    
+    /// Assignement operator
+    template <typename S>
+    inline self& operator=(const Matrix<S>& rhs) 
+    {
+      this->setValues(rhs.getValArray());
+      return *this;
+    }
+    
+    /// Assignement operator
+    inline self& operator=(const self& rhs) 
+    {
+      this->setValues(rhs.getValArray());
+      return *this;
+    }
+    
+    /// Assignement operator for scalars
+    template <typename S>
+    typename enable_if<boost::is_convertible<S, T>, WorldMatrix<T> >::type &
+    operator=(S rhs) 
+    {
+      this->set(rhs);
+      return *this;
+    }
   
     /// Returns true if the matrix is a diagonal matrix, returns false otherwise.
     bool isDiagMatrix() const;
@@ -495,12 +565,6 @@ namespace AMDiS {
     void vecProduct(const WorldVector<T>& v1, const WorldVector<T>& v2);
   };
 
-
-
-  /// returns the euclidian distance of a and b
-  template<typename T, GeoIndex d>
-  double absteukl(const FixVec<T,d>& a, const FixVec<T,d>& b);
-
   /// FixVec operator for stream output
   template<typename T, GeoIndex d>
   std::ostream& operator <<(std::ostream& out, const FixVec<T,d>& fixvec)
@@ -517,177 +581,6 @@ namespace AMDiS {
   /// creates and inits and double array
   double *createAndInitArray(int size, ...); 
 
-  template<typename T>
-  WorldVector<T> operator*(const WorldVector<T>& v, double d)
-  {
-    WorldVector<T> result = v;
-    result *= d;
-    return result;
-  }
-
-  template<typename T>
-  WorldVector<T> operator*(double d, const WorldVector<T>& v)
-  {
-    return v * d;
-  }
-  
-  template<typename T>
-  WorldVector<T> operator/(const WorldVector<T>& v, double d)
-  {
-    WorldVector<T> result = v;
-    result = v * (1.0/d);
-    return result;
-  }
-
-  template<typename T>
-  WorldVector<T>& operator+=(WorldVector<T>& v1,
-			     const WorldVector<T>& v2)
-  {
-    add(v1, v2, v1);
-    return v1;
-  }
-
-  template<typename T>
-  WorldVector<T>& operator-=(WorldVector<T>& v1,
-			     const WorldVector<T>& v2)
-  {
-    axpy(-1.0, v2, v1);
-    return v1;
-  }
-
-  template<typename T>
-  WorldVector<T> operator+(const WorldVector<T>& v1,
-			   const WorldVector<T>& v2)
-  {
-    WorldVector<T> result = v1;
-    result += v2;
-    return result;
-  }
-
-  template<typename T>
-  WorldVector<T> operator-(const WorldVector<T>& v1,
-			   const WorldVector<T>& v2)
-  {
-    WorldVector<T> result = v1;
-    result -= v2;
-    return result;
-  }
-
-  inline bool operator<(const WorldVector<double>& v1, const WorldVector<double>& v2) 
-  {
-    int dow = Global::getGeo(WORLD);
-    for (int i = 0; i < dow; i++) {
-      if (abs(v1[i] - v2[i]) < DBL_TOL) 
-	continue;
-      return v1[i] < v2[i];
-    }
-    return false;
-  }
-
-  inline bool operator==(const WorldVector<double>& v1, const WorldVector<double>& v2) 
-  {
-    int dow = Global::getGeo(WORLD);
-    for (int i = 0; i < dow; i++)
-      if (abs(v1[i] - v2[i]) > DBL_TOL) 
-	return false;
-
-    return true;
-  }
-
-  template<typename T>
-  WorldMatrix<T>& operator*=(WorldMatrix<T>& m, T scal);
-
-  template<typename T>
-  WorldMatrix<T>& operator-=(WorldMatrix<T>& m1, const WorldMatrix<T>& m2);
-
-  template<typename T>
-  WorldMatrix<T>& operator+=(WorldMatrix<T>& m1, const WorldMatrix<T>& m2);
-
-  template<typename T>
-  WorldMatrix<T> operator*(WorldMatrix<T> v, double d)
-  {
-    v *= d;
-    return v;
-  }
-
-  template<typename T>
-  WorldMatrix<T> operator*(double d, WorldMatrix<T> v)
-  {
-    v *= d;
-    return v;
-  }
-
-  template<typename T>
-  WorldMatrix<T> operator/(WorldMatrix<T> v, double d)
-  {
-    v *= 1./d;
-    return v;
-  }
-
-  template<typename T>
-  WorldVector<T> operator*(const WorldMatrix<T>& M, const WorldVector<T>& v )
-  {
-      WorldVector<T> res;
-      res.multMatrixVec(M,v);
-      return res;
-  }
-
-  template<typename T>
-  WorldMatrix<T> operator+(WorldMatrix<T> M1, const WorldMatrix<T>& M2 )
-  {
-    M1 += M2;
-    return M1;
-  }
-
-  template<typename T>
-  WorldMatrix<T> operator-(WorldMatrix<T> M1, const WorldMatrix<T>& M2 )
-  {
-    M1 -= M2;
-    return M1;
-  }
-
-  template<typename T>
-  WorldVector<WorldVector<T> > 
-  operator*(const WorldVector<WorldVector<T> >& A, const WorldVector<WorldVector<T> >& B)
-  {
-    WorldVector<WorldVector<T> > result;
-    nullify(result);
-    for (size_t r = 0; r < num_rows(A); r++)
-      for (size_t c = 0; c < num_cols(A); c++)
-	for (size_t i = 0; i < num_cols(A); i++)
-	  result[r][c] += A[r][i] * B[i][c];
-    return result;
-  }
-  
-  template<typename T>
-  void set_to_zero(WorldVector<WorldVector<T> >& mat)
-  {
-    nullify(mat);
-  }
-
-  template<typename T>
-  WorldVector<T> operator-(WorldVector<T> v)
-  {
-    v *= -1.0;
-    return v;
-  }
-
-  template<typename T>
-  WorldMatrix<T> operator-(WorldMatrix<T> v)
-  {
-    v *= -1.0;
-    return v;
-  }
-
-  inline double norm(const WorldVector<double>& v)
-  {
-    double val = 0.0;
-    for (int i = 0; i < Global::getGeo(WORLD); i++)
-      val += v[i] * v[i];
-    return sqrt(val);
-  }
-
-
   template<typename T>
   struct GradientType
   {
@@ -772,8 +665,6 @@ namespace mtl
   } // end namespace traits
 } // end namespace mtl
 
-
-
 #include "FixVec.hh"
 
 #endif // AMDIS_FIXVEC_H
diff --git a/AMDiS/src/FixVec.hh b/AMDiS/src/FixVec.hh
index 98b9aaebb1e053987b1839da5e1a606db6a4f368..24704567cc6d492758472a2762d99692e9dab5b7 100644
--- a/AMDiS/src/FixVec.hh
+++ b/AMDiS/src/FixVec.hh
@@ -34,17 +34,6 @@ namespace AMDiS {
     }
   }
 
-  template<typename T, GeoIndex d>
-  double absteukl(const FixVec<T,d>& a,const FixVec<T,d>& b)
-  {
-    double erg = 0.0;
-
-    for (int i = 0; i < a.getSize() ; i++)
-      erg = erg + ((a[i] - b[i]) * (a[i] - b[i]));
-
-    return sqrt(erg);
-  }
-
   template<typename T>
   void WorldVector<T>::multMatrixVec(const WorldMatrix<T> &m, const WorldVector<T> &v)
   {
@@ -107,36 +96,4 @@ namespace AMDiS {
 	*thisIt = *v1It * *v2It;
   }
   
-  template<typename T>
-  WorldMatrix<T>& operator*=(WorldMatrix<T>& m, T scal)
-  {
-    for (T* mIt = m.begin(); mIt != m.end(); mIt++)
-      *mIt *= scal;
-
-    return m;
-  }
-
-  template<typename T>
-  WorldMatrix<T>& operator-=(WorldMatrix<T>& m1, const WorldMatrix<T>& m2)
-  {
-    T *m1It, *m2It;
-    for (m1It = m1.begin(), m2It = m2.begin();
-	 m1It != m1.end(); 
-	 m1It++, m2It++)
-      *m1It -= *m2It;
-
-    return m1;
-  }
-
-  template<typename T>
-  WorldMatrix<T>& operator+=(WorldMatrix<T>& m1, const WorldMatrix<T>& m2)
-  {
-    T* m1It, *m2It;
-    for (m1It = m1.begin(), m2It = m2.begin();
-	 m1It != m1.end(); 
-	 m1It++, m2It++)
-      *m1It += *m2It;
-
-    return m1;
-  }
 }
diff --git a/AMDiS/src/Global.h b/AMDiS/src/Global.h
index 42405845a9cc5ed8144a3c8f22ab26efa86ed57f..2f44fdc50c4b19a315bf2039f165afa83fdbed67 100644
--- a/AMDiS/src/Global.h
+++ b/AMDiS/src/Global.h
@@ -31,29 +31,7 @@
 #ifndef AMDIS_GLOBAL_H
 #define AMDIS_GLOBAL_H
 
-#if (__GNUC__) && (__GNUC__ > 2) 
-#define OPENMODE std::ios::openmode
-#else
-#define OPENMODE std::ios::open_mode
-#endif
-
-#include <boost/config.hpp>
-
-// TODO: better c++11 test!
-#if (defined BOOST_NO_CXX11_OVERRIDE) || __cplusplus <= 199711L || ((defined _MSC_VER) && _MSC_VER < 1100)
-  #define override 
-#endif
-#if !((defined BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_DECLTYPE))
-  #define HAS_CPP11_DECLTYPE
-#endif
-#if !((defined BOOST_NO_CXX11_VARIADIC_TEMPLATES) || (defined BOOST_NO_VARIADIC_TEMPLATES)) || (defined BOOST_HAS_VARIADIC_TMPL)
-  #define HAS_VARIADIC_TEMPLATES
-#endif
-
-/** \brief current AMDiS version */
-#ifndef AMDIS_VERSION
-#define AMDIS_VERSION  "AMDiS: Version 0.9.1"
-#endif
+#include "Config.h"
 
 #include <string>
 #include <vector>
@@ -66,7 +44,7 @@
 #include <float.h>
 #include <time.h>
 
-#ifdef _WIN32
+#ifdef _MSC_VER
 #include <io.h>
 #else
 #include <unistd.h>
@@ -87,7 +65,7 @@ namespace AMDiS {
 
   extern const char *funcName;
 
-  const int amdisRevisionNumber = 1700;
+  const int amdisRevisionNumber = 1700; // TODO: how to update this value
 
   /// Used by matrix vector multiplication
   typedef enum { NoTranspose,
@@ -179,7 +157,7 @@ namespace AMDiS {
   /// check for file existence
   inline bool file_exists(const std::string filename)
   {
-#ifdef _WIN32
+#ifdef _MSC_VER
     return _access(filename.c_str(), 0) == 0;
 #else
     return access(filename.c_str(), F_OK) == 0;
@@ -470,7 +448,9 @@ namespace AMDiS {
       BOUNDARY =-5, /**< index for boundary nodes of an element. This could be
 		     * vertices, edges or faces.
 		     */
-      PROJECTION=-6 /**< index for element and boundary projections */
+      PROJECTION=-6, /**< index for element and boundary projections */
+      
+      NO_INDEX =-127
     } GeoIndex;
 
 #define MAXPART FACE
diff --git a/AMDiS/src/MacroElement.h b/AMDiS/src/MacroElement.h
index 7dd5996ca20eb288f96eb5b74029da4ccdbb42c9..d2e2c0ed5949b5ba96e0aa8885fa23382f861e22 100644
--- a/AMDiS/src/MacroElement.h
+++ b/AMDiS/src/MacroElement.h
@@ -82,6 +82,15 @@ namespace AMDiS {
       return neighbour[i];
     }
 
+    /// Returns the i-th inverse neighbour of this MacroElement \ref neighbour_inv[i]
+    /// Uses the inverse neighbour relation in graph-structured meshes where
+    /// elements can have more than one neighbour
+    /// If [b] is neighbour of [a], then is [a] neighbour_inv of [b]
+    inline MacroElement* getNeighbourInv(int i) const 
+    {
+      return neighbour_inv[i];
+    }
+
     /// Returns the i-th opp-vertex of this MacroElement \ref oppVertex[i]
     inline int getOppVertex(int i) const 
     {
@@ -202,6 +211,9 @@ namespace AMDiS {
     /// Pointers to all neighbours of this MacroElement 
     FixVec<MacroElement*, NEIGH> neighbour;
 
+    /// Pointers to all neighbours of this MacroElement 
+    FixVec<MacroElement*, NEIGH> neighbour_inv;
+    
     /// opp vertices of this MacroElement
     FixVec<int, NEIGH> oppVertex;
 
diff --git a/AMDiS/src/MatrixVector.h b/AMDiS/src/MatrixVector.h
index 354c67511d7c7abb29a6fd692fac06d72d4b4941..b502ddcf102d368f4903b632fde8d3b2a12ee42a 100644
--- a/AMDiS/src/MatrixVector.h
+++ b/AMDiS/src/MatrixVector.h
@@ -29,6 +29,7 @@
 #include "Global.h"
 #include "AMDiS_fwd.h"
 #include "Serializable.h"
+#include "traits/basic.hpp" // not dependenciess on other AMDiS types
 
 namespace AMDiS {
 
@@ -38,17 +39,43 @@ namespace AMDiS {
   {
   public:
     
-    typedef T value_type;
+    typedef T       value_type;
+    typedef Vector  self;
     
     /// Constructor.
     Vector(int i = 0) 
-      : size(i),
+      : size(0),
 	valArray(NULL)
     {
-      if (size == 0) 
+      resize(i);
+    }
+
+    /// Copy constructor.
+    Vector(self const& rhs) 
+      : Serializable(),
+	size(rhs.getSize()),
+	valArray(new T[rhs.getSize()])
+    {
+      setValues(rhs.getValArray());
+    }
+    
+    /// Copy constructor for other of different value_type
+    template <typename S>
+    Vector(Vector<S> const& rhs)
+      : Serializable(),
+	size(rhs.getSize()),
+	valArray(new T[rhs.getSize()])
+    {
+      setValues(rhs.getValArray());
+    }
+
+    /// Destructor.
+    virtual ~Vector() 
+    {
+      if (valArray != NULL) {
+	delete [] valArray; 
 	valArray = NULL;
-      else
-	valArray = new T[size];
+      }
     }
 
     inline bool used() const 
@@ -59,7 +86,7 @@ namespace AMDiS {
     /// Change the size of the vector to newSize.
     inline void resize(int newSize) 
     {
-      if (size != newSize) {
+      if (size != newSize && newSize > 0) {
 	if (valArray != NULL) 
 	  delete [] valArray;
 	valArray = new T[newSize];
@@ -67,42 +94,25 @@ namespace AMDiS {
       }
     }
 
-    /// Copy constructor.
-    Vector(const Vector<T>& rhs) 
-      : Serializable(),
-	size(rhs.size)
+    /// Assignement operator
+    template <typename S>
+    inline self& operator=(Vector<S> const& rhs) 
     {
-      valArray = new T[rhs.size];
-      *this = rhs; // uses operator=()
-    }
-
-    /// Destructor.
-    virtual ~Vector() 
-    { 
-      if (valArray != NULL) {
-	delete [] valArray; 
-	valArray = NULL;
-      }
+      resize(rhs.getSize());
+      this->setValues(rhs.getValArray());
+      return *this;
     }
-
-    /// Assignement operator
-    inline const Vector<T>& operator=(const Vector<T>& rhs) 
+    
+    inline self& operator=(self const& rhs) 
     {
-      TEST_EXIT_DBG(rhs.size == size)
-	("Invalid sizes %d != %d!\n", rhs.size, size);
-
-      T *rhsIt, *thisIt;
-      for (rhsIt = rhs.begin(), thisIt = this->begin();
-	   rhsIt != rhs.end();
-	   ++rhsIt, ++thisIt)
-	*thisIt = *rhsIt;      
-
+      resize(rhs.getSize());
+      this->setValues(rhs.getValArray());
       return *this;
     }
 
-    /// Assignement operator
+    /// Assignement operator for scalars
     template <typename S>
-    inline const Vector<T>&
+    typename enable_if<boost::is_convertible<S, T>, Vector<T> >::type &
     operator=(const S& scal) 
     {
       for (T *thisIt = this->begin(); thisIt != this->end(); ++thisIt)
@@ -112,54 +122,52 @@ namespace AMDiS {
     }
 
     /// Assignement operator
-    inline const Vector<T>& operator=(const T* vec) 
+    inline self& operator=(const T* vec) 
     {
-      T *thisIt;
-      const T *vecIt;
-      for (thisIt = this->begin(), vecIt = &vec[0];
-	   thisIt != this->end();
-	   ++thisIt, ++vecIt)
-	*thisIt = *vecIt;
-
+      this->setValues(vec);
       return *this;
     }
 
     /// Sets all entries to scal.
     template <typename S>
-    inline typename boost::disable_if<boost::mpl::and_<boost::is_integral<S>, boost::is_pointer<T> >, const Vector<T>& >::type
-    set(const S& scal) 
+    inline typename disable_if<and_<boost::is_integral<S>, boost::is_pointer<T> >, Vector<T>& >::type
+    set(S const& scal) 
     {
       return *this = scal;
     }
     
-    inline const Vector<T>& set(const T& scal) 
+    inline Vector<T>& set(T const& scal) 
     {
       return *this = scal;
     }
     
+    void setValues_aux(const T* values, true_) // trivially copyable
+    {
+      std::memcpy(valArray, values, sizeof(T)*size);
+    }
+    
+    template <typename S>
+    void setValues_aux(const S* values, false_) // NOT trivially copyable
+    {
+      std::copy(values, values + size, valArray);
+    }
 
     /// Sets all entries.
-    inline const Vector<T>& setValues(const T* values) 
-    {
-      T *thisIt;
-      const T *valuesIt;
-      for (thisIt = this->begin(), valuesIt = values; 
-	   thisIt != this->end(); 
-	   ++thisIt, ++valuesIt) 
-	*thisIt = *valuesIt;
-	
-      return *this;
+    template <typename S>
+    void setValues(const S* values) 
+    {
+      typedef typename and_< boost::is_same<S,T>, traits::is_trivially_copyable<S> >::type  use_memcpy;
+      setValues_aux(values, use_memcpy());
     }
 
     /// Sets all entries.
-    inline void fill(const T value) 
+    inline void fill(T value) 
     {
-      for (T *thisIt = this->begin(); thisIt != this->end(); thisIt++)
-	*thisIt = value;
+      std::fill(valArray, valArray + size, value);
     }
 
     /// Comparison operator.
-    inline bool operator==(const Vector<T>& rhs) const 
+    inline bool operator==(Vector<T> const& rhs) const 
     {
       if (size != rhs.size) 
 	return false;
@@ -175,7 +183,7 @@ namespace AMDiS {
     }
 
     /// Comparison operator.
-    inline bool operator!=(const Vector<T>& rhs) const 
+    inline bool operator!=(Vector<T> const& rhs) const 
     {
       return !(*this==rhs);
     }
@@ -207,13 +215,18 @@ namespace AMDiS {
     }
 
     /// Returns \ref size.
-    virtual int getSize() const 
+    inline int getSize() const 
     { 
       return size; 
     }
 
     /// Returns \ref valArray as T-array
-    inline T *getValArray() 
+    inline T* getValArray() 
+    { 
+      return valArray; 
+    }
+    
+    inline T const* getValArray() const
     { 
       return valArray; 
     }
@@ -257,12 +270,26 @@ namespace AMDiS {
   class Matrix : public Vector<T>
   {
   public:
+    typedef Matrix     self;
+    typedef Vector<T>  super;
+  
+    /// Default constructor.
+    Matrix()
+      : Vector<T>(0), rows(0), cols(0)
+    {}
+    
     /// Constructor.
     Matrix(int r, int c)
-      : Vector<T>(r * c), 
+      : super(r * c), 
 	rows(r),
 	cols(c)
     {}
+    
+    Matrix(self const& other)
+      : super(other),
+	rows(other.getNumRows()),
+	cols(other.getNumCols())
+    { }
 
     /// Changes the size of the matrix to newRows x newCols.
     inline void resize(int newRows, int newCols) 
@@ -274,10 +301,27 @@ namespace AMDiS {
       }
     }
 
-    /// Assignement operator.
-    inline const Matrix<T>& operator=(const T& scal) 
+    /// Assignement operator
+    template <typename S>
+    inline self& operator=(const Matrix<S>& rhs) 
+    {
+      resize(rhs.getNumRows(), rhs.getNumCols());
+      this->setValues(rhs.getValArray());
+      return *this;
+    }
+    
+    inline self& operator=(self const& rhs) 
+    {
+      resize(rhs.getNumRows(), rhs.getNumCols());
+      this->setValues(rhs.getValArray());
+      return *this;
+    }
+
+    /// Assignement operator for scalars.
+    inline Matrix<T>& operator=(const T& scal) 
     {
-      return static_cast<const Matrix<T>&>(Vector<T>::operator=(scal));
+      Vector<T>::operator=(scal);
+      return *this;
     }
 
     ///
@@ -331,16 +375,16 @@ namespace AMDiS {
     }
 
     /// Returns \ref rows.
-    inline int getSize() const 
-    {
-      return rows; 
-    }
+//     inline int getSize() const 
+//     {
+//       return rows*cols; 
+//     }
 
     /// Returns pointer after the last vector element.
-    inline T *end() const 
-    { 
-      return this->valArray + (cols * rows); 
-    }
+//     inline T *end() const 
+//     { 
+//       return this->valArray + (cols * rows); 
+//     }
 
     void print() const 
     {
@@ -359,189 +403,6 @@ namespace AMDiS {
     /// Number of matrix columns.
     int cols;
   };
-
-  /// Matrix vector multiplication.
-  template<typename T>
-  inline const Vector<T>& mv(const Matrix<T>& m, const Vector<T>& v, Vector<T>& result)
-  {
-    TEST_EXIT_DBG(m.getNumCols() == v.getSize())("m and v not compatible\n");
-    TEST_EXIT_DBG(v.getSize() == result.getSize())("wrong result size\n");
-
-    T *resultIt, *mIt, *vIt;
-
-    for (resultIt = result.begin(), mIt = m.begin(); 
-	 resultIt != result.end(); 
-	 ++resultIt) {
-      *resultIt = 0;
-      for (vIt = v.begin(); vIt != v.end(); ++vIt, ++mIt)
-	*resultIt += *mIt * *vIt;
-    }
-
-    return result;
-  }
-
-  /// Matrix vector multiplication.
-  template<typename T>
-  inline const Vector<T>& operator*=(const Vector<T>& v, const Matrix<T>& m) 
-  {
-    return mv(m, v, v);
-  }
-
-  /// Matrix vector multiplication.
-  template<typename T>
-  inline Vector<T> operator*(const Matrix<T>& m, const Vector<T>& v) 
-  {
-    Vector<T> result(v.getSize());
-    return mv(m, v, result);
-  }
-
-  /// Scalar product.
-  template<typename T> 
-  inline double operator*(const Vector<T>& v1, const Vector<T>& v2) 
-  {
-    double result = 0.0;
-
-    T *v1It, *v2It;
-    for (v1It = v1.begin(), v2It = v2.begin();
-	 v1It != v1.end();
-	 ++v1It, ++v2It)
-      result += *v1It * *v2It;
-
-    return result;
-  }
-
-  /// Vector addition.
-  template<typename T> 
-  inline const Vector<T>& add(const Vector<T>& v1, const Vector<T>& v2, Vector<T>& result)
-  {
-    TEST_EXIT_DBG(v1.getSize() == v2.getSize())("invalid size in test v1 == v2\n");
-    TEST_EXIT_DBG(v2.getSize() == result.getSize())("invalid size in test v2 == result\n");
-    T *v1It, *v2It, *resultIt;
-    for (v1It = v1.begin(), v2It = v2.begin(), resultIt = result.begin();
-	 v1It != v1.end();
-	 ++v1It, ++v2It, ++resultIt)
-      *resultIt = *v1It + *v2It;
-
-    return result;
-  }
-
-  /// scalar * vector
-  template<typename T, typename S>
-  inline const Vector<T>& mult(const S& scal,
-			       const Vector<T>& v, 
-			       Vector<T>& result)
-  {
-    TEST_EXIT_DBG(v.getSize() == result.getSize())("invalid size\n");
-
-    T *vIt, *resultIt;
-    for (vIt = v.begin(), resultIt = result.begin();
-	 vIt != v.end();
-	 ++vIt, ++resultIt) 
-      *resultIt = scal * *vIt;
-
-    return result;
-  }
-
-  /// vector + scalar
-  template<typename T>
-  inline const Vector<T>& add(const Vector<T>& v, const T& scal, Vector<T>& result)
-  {
-    TEST_EXIT_DBG(v.getSize() == result.getSize())("invalid size\n");
-    T *vIt, *resultIt;
-    for (vIt = v.begin(), resultIt = result.begin();
-	 vIt != v.end();
-	 ++vIt, ++resultIt)
-      *resultIt = *vIt + scal;
-
-    return result;
-  }
-
-  /// y = a * x + y.
-  template<typename T, typename S>
-  inline const Vector<T>& axpy(const S& a,
-			       const Vector<T> &x,
-			       Vector<T> &y)
-  {
-    TEST_EXIT_DBG(x.getSize() == y.getSize())("invalid size\n");
-    T *xIt, *yIt;
-    for (xIt = x.begin(), yIt = y.begin();
-	 xIt != x.end();
-	 ++xIt, ++yIt) 
-      *yIt += a * *xIt;
-
-    return y;
-  }
-
-  template<typename T, typename S>
-  inline const Vector<T>& operator*=(Vector<T>& v, const S& scal)
-  {
-    return mult(scal, v, v);
-  }
-
-  template<typename T>
-  inline Vector<T> operator*(const Vector<T>& v, const T& scal) 
-  {
-    Vector<T> result = v;
-    result *= scal;
-    return result;
-  }
-
-  template<typename T>
-  inline const Vector<T>& operator+(const Vector<T>& v1, const T& scal) 
-  {
-    Vector<T> result(v1.getSize());
-    return add(v1, scal, result);
-  }
-
-  template<typename T>
-  inline const Vector<T>& operator+=(Vector<T>& v1, const Vector<T>& v2) 
-  {
-    return add(v1, v2, v1);
-  }
-
-  template<typename T>
-  inline Vector<T> operator+(const Vector<T>& v1, const Vector<T>& v2) 
-  {
-    Vector<T> result = v1;
-    result += v2;
-    return result;
-  }
-
-  template<typename T>
-  const Vector<T>& operator-=(Vector<T>& v1, const Vector<T>& v2)
-  {
-    return axpy(-1.0, v2, v1);
-  }
-
-  template<typename T>
-  Vector<T> operator-(const Vector<T>& v1, const Vector<T>& v2)
-  {
-    Vector<T> result = v1;
-    result -= v2;
-    return result;
-  }
-
-  template<typename T>
-  inline double norm(const Vector<T> *v)
-  {
-    T *vIt;
-    double result = 0;
-    for (vIt = v->begin(); vIt != v->end(); ++vIt)
-      result += *vIt * *vIt;
-    return sqrt(result);
-  }
-
-  template<typename T>
-  void vectorProduct(const Vector<T>& x, 
-		     const Vector<T>& y, 
-		     Vector<T>& z)
-  {
-    FUNCNAME_DBG("vectorProduct()");
-    TEST_EXIT_DBG(Global::getGeo(WORLD) == 3)("DIM_OF_WORLD != 3\n");
-    z[0] = x[1] * y[2] - x[2] * y[1];
-    z[1] = x[2] * y[0] - x[0] * y[2];
-    z[2] = x[0] * y[1] - x[1] * y[0];
-  }  
   
   template<typename T>
   inline size_t num_rows(const Vector<T>& vec)
diff --git a/AMDiS/src/MatrixVectorOperations.h b/AMDiS/src/MatrixVectorOperations.h
new file mode 100644
index 0000000000000000000000000000000000000000..3190dc1e73a2b86ed52b3bd66a4b9cfcb435cc96
--- /dev/null
+++ b/AMDiS/src/MatrixVectorOperations.h
@@ -0,0 +1,579 @@
+/******************************************************************************
+ *
+ * AMDiS - Adaptive multidimensional simulations
+ *
+ * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
+ * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
+ *
+ * Authors: 
+ * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *
+ * This file is part of AMDiS
+ *
+ * See also license.opensource.txt in the distribution.
+ * 
+ ******************************************************************************/
+
+
+
+/** \file MatrixVectorOperations.h */
+
+#ifndef AMDIS_MATVEC_OPERATIONS_H
+#define AMDIS_MATVEC_OPERATIONS_H
+
+#include "Traits.h"
+
+namespace AMDiS {
+
+  // ---------------------------------------------------------------------------
+  // Operations with Vector and Matrix
+
+  /// Matrix vector multiplication.
+  template<typename T>
+  inline const Vector<T>& mv(const Matrix<T>& m, const Vector<T>& v, Vector<T>& result)
+  {
+    TEST_EXIT_DBG(m.getNumCols() == v.getSize())("m and v not compatible\n");
+    TEST_EXIT_DBG(v.getSize() == result.getSize())("wrong result size\n");
+
+    T *resultIt, *mIt, *vIt;
+
+    for (resultIt = result.begin(), mIt = m.begin(); 
+	 resultIt != result.end(); 
+	 ++resultIt) {
+      *resultIt = 0;
+      for (vIt = v.begin(); vIt != v.end(); ++vIt, ++mIt)
+	*resultIt += *mIt * *vIt;
+    }
+
+    return result;
+  }
+
+  /// Vector addition.
+  template<typename T> 
+  inline const Vector<T>& add(const Vector<T>& v1, const Vector<T>& v2, Vector<T>& result)
+  {
+    TEST_EXIT_DBG(v1.getSize() == v2.getSize())("invalid size in test v1 == v2\n");
+    TEST_EXIT_DBG(v2.getSize() == result.getSize())("invalid size in test v2 == result\n");
+    T *v1It, *v2It, *resultIt;
+    for (v1It = v1.begin(), v2It = v2.begin(), resultIt = result.begin();
+	 v1It != v1.end();
+	 ++v1It, ++v2It, ++resultIt)
+      *resultIt = *v1It + *v2It;
+
+    return result;
+  }
+
+  /// scalar * vector
+  template<typename T, typename S>
+  inline const Vector<T>& mult(const S& scal,
+			       const Vector<T>& v, 
+			       Vector<T>& result)
+  {
+    TEST_EXIT_DBG(v.getSize() == result.getSize())("invalid size\n");
+
+    T *vIt, *resultIt;
+    for (vIt = v.begin(), resultIt = result.begin();
+	 vIt != v.end();
+	 ++vIt, ++resultIt) 
+      *resultIt = scal * *vIt;
+
+    return result;
+  }
+
+  /// vector + scalar
+  template<typename T>
+  inline const Vector<T>& add(const Vector<T>& v, const T& scal, Vector<T>& result)
+  {
+    TEST_EXIT_DBG(v.getSize() == result.getSize())("invalid size\n");
+    T *vIt, *resultIt;
+    for (vIt = v.begin(), resultIt = result.begin();
+	 vIt != v.end();
+	 ++vIt, ++resultIt)
+      *resultIt = *vIt + scal;
+
+    return result;
+  }
+
+  /// y = a * x + y.
+  template<typename T, typename S>
+  inline const Vector<T>& axpy(const S& a,
+			       const Vector<T> &x,
+			       Vector<T> &y)
+  {
+    TEST_EXIT_DBG(x.getSize() == y.getSize())("invalid size\n");
+    T *xIt, *yIt;
+    for (xIt = x.begin(), yIt = y.begin();
+	 xIt != x.end();
+	 ++xIt, ++yIt) 
+      *yIt += a * *xIt;
+
+    return y;
+  }
+  
+  // times / divides
+  // ---------------
+
+  /// Matrix vector multiplication: vector := matrix * vector
+  template<typename T>
+  inline const Vector<T>& operator*=(const Vector<T>& v, const Matrix<T>& m) 
+  {
+    return mv(m, v, v);
+  }
+
+  /// Matrix vector multiplication: vector := matrix * vector
+  template<typename T>
+  inline Vector<T> operator*(const Matrix<T>& m, const Vector<T>& v) 
+  {
+    Vector<T> result(m.getNumCols());
+    return mv(m, v, result);
+  }
+
+  /// Scalar product: scalar := vector * vector
+  template<typename T, typename S> 
+  inline typename traits::mult_type<T,S>::type 
+  operator*(const Vector<T>& v1, const Vector<S>& v2) 
+  {
+    typename traits::mult_type<T,S>::type result;
+    nullify(result);
+
+    T *v1It;
+    S *v2It;
+    for (v1It = v1.begin(), v2It = v2.begin();
+	 v1It != v1.end();
+	 ++v1It, ++v2It)
+      result += *v1It * *v2It;
+
+    return result;
+  }
+
+  /// vector *= scalar (elementwise)
+  template <typename T, typename S>
+  Vector<T>& operator*=(Vector<T>& v, S scal)
+  {
+    T *vIt;
+    for (vIt = v.begin(); vIt != v.end(); ++vIt) 
+      *vIt *= scal;
+    return v;
+  }
+
+  /// vector := vector * scalar (elementwise)
+  template <typename T, typename S>
+  Vector<typename traits::mult_type<T, S>::type>
+  operator*(Vector<T> const& v, S scal) 
+  {
+    Vector<typename traits::mult_type<T, S>::type> result = v;
+    result *= scal;
+    return result;
+  }
+
+  /// vector /= scalar (elementwise)
+  template <typename T, typename S>
+  Vector<T>& operator/=(Vector<T>& v, S scal)
+  {
+    T *vIt;
+    for (vIt = v.begin(); vIt != v.end(); ++vIt) 
+      *vIt /= scal;
+    return v;
+  }
+
+  /// vector := vector / scalar (elementwise)
+  template <typename T, typename S>
+  Vector<typename traits::mult_type<T, S>::type>
+  operator/(Vector<T> const& v, S scal) 
+  {
+    Vector<typename traits::mult_type<T, S>::type> result = v;
+    result /= scal;
+    return result;
+  }
+  
+  // plus / minus
+  // ------------
+
+  /// vector += scalar
+  template <typename T, typename S>
+  typename boost::enable_if<typename traits::is_scalar<S>::type,
+    Vector<T> >::type&
+  operator+=(Vector<T>& x, S scal) 
+  {
+    T *xIt;
+    for (xIt = x.begin(); xIt != x.end(); ++xIt) 
+      *xIt += scal;
+    return x;
+  }
+
+  /// vector := vector + scalar
+  template <typename T, typename S>
+  typename boost::enable_if<typename traits::is_scalar<S>::type,
+    Vector<T> >::type
+  operator+(Vector<T> result, T scal) 
+  {
+    result += scal;
+    return result;
+  }
+
+  /// vector += vector
+  template <typename T, typename S>
+  Vector<T>& operator+=(Vector<T>& x, const Vector<S>& y) 
+  {
+    T *xIt;
+    S *yIt;
+    for (xIt = x.begin(), yIt = y.begin(); xIt != x.end(); ++xIt, ++yIt) 
+      *xIt += *yIt;
+    return x;
+  }
+
+  /// vector := vector + vector
+  template <typename T, typename S>
+  Vector<T> operator+(Vector<T> result, const Vector<S>& v2) 
+  {
+    result += v2;
+    return result;
+  }
+
+  /// vector -= vector
+  template <typename T, typename S>
+  Vector<T>& operator-=(Vector<T>& x, const Vector<S>& y)
+  {
+    T *xIt;
+    S *yIt;
+    for (xIt = x.begin(), yIt = y.begin(); xIt != x.end(); ++xIt, ++yIt) 
+      *xIt -= *yIt;
+    return x;
+  }
+
+  /// vector := vector - vector
+  template <typename T, typename S>
+  Vector<T> operator-(Vector<T> result, const Vector<S>& v2)
+  {
+    result -= v2;
+    return result;
+  }
+  
+  // special operators
+  // -----------------
+
+  /// 2-norm of a vector
+  template<typename T>
+  inline T norm(const Vector<T> *v)
+  {
+    T result; nullify(result);
+    for (T* vIt = v->begin(); vIt != v->end(); ++vIt)
+      result += *vIt * *vIt;
+    return std::sqrt(result);
+  }
+  
+  /// 2-norm of a vector
+  template<typename T>
+  inline T norm(const Vector<T>& v)
+  {
+    return norm(&v);
+  }
+
+  /// cross-product of two vectors: vector := vector x vector (only in 3d)
+  template<typename T>
+  void vectorProduct(const Vector<T>& x, 
+		     const Vector<T>& y, 
+		     Vector<T>& z)
+  {
+    FUNCNAME_DBG("vectorProduct()");
+    TEST_EXIT_DBG(Global::getGeo(WORLD) == 3)("DIM_OF_WORLD != 3\n");
+    z[0] = x[1] * y[2] - x[2] * y[1];
+    z[1] = x[2] * y[0] - x[0] * y[2];
+    z[2] = x[0] * y[1] - x[1] * y[0];
+  }  
+
+  // ---------------------------------------------------------------------------
+  // Operations with WorldVector and WorldMatrix
+
+  // times / divides
+  // ---------------
+
+  /// Scalar product: scalar := vector * vector
+  template<typename T, typename S>
+  inline typename traits::mult_type<T,S>::type 
+  operator*(const WorldVector<T>& v1, const WorldVector<S>& v2) 
+  {
+    typename traits::mult_type<T,S>::type result;
+    nullify(result);
+
+    T *v1It;
+    S *v2It;
+    for (v1It = v1.begin(), v2It = v2.begin();
+	 v1It != v1.end();
+	 ++v1It, ++v2It)
+      result += *v1It * *v2It;
+
+    return result;
+  }
+  
+  /// vector := vector * scalar (elementwise)
+  template<typename T, typename S>
+  WorldVector<T>
+  operator*(WorldVector<T> const& v, S scal)
+  {
+    WorldVector<T> result = v;
+    result *= scal; // calls operator*=(Vector<T>, S)
+    return result;
+  }
+
+  /// vector := scalar * vector (elementwise)
+  template<typename T, typename S>
+  WorldVector<T>
+  operator*(S scal, WorldVector<T> const& v)
+  {
+    WorldVector<T> result = v;
+    result *= scal; // calls operator*=(Vector<T>, S)
+    return result;
+  }
+
+  /// vector := vector / scalar (elementwise)
+  template<typename T, typename S>
+  WorldVector<T>
+  operator/(WorldVector<T> const& v, S scal)
+  {
+    WorldVector<T> result = v;
+    result /= scal;  // calls operator/=(Vector<T>, S)
+    return result;
+  }
+  
+  /// matrix *= scalar (elementwise)
+//   template<typename T>
+//   WorldMatrix<T>& operator*=(WorldMatrix<T>& m, T scal)
+//   {
+//     for (T* mIt = m.begin(); mIt != m.end(); mIt++)
+//       *mIt *= scal;
+// 
+//     return m;
+//   }
+  
+  /// matrix := matrix * scalar (elementwise)
+  template <typename T, typename S>
+  WorldMatrix<T>
+  operator*(WorldMatrix<T> const& m, S scal)
+  {
+    WorldMatrix<T> result = m;
+    result *= scal; // calls operator*=(Vector<T>, S)
+    return result;
+  }
+
+  /// matrix := scalar * matrix (elementwise)
+  template <typename T, typename S>
+  WorldMatrix<T>
+  operator*(S scal, WorldMatrix<T> const& m)
+  {
+    WorldMatrix<T> result = m;
+    result *= scal; // calls operator*=(Vector<T>, S)
+    return result;
+  }
+
+  /// matrix := matrix / scalar (elementwise)
+  template <typename T, typename S>
+  WorldMatrix<T>
+  operator/(WorldMatrix<T> const& m, S scal)
+  {
+    WorldMatrix<T> result = m;
+    result /= scal; // calls operator/=(Vector<T>, S)
+    return result;
+  }
+
+  /// vector := matrix * vector
+  template<typename T>
+  WorldVector<T> operator*(const WorldMatrix<T>& M, const WorldVector<T>& v )
+  {
+    WorldVector<T> res;
+    res.multMatrixVec(M,v);
+    return res;
+  }
+
+  /// matrix := matrix * matrix
+  template<typename T>
+  WorldVector<WorldVector<T> > 
+  operator*(const WorldVector<WorldVector<T> >& A, const WorldVector<WorldVector<T> >& B)
+  {
+    WorldVector<WorldVector<T> > result;
+    nullify(result);
+    for (size_t r = 0; r < num_rows(A); r++)
+      for (size_t c = 0; c < num_cols(A); c++)
+	for (size_t i = 0; i < num_cols(A); i++)
+	  result[r][c] += A[r][i] * B[i][c];
+    return result;
+  }
+  
+  // plus / minus
+  // ------------
+  
+// NOTE: call operators of Vector<T> directly
+#if 0
+  template<typename T>
+  WorldVector<T>& operator+=(WorldVector<T>& v1,
+			     const WorldVector<T>& v2)
+  {
+    add(v1, v2, v1);
+    return v1;
+  }
+
+  template<typename T>
+  WorldVector<T>& operator-=(WorldVector<T>& v1,
+			     const WorldVector<T>& v2)
+  {
+    axpy(-1.0, v2, v1);
+    return v1;
+  }
+#endif
+
+  /// vector := vector + vector
+  template <typename T, typename S>
+  WorldVector<T>&
+  operator+=(WorldVector<T>& v1, WorldVector<S> const& v2)
+  {
+    static_cast<Vector<T>&>(v1) += static_cast<Vector<S> const&>(v2);
+    return v1;
+  }
+  
+  /// vector := vector + vector
+  template <typename T, typename S>
+  WorldVector<typename traits::add_type<T, S>::type>
+  operator+(WorldVector<T> result, const WorldVector<S>& v2)
+  {
+    result += v2; // calls operator+=(Vector<T>, Vector<T>)
+    return result;
+  }
+
+  /// vector := vector - vector
+  template <typename T, typename S>
+  WorldVector<typename traits::add_type<T, S>::type>
+  operator-(WorldVector<T> result, const WorldVector<S>& v2)
+  {
+    result -= v2; // calls operator-=(Vector<T>, Vector<T>)
+    return result;
+  }
+
+  /// matrix += matrix
+  template <typename T, typename S>
+  WorldMatrix<T>& operator+=(WorldMatrix<T>& m1, const WorldMatrix<S>& m2)
+  {
+    T* m1It;
+    S* m2It;
+    for (m1It = m1.begin(), m2It = m2.begin();
+	 m1It != m1.end(); 
+	 m1It++, m2It++)
+      *m1It += *m2It;
+
+    return m1;
+  }
+
+  /// matrix := matrix + matrix
+  template <typename T, typename S>
+  WorldMatrix<T> operator+(WorldMatrix<T> M1, const WorldMatrix<S>& M2 )
+  {
+    M1 += M2;
+    return M1;
+  }
+  
+  /// matrix -= matrix
+  template <typename T, typename S>
+  WorldMatrix<T>& operator-=(WorldMatrix<T>& m1, const WorldMatrix<S>& m2)
+  {
+    T *m1It;
+    S *m2It;
+    for (m1It = m1.begin(), m2It = m2.begin();
+	 m1It != m1.end(); 
+	 m1It++, m2It++)
+      *m1It -= *m2It;
+
+    return m1;
+  }
+
+  /// matrix := matrix - matrix
+  template <typename T, typename S>
+  WorldMatrix<T> operator-(WorldMatrix<T> M1, const WorldMatrix<S>& M2 )
+  {
+    M1 -= M2;
+    return M1;
+  }
+  
+  // unary minus operators
+  // ---------------------
+
+  /// vector := -vector (elementwise)
+  template<typename T>
+  WorldVector<T> operator-(WorldVector<T> v)
+  {
+    v *= -1.0;
+    return v;
+  }
+
+  /// matrix := -matrix (elementwise)
+  template<typename T>
+  WorldMatrix<T> operator-(WorldMatrix<T> v)
+  {
+    v *= -1.0;
+    return v;
+  }
+  
+  // comparison operators
+  // --------------------
+
+  /// test for less-then (elementwise) up to DBL_TOL
+  inline bool operator<(const WorldVector<double>& v1, const WorldVector<double>& v2) 
+  {
+    int dow = Global::getGeo(WORLD);
+    for (int i = 0; i < dow; i++) {
+      if (std::abs(v1[i] - v2[i]) < DBL_TOL) 
+	continue;
+      return v1[i] < v2[i];
+    }
+    return false;
+  }
+
+  /// test for equality (elementwise) up to DBL_TOL
+  inline bool operator==(const WorldVector<double>& v1, const WorldVector<double>& v2) 
+  {
+    int dow = Global::getGeo(WORLD);
+    for (int i = 0; i < dow; i++)
+      if (std::abs(v1[i] - v2[i]) > DBL_TOL) 
+	return false;
+
+    return true;
+  }
+  
+  // special operators
+  // -----------------
+  
+  /// wrapper for nullify
+  template<typename T>
+  void set_to_zero(WorldVector<WorldVector<T> >& mat)
+  {
+    nullify(mat);
+  }
+
+// NOTE: call norm(Vector<T>) directly
+#if 0
+  inline double norm(const WorldVector<double>& v)
+  {
+    double val = 0.0;
+    for (int i = 0; i < Global::getGeo(WORLD); i++)
+      val += v[i] * v[i];
+    return sqrt(val);
+  }
+#endif
+
+  /// returns the euclidian distance of a and b
+  template<typename T, GeoIndex d>
+  double absteukl(const FixVec<T,d>& a,const FixVec<T,d>& b)
+  {
+    double erg = 0.0;
+    for (int i = 0; i < a.getSize(); ++i)
+      erg += sqr(a[i] - b[i]);
+
+    return std::sqrt(erg);
+  }
+
+} // end namespace AMDiS
+
+#endif // AMDIS_MATVEC_OPERATIONS_H
+
diff --git a/AMDiS/src/ProblemInstat.cc b/AMDiS/src/ProblemInstat.cc
index de493c6ea83cb172a5647d02964403254a58b1de..6a99b7e4d88cd74e3e1822a33d78d755c0debb27 100644
--- a/AMDiS/src/ProblemInstat.cc
+++ b/AMDiS/src/ProblemInstat.cc
@@ -139,7 +139,7 @@ namespace AMDiS {
       oldSolution = new SystemVector("old solution", problemStat->getFeSpaces(), size);
       for (int i = 0; i < size; i++) {
 	oldSolution->setDOFVector(i, new DOFVector<double>(problemStat->getFeSpace(i), 
-							   name + "_uOld"));
+							   name + "_uOld", true));
 	oldSolution->getDOFVector(i)->setCoarsenOperation(COARSE_INTERPOL);
       
 	if (problemStat->getEstimator(i))
diff --git a/AMDiS/src/SecondOrderTerm.h b/AMDiS/src/SecondOrderTerm.h
index b8dfb1b7700bd3614bc35f8e5af8543f9072f62e..ef52a0c87c14996ff8a64e5a250693a96abeadcf 100644
--- a/AMDiS/src/SecondOrderTerm.h
+++ b/AMDiS/src/SecondOrderTerm.h
@@ -29,6 +29,7 @@
 #include "OperatorTerm.h"
 #include "ElInfo.h"
 #include "AbstractFunction.h"
+#include "MatrixVectorOperations.h"
 
 namespace AMDiS {
 
diff --git a/AMDiS/src/SubAssembler.cc b/AMDiS/src/SubAssembler.cc
index 59b68ce2fe3645afa9b14b6dd415988f30797be1..65d66542d82ab44bdbafacaa3ac96b85ff598d2b 100644
--- a/AMDiS/src/SubAssembler.cc
+++ b/AMDiS/src/SubAssembler.cc
@@ -135,7 +135,7 @@ namespace AMDiS {
     // calls initElement of each term
     for (vector<OperatorTerm*>::iterator it = terms.begin(); 
 	 it != terms.end(); ++it) {
-      if (largeElInfo == NULL)
+      if (largeElInfo == NULL || smallElInfo == largeElInfo)
 	(*it)->initElement(smallElInfo, this, quad);
       else
 	(*it)->initElement(smallElInfo, largeElInfo, this, quad);      
diff --git a/AMDiS/src/TransformDOF.h b/AMDiS/src/TransformDOF.h
index 0764e21179633f543c0a3862e150f078b90bc538..18822002970f9c7212913d1eba3f985c51aa928d 100644
--- a/AMDiS/src/TransformDOF.h
+++ b/AMDiS/src/TransformDOF.h
@@ -736,13 +736,13 @@ template<typename T> inline void transformDOFInterpolation(
 
 // ====================================================================================
 
-template<typename T>
-T accumulateDOF_simple(DOFVector<T> *vec,
-			      T value0,
-			      BinaryAbstractFunction<T, T, T> *binary_op)
+template<typename S, typename T>
+S accumulateDOF_simple(DOFVector<T> *vec,
+		       S value0,
+		       BinaryAbstractFunction<S, S, T> *binary_op)
 {
   DOFIterator<T> vecIter(vec, USED_DOFS);
-  T value = value0;
+  S value = value0;
   for(vecIter.reset(); !vecIter.end(); ++vecIter)
   {
     value = (*binary_op)(value, *vecIter);
diff --git a/AMDiS/src/ZeroOrderTerm.h b/AMDiS/src/ZeroOrderTerm.h
index 5c0dc44632e62ab1030972839218b6c835a84bbf..549a2efe43d17bc33d99d34191e6786881684881 100644
--- a/AMDiS/src/ZeroOrderTerm.h
+++ b/AMDiS/src/ZeroOrderTerm.h
@@ -28,6 +28,7 @@
 #include "AMDiS_fwd.h"
 #include "OperatorTerm.h"
 #include "AbstractFunction.h"
+#include "MatrixVectorOperations.h"
 
 namespace AMDiS {
 
diff --git a/AMDiS/src/config/Config_clang.h b/AMDiS/src/config/Config_clang.h
new file mode 100644
index 0000000000000000000000000000000000000000..1daa7f50061a6d7dd48a77e87d3f95d67010cefd
--- /dev/null
+++ b/AMDiS/src/config/Config_clang.h
@@ -0,0 +1,60 @@
+#pragma once
+
+#define CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
+#define COMPILER_VERSION "Clang: CLANG_VERSION"
+
+// alignement specification
+// ------------------------
+#define ALIGNED(type,name,N)  type name[N] __attribute__ ((aligned(CACHE_LINE)))
+typedef double aligned_double   __attribute__ ((aligned(CACHE_LINE)));
+typedef float  aligned_float    __attribute__ ((aligned(CACHE_LINE)));
+typedef int    aligned_int      __attribute__ ((aligned(CACHE_LINE)));
+typedef size_t aligned_size_t   __attribute__ ((aligned(CACHE_LINE)));
+
+// some compiler attributes
+// ------------------------
+#define NOINLINE                __attribute__ ((noinline))
+#define ALWAYS_INLINE           __attribute__ ((always_inline))
+#define OPENMODE                std::ios::openmode
+
+// C++11 features
+// --------------
+#if __cplusplus > 199711L
+
+#if CLANG_VERSION >= 20900
+  #define HAS_VARIADIC_TEMPLATES 1
+#endif
+
+#if CLANG_VERSION >= 30000
+  #define HAS_ALIAS_TEMPLATES 1
+#endif
+
+#if CLANG_VERSION >= 20900
+  #define HAS_DECLTYPE 1
+#endif
+
+#if CLANG_VERSION >= 30100
+  #define HAS_CONSTEXPR 1
+#endif
+
+#if CLANG_VERSION >= 30000
+  #define HAS_DELEGATING_CONSTRUCTORS 1
+#endif
+
+#if CLANG_VERSION >= 30000
+  #define HAS_RANGE_BASED_FOR 1
+#endif
+
+#if CLANG_VERSION >= 30100
+  #define HAS_INITIALIZER_LISTS 1
+#endif
+
+#if CLANG_VERSION >= 30000
+  #define HAS_OVERRIDE 1
+#endif
+
+#if CLANG_VERSION >= 20900
+  #define HAS_TYPED_ENUMS 1
+#endif
+
+#endif
\ No newline at end of file
diff --git a/AMDiS/src/config/Config_defaults.h b/AMDiS/src/config/Config_defaults.h
new file mode 100644
index 0000000000000000000000000000000000000000..8341f43ad54b872b71b7826b56e1b4886b235a7b
--- /dev/null
+++ b/AMDiS/src/config/Config_defaults.h
@@ -0,0 +1,69 @@
+#pragma once
+
+#ifndef COMPILER_NAME
+  #define COMPILER_NAME "Unknown"
+#endif
+#ifndef COMPILER_VERSION
+  #define COMPILER_VERSION 0
+#endif
+
+// alignement specification
+// ------------------------
+#ifndef ALIGNED
+#define ALIGNED(type,name,N)  type name[N]
+typedef double aligned_double;
+typedef float  aligned_float;
+typedef int    aligned_int;
+typedef size_t aligned_size_t;
+#endif
+
+// some compiler attributes
+// ------------------------
+#ifndef NOINLINE
+  #define NOINLINE
+#endif
+#ifndef ALWAYS_INLINE
+  #define ALWAYS_INLINE
+#endif
+#ifndef OPENMODE
+  #define OPENMODE std::ios::openmode
+#endif
+
+// C++11 features
+// --------------
+#ifndef HAS_VARIADIC_TEMPLATES
+  #define HAS_VARIADIC_TEMPLATES 0
+#endif
+
+#ifndef HAS_ALIAS_TEMPLATES
+  #define HAS_ALIAS_TEMPLATES 0
+#endif
+
+#ifndef HAS_DECLTYPE
+  #define HAS_DECLTYPE 0
+#endif
+
+#ifndef HAS_CONSTEXPR
+  #define HAS_CONSTEXPR 0
+#endif
+
+#ifndef HAS_DELEGATING_CONSTRUCTORS
+  #define HAS_DELEGATING_CONSTRUCTORS 0
+#endif
+
+#ifndef HAS_RANGE_BASED_FOR
+  #define HAS_RANGE_BASED_FOR 0
+#endif
+
+#ifndef HAS_INITIALIZER_LISTS
+  #define HAS_INITIALIZER_LISTS 0
+#endif
+
+#ifndef HAS_OVERRIDE
+  #define HAS_OVERRIDE 0
+  #define override
+#endif
+
+#ifndef HAS_TYPED_ENUMS
+  #define HAS_TYPED_ENUMS 0
+#endif
\ No newline at end of file
diff --git a/AMDiS/src/config/Config_gcc.h b/AMDiS/src/config/Config_gcc.h
new file mode 100644
index 0000000000000000000000000000000000000000..2247ed3beb5ba1dcad252e7558fc700bd5908539
--- /dev/null
+++ b/AMDiS/src/config/Config_gcc.h
@@ -0,0 +1,62 @@
+#pragma once
+
+#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+
+#define COMPIER_NAME "gcc"
+#define COMPILER_VERSION GCC_VERSION
+
+// alignement specification
+// ------------------------
+#define ALIGNED(type,name,N)  type name[N] __attribute__ ((aligned(CACHE_LINE)))
+typedef double aligned_double   __attribute__ ((aligned(CACHE_LINE)));
+typedef float  aligned_float    __attribute__ ((aligned(CACHE_LINE)));
+typedef int    aligned_int      __attribute__ ((aligned(CACHE_LINE)));
+typedef size_t aligned_size_t   __attribute__ ((aligned(CACHE_LINE)));
+
+// some compiler attributes
+// ------------------------
+#define NOINLINE                __attribute__ ((noinline))
+#define ALWAYS_INLINE           __attribute__ ((always_inline))
+#define OPENMODE                std::ios::openmode
+
+// C++11 features
+// --------------
+#if __cplusplus > 199711L
+
+#if GCC_VERSION >= 40300
+  #define HAS_VARIADIC_TEMPLATES 1
+#endif
+
+#if GCC_VERSION >= 40700
+  #define HAS_ALIAS_TEMPLATES 1
+#endif
+
+#if __cpp_decltype >= 200707
+  #define HAS_DECLTYPE 1
+#endif
+
+#if GCC_VERSION >= 40600
+  #define HAS_CONSTEXPR 1
+#endif
+
+#if GCC_VERSION >= 40700
+  #define HAS_DELEGATING_CONSTRUCTORS 1
+#endif
+
+#if GCC_VERSION >= 40600
+  #define HAS_RANGE_BASED_FOR 1
+#endif
+
+#if GCC_VERSION >= 40400
+  #define HAS_INITIALIZER_LISTS 1
+#endif
+
+#if GCC_VERSION >= 40700
+  #define HAS_OVERRIDE 1
+#endif
+
+#if GCC_VERSION >= 40400
+  #define HAS_TYPED_ENUMS 1
+#endif
+
+#endif
\ No newline at end of file
diff --git a/AMDiS/src/config/Config_intel.h b/AMDiS/src/config/Config_intel.h
new file mode 100644
index 0000000000000000000000000000000000000000..4053bcb9017953ae8d048565c916221c3ff1e533
--- /dev/null
+++ b/AMDiS/src/config/Config_intel.h
@@ -0,0 +1,63 @@
+#pragma once
+
+// MMmm (M...major, m...minor)
+#define INTEL_VERSION __INTEL_COMPILER
+
+#define COMPIER_NAME "icc"
+#define COMPILER_VERSION INTEL_VERSION
+
+// alignement specification
+// ------------------------
+#define ALIGNED(type,name,N)  __declspec(align(CACHE_LINE)) type name[N]
+typedef __declspec(align(CACHE_LINE)) double aligned_double;
+typedef __declspec(align(CACHE_LINE)) float  aligned_float;
+typedef __declspec(align(CACHE_LINE)) int    aligned_int;
+typedef __declspec(align(CACHE_LINE)) size_t aligned_size_t;
+
+// some compiler attributes
+// ------------------------
+#define NOINLINE
+#define ALWAYS_INLINE
+#define OPENMODE       std::ios::openmode
+
+// C++11 features
+// --------------
+#if __cplusplus > 199711L
+
+#if INTEL_VERSION >= 1201
+  #define HAS_VARIADIC_TEMPLATES 1
+#endif
+
+#if INTEL_VERSION >= 1201
+  #define HAS_ALIAS_TEMPLATES 1
+#endif
+
+#if INTEL_VERSION >= 1200
+  #define HAS_DECLTYPE 1
+#endif
+
+#if INTEL_VERSION >= 1400
+  #define HAS_CONSTEXPR 1
+#endif
+
+#if INTEL_VERSION >= 1400
+  #define HAS_DELEGATING_CONSTRUCTORS 1
+#endif
+
+#if INTEL_VERSION >= 1400
+  #define HAS_RANGE_BASED_FOR 1
+#endif
+
+#if INTEL_VERSION >= 1400
+  #define HAS_INITIALIZER_LISTS 1
+#endif
+
+#if INTEL_VERSION >= 1400
+  #define HAS_OVERRIDE 1
+#endif
+
+#if INTEL_VERSION >= 1400
+  #define HAS_TYPED_ENUMS 1
+#endif
+
+#endif
\ No newline at end of file
diff --git a/AMDiS/src/config/Config_msc.h b/AMDiS/src/config/Config_msc.h
new file mode 100644
index 0000000000000000000000000000000000000000..14edbf107821a100d63fd6e16ff39e153d776c00
--- /dev/null
+++ b/AMDiS/src/config/Config_msc.h
@@ -0,0 +1,66 @@
+#pragma once
+
+#define MSC_VERSION _MSV_VER
+// MSC_VERSION == 1800 (Visual Studio 2013)
+// MSC_VERSION == 1700 (Visual Studio 2012)
+// MSC_VERSION == 1600 (Visual Studio 2010)
+// MSC_VERSION == 1500 (Visual Studio 2008)
+
+#define COMPIER_NAME "msc"
+#define COMPILER_VERSION MSC_VERSION
+
+// alignement specification
+// ------------------------
+#define ALIGNED(type,name,N)  __declspec(align(CACHE_LINE)) type name[N]
+typedef __declspec(align(CACHE_LINE)) double aligned_double;
+typedef __declspec(align(CACHE_LINE)) float  aligned_float;
+typedef __declspec(align(CACHE_LINE)) int    aligned_int;
+typedef __declspec(align(CACHE_LINE)) size_t aligned_size_t;
+
+// some compiler attributes
+// ------------------------
+#define NOINLINE         __declspec(noinline)
+#define ALWAYS_INLINE    __forceinline
+#define OPENMODE         std::ios::open_mode
+
+// C++11 features
+// --------------
+#if __cplusplus > 199711L
+
+#if MSC_VERSION >= 1800
+  #define HAS_VARIADIC_TEMPLATES 1
+#endif
+
+#if MSC_VERSION >= 1800
+  #define HAS_ALIAS_TEMPLATES 1
+#endif
+
+#if MSC_VERSION >= 1600
+  #define HAS_DECLTYPE 1
+#endif
+
+// #if MSC_VERSION >= 2000 (?)
+#define HAS_CONSTEXPR 0
+// #endif
+
+#if MSC_VERSION >= 1800
+  #define HAS_DELEGATING_CONSTRUCTORS 1
+#endif
+
+#if MSC_VERSION >= 1700
+  #define HAS_RANGE_BASED_FOR 1
+#endif
+
+#if MSC_VERSION >= 1800
+  #define HAS_INITIALIZER_LISTS 1
+#endif
+
+#if MSC_VERSION >= 1700
+  #define HAS_OVERRIDE 1
+#endif
+
+#if MSC_VERSION >= 1700
+  #define HAS_TYPED_ENUMS 1
+#endif
+
+#endif
\ No newline at end of file
diff --git a/AMDiS/src/config/Config_pgi.h b/AMDiS/src/config/Config_pgi.h
new file mode 100644
index 0000000000000000000000000000000000000000..377a985072d75cb9aa8cf824d528dd688ec00751
--- /dev/null
+++ b/AMDiS/src/config/Config_pgi.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#define PGI_VERSION (__PGIC__ * 10000 + __PGIC_MINOR * 100 + __PGIC_PATCHLEVEL__)
+
+#define COMPIER_NAME "pgi"
+#define COMPILER_VERSION PGI_VERSION
\ No newline at end of file
diff --git a/AMDiS/src/expressions/add_expr.hpp b/AMDiS/src/expressions/add_expr.hpp
index 085427ec575c2528fe25486b8057798d42f41042..c98554b317df95d4d02b3bf0a8f96098773ea40f 100644
--- a/AMDiS/src/expressions/add_expr.hpp
+++ b/AMDiS/src/expressions/add_expr.hpp
@@ -60,6 +60,32 @@ namespace AMDiS
       std::string str() const { return std::string("(") + super::term1.str() + " + " + super::term2.str() + ")"; }
     };
     
+    /// Expression that represents "E1 - E2"
+    template<typename Term1, typename Term2>
+    struct Subtract : public LazyOperatorTerm2<Term1, Term2>
+    {
+      typedef LazyOperatorTerm2<Term1, Term2> super;
+      typedef typename traits::add_type
+      <
+	typename Term1::value_type,
+	typename Term2::value_type
+      >::type value_type;
+      
+      BOOST_STATIC_ASSERT_MSG( !(boost::is_same<value_type, traits::no_valid_type>::value), "********** ERROR: Can not subtract terms **********" );
+      
+      Subtract(const Term1& term1_, const Term2& term2_)
+	: super(term1_, term2_) {}
+      
+      int getDegree() const
+      {
+	return std::max(super::term1.getDegree(), super::term2.getDegree());
+      }
+
+      inline value_type operator()(const int& iq) const { return super::term1(iq) - super::term2(iq); }
+      
+      std::string str() const { return std::string("(") + super::term1.str() + " - " + super::term2.str() + ")"; }
+    };
+    
     /// Expression that represents "-E"
     template<typename Term>
     struct Negative : public LazyOperatorTerm1<Term>
@@ -107,24 +133,15 @@ namespace AMDiS
 	>
       > {};
       
-      
     template<typename Term1, typename Term2>
     struct Subtract : boost::enable_if
       < 
 	typename traits::is_valid_arg2<Term1, Term2>::type,
-	typename boost::mpl::if_<
-	  typename traits::is_constant<Term2>::type,
-	  expressions::Add
-	  <
-	    typename traits::to_expr<Term1>::type, 
-	    typename traits::to_expr<Term2>::type
-	  >,
-	  expressions::Add
-	  <
-	    typename traits::to_expr<Term1>::type, 
-	    expressions::Negative< typename traits::to_expr<Term2>::type >
-	  >
-	>::type
+	expressions::Subtract
+	<
+	  typename traits::to_expr<Term1>::type, 
+	  typename traits::to_expr<Term2>::type
+	>
       > {};
   }
 
@@ -159,7 +176,10 @@ namespace AMDiS
   inline typename result_of::Subtract<Term1, Term2>::type
   operator-(const Term1& t1, const Term2& t2)
   {
-    return t1 + (-t2);
+    typedef typename traits::to_expr<Term1>::to Expr1;
+    typedef typename traits::to_expr<Term2>::to Expr2;
+    return expressions::Subtract< typename Expr1::type, typename Expr2::type >
+	    (Expr1::get(t1), Expr2::get(t2));
   }
 
 } // end namespace AMDiS
diff --git a/AMDiS/src/expressions/valueOf.hpp b/AMDiS/src/expressions/valueOf.hpp
index 5b7536192ed16e771cc3b602beeb710523a00ed8..ef4ed4e1a8d79cf15e8422c4efadc53c11ae9748 100644
--- a/AMDiS/src/expressions/valueOf.hpp
+++ b/AMDiS/src/expressions/valueOf.hpp
@@ -128,7 +128,7 @@ namespace AMDiS
     /// Expressions that extracts the matrix-value of a Matrix<DOFVector> at QPs
     template<template<class> class Matrix, typename T, typename Name>
     struct ValueOf<Matrix<DOFVector<T>*>, Name, 
-		  typename boost::enable_if<typename traits::is_matrix<Matrix<T> >::type>::type > 
+		  typename enable_if< traits::is_matrix<Matrix<T> > >::type > 
       : public LazyOperatorTermBase
     {
       typedef Matrix<T> value_type;
@@ -138,7 +138,7 @@ namespace AMDiS
       mutable mtl::dense_vector<value_type> vec;
       mutable Matrix<mtl::dense_vector<T> > coeff;
 
-      ValueOf(Matrix<DOFVector<T>*>& vector) : vecDV(vector) 
+      ValueOf(Matrix<DOFVector<T>*> const& vector) : vecDV(vector) 
       {
 	resize(coeff, num_rows(vecDV), num_cols(vecDV));
       }
diff --git a/AMDiS/src/expressions/value_expr.hpp b/AMDiS/src/expressions/value_expr.hpp
index f7c80e86ae6f80f8f9eb70fd1f1eed1afdb1728e..4f6de8bde3379e157904b2af5158712bff4843f4 100644
--- a/AMDiS/src/expressions/value_expr.hpp
+++ b/AMDiS/src/expressions/value_expr.hpp
@@ -62,23 +62,10 @@ namespace AMDiS
     {
       typedef Vector<int> value_type;
       value_type V;
-	  
-      template<typename OT>
-      void initElement(OT* ot, const ElInfo* elInfo,
-		      SubAssembler* subAssembler, Quadrature *quad, 
-		      const BasisFunction *basisFct = NULL)
-      {
-	V.resize(Size);
-	int values[Size] = {V0, V1, V2};
-	V.setValues(&values);
-      }
-
-      template<typename OT>
-      void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo,
-		      SubAssembler* subAssembler, Quadrature *quad, 
-		      const BasisFunction *basisFct = NULL) 
-      {
-	initElement(ot, smallElInfo, subAssembler, quad, basisFct);
+      
+      CVector() : V(Size) {
+	int values[3] = {V0, V1, V2};
+	V.setValues(values);
       }
 		    
       inline value_type operator()(const int& iq) const { return V; }
@@ -87,6 +74,45 @@ namespace AMDiS
     };
     
     
+    /// Expression that encapsulates a compiletime vector
+    template<int V0 = 0, int V1 = 0, int V2 = 0>
+    struct WVector : public LazyOperatorTermBase
+    {
+      typedef WorldVector<int> value_type;
+      value_type V;
+      
+      WVector() {
+	V[0] = V0;
+	if (size(V) > 1) V[1] = V1;
+	if (size(V) > 2) V[2] = V2;
+      }
+		    
+      inline value_type operator()(const int& iq) const { return V; }
+      
+      std::string str() const { return std::string("[V(") + boost::lexical_cast<std::string>(size(V)) + ")]"; }
+    };
+    
+    template<int I = -1> 
+    struct E : public LazyOperatorTermBase
+    {
+      typedef WorldVector<int> value_type;
+      value_type V;
+      
+      E(int I_ = -1) {
+	assert((I >= 0 && I_ < 0) || (I < 0 && I_ >= 0));
+	V = 0; V[std::max(I, I_)] = 1;
+      }
+		    
+      inline value_type operator()(const int& iq) const { return V; }
+      
+      std::string str() const { return std::string("[V(") + boost::lexical_cast<std::string>(size(V)) + ")]"; }
+    };
+    
+    template<> struct E<0> : WVector<1> {};
+    template<> struct E<1> : WVector<0,1> {};
+    template<> struct E<2> : WVector<0,0,1> {};
+    
+    
     /// Expression that encapsulates a compiletime matrix
     template<int Rows, int Cols, int V0 = 0, int V1 = 0, int V2 = 0,
 				int V3 = 0, int V4 = 0, int V5 = 0,
@@ -94,31 +120,86 @@ namespace AMDiS
     struct CMatrix : public LazyOperatorTermBase
     {
       typedef Matrix<int> value_type;
-      value_type V;
-	  
-      template<typename OT>
-      void initElement(OT* ot, const ElInfo* elInfo,
-		      SubAssembler* subAssembler, Quadrature *quad, 
-		      const BasisFunction *basisFct = NULL)
-      {
-	V.resize(Rows, Cols);
-	int values[Rows*Cols] = {V0, V1, V2, V3, V4, V5, V6, V7, V8};
-	V.setValues(&values);
-      }
-
-      template<typename OT>
-      void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo,
-		      SubAssembler* subAssembler, Quadrature *quad, 
-		      const BasisFunction *basisFct = NULL) 
-      {
-	initElement(ot, smallElInfo, subAssembler, quad, basisFct);
+      value_type M;
+      
+      CMatrix() : M(Rows, Cols) {
+	int values[9] = {V0, V1, V2, V3, V4, V5, V6, V7, V8};
+	M.setValues(values);
       }
 		    
-      inline value_type operator()(const int& iq) const { return V; }
+      inline value_type operator()(const int& iq) const { return M; }
       
       std::string str() const { return std::string("[M(") + boost::lexical_cast<std::string>(Rows) + ","+ boost::lexical_cast<std::string>(Cols) + ")]"; }
     };
     
+    
+    /// Expression that encapsulates a compiletime matrix
+    template<int V0 = 0, int V1 = 0, int V2 = 0,
+	     int V3 = 0, int V4 = 0, int V5 = 0,
+	     int V6 = 0, int V7 = 0, int V8 = 0>
+    struct WMatrix : public LazyOperatorTermBase
+    {
+      typedef WorldMatrix<int> value_type;
+      value_type M;
+      
+      WMatrix() {
+	M[0][0] = V0;
+	if (Global::getGeo(WORLD) == 2) {
+	                M[0][1] = V1;
+	  M[1][0] = V2; M[1][1] = V3;
+	} else if (Global::getGeo(WORLD) == 3) {
+	                M[0][1] = V1; M[0][2] = V2;
+	  M[1][0] = V3; M[1][1] = V4; M[1][2] = V5;
+	  M[2][0] = V6; M[2][1] = V7; M[2][2] = V8;
+	}
+      }
+		    
+      inline value_type operator()(const int& iq) const { return M; }
+      
+      std::string str() const { return std::string("[M(") + boost::lexical_cast<std::string>(Global::getGeo(WORLD)) + ","+ boost::lexical_cast<std::string>(Global::getGeo(WORLD)) + ")]"; }
+    };
+    
+    
+    template<int N = -1> 
+    struct Eye : public LazyOperatorTermBase
+    {
+      typedef Matrix<int> value_type;
+      value_type M;
+      size_t n;
+      
+      Eye(int n) : M(n,n) {
+	assert((N >= 0 && n < 0) || (N < 0 && n >= 0));
+	M = 0;
+	for (size_t i = 0; i < n; ++i)
+	  M[i][i] = 1;
+      }
+		    
+      inline value_type operator()(const int& iq) const { return M; }
+      
+      std::string str() const { return std::string("[M(") + boost::lexical_cast<std::string>(n) + ","+ boost::lexical_cast<std::string>(n) + ")]"; }
+    };
+    
+    template<> 
+    struct Eye<-2> : public LazyOperatorTermBase
+    {
+      typedef WorldMatrix<int> value_type;
+      value_type M;
+      
+      Eye() {
+	M = 0;
+	for (size_t i = 0; i < Global::getGeo(WORLD); ++i)
+	  M[i][i] = 1;
+      }
+		    
+      inline value_type operator()(const int& iq) const { return M; }
+      
+      std::string str() const { return std::string("[M(") + boost::lexical_cast<std::string>(Global::getGeo(WORLD)) + ","+ boost::lexical_cast<std::string>(Global::getGeo(WORLD)) + ")]"; }
+    };
+    
+    template<> struct Eye<1> : CMatrix<1,1, 1> {};
+    template<> struct Eye<2> : CMatrix<2,2, 1,0, 0,1> {};
+    template<> struct Eye<3> : CMatrix<3,3, 1,0,0, 0,1,0, 0,0,1> {};
+    
   } // end namespace expressions
   
   
@@ -212,6 +293,27 @@ namespace AMDiS
   template<typename T>
   inline expressions::Reference<T> ref_(T* value) { return expressions::Reference<T>(value); }
 
+  
+  // unit vectors
+  template<int I>
+  inline expressions::E<I> E() 
+  { return expressions::E<I>(); }
+  
+  inline expressions::E<-1> E(int i) 
+  { return expressions::E<-1>(i); }
+  
+  // unit matrix
+  template<int N>
+  inline expressions::Eye<N> eye() 
+  { return expressions::Eye<N>(); }  // NxN unit-matrix 
+  
+  inline expressions::Eye<-1> eye(int n) 
+  { return expressions::Eye<-1>(n); } // nxn unit-matrix
+  
+  inline expressions::Eye<-2> eye() 
+  { return expressions::Eye<-2>(); } // dow x dow unit-matrix
+  
+  
 } // end namespace AMDiS
 
 #endif // AMDIS_VALUE_EXPR_HPP
diff --git a/AMDiS/src/expressions/vec_functors.hpp b/AMDiS/src/expressions/vec_functors.hpp
index 83d22d9b22553b01153a624b053e3a4f28d7625c..d67d870bc5e234c8adc2b5c8eb681bcdfe70f5e8 100644
--- a/AMDiS/src/expressions/vec_functors.hpp
+++ b/AMDiS/src/expressions/vec_functors.hpp
@@ -29,6 +29,18 @@
 #include "operations/norm.hpp"
 #include "operations/product.hpp"
     
+/**
+ *  This file provides expressions for vectors and matrices:
+ *  (where v_expr is an expression of vector type, and m_expr an
+ *   expression of matrix type)
+ *
+ *    two_norm(v_expr) ... the 2-norm of a vector v: result = sqrt(v^H * v)
+ *    one_norm(v_expr) ... the 1-norm of a vector v: result = sum_i(abs(v_i))
+ *    one_norm(m_expr) ... the 1-norm of a matrix m: result = max_j(sum_i(abs(m_ij))
+ *    p_norm<P>(v_expr) .. the P-norm of a vector v: result = [sum_i(abs(v_i)^P)]^(1/P)
+ *
+ **/    
+    
 namespace AMDiS 
 {
   namespace traits
@@ -173,7 +185,7 @@ namespace AMDiS
     struct one_norm<T, tag::expression> : result_of::UnaryExpr<functors::OneNorm, T, traits::is_vector, traits::is_matrix> {};
   }
   
-  /// the 2-norm of a vector v: result = sqrt(v^H * v)
+  /// the 1-norm of a vector v: result = max_i(abs(v_i))
   template<typename Term>
   inline typename result_of::one_norm<Term, tag::expression>::type
   one_norm_dispatch(const Term& t, tag::expression)
diff --git a/AMDiS/src/io/FileWriter.cc b/AMDiS/src/io/FileWriter.cc
index 2afc9f5fc009b2a259ea7c9531f67f8eba57d32e..67a6b4aa46c4df11a763b0e80248127c7e136f6e 100644
--- a/AMDiS/src/io/FileWriter.cc
+++ b/AMDiS/src/io/FileWriter.cc
@@ -52,10 +52,10 @@ namespace AMDiS
   {
     template<>
     FileWriter<double>::FileWriter(std::string name_,
-                         Mesh *mesh_,
-                         SystemVector *vecs)
+			  Mesh *mesh_,
+			  SystemVector *vecs)
       : name(name_),
-        mesh(mesh_)
+	mesh(mesh_)
     {
       initialize();
 
@@ -63,211 +63,164 @@ namespace AMDiS
   * Removed by Siqi. not sure.
   * for (int i = 0; i < static_cast<int>(vecs->getSize()); i++)
   * TEST_EXIT(vecs->getDOFVector(0)->getFeSpace() == vecs->getDOFVector(i)->getFeSpace())
-  *     ("All FeSpace have to be equal!\n");
+  * 	("All FeSpace have to be equal!\n");
   */ 
       feSpace = vecs->getDOFVector(0)->getFeSpace();
       solutionVecs.resize(vecs->getSize());
       for (int i = 0; i < static_cast<int>(vecs->getSize()); i++)
-        solutionVecs[i] = vecs->getDOFVector(i);
+	solutionVecs[i] = vecs->getDOFVector(i);
       
       for (size_t i = 0; i < solutionVecs.size(); i++)
-        solutionNames.push_back(solutionVecs[i]->getName());
+	solutionNames.push_back(solutionVecs[i]->getName());
     }
 
 
     template<>
     void FileWriter<double>::writeFiles(AdaptInfo *adaptInfo,
-                                bool force,
-                                int level,
-                                Flag flag,
-                                bool (*writeElem)(ElInfo*))
+				bool force,
+				int level,
+				Flag flag,
+				bool (*writeElem)(ElInfo*))
     {
       FUNCNAME("FileWriter<T>::writeFiles()");
       using namespace ::AMDiS::io;
 
-      if (timeModulo > 0.0) {
-        if ((lastWriteTime != 0.0 && adaptInfo->getTime() < lastWriteTime + timeModulo) && !force)
-          return;
-      } else {
-        if ((adaptInfo->getTimestepNumber() % tsModulo != 0) && !force) 
-          return;
-      }
-
-      lastWriteTime = adaptInfo->getTime();
+      if (!super::doWriteTimestep(adaptInfo, force))
+	return;
 
       //-----------------by Siqi---------------------//
       if (writeAMDiSFormat || writePeriodicFormat || writeParaViewFormat
-        || writeParaViewVectorFormat || writeParaViewAnimation
-        || writeDofFormat || (writeArhFormat && !writeArh2Format) || writePovrayFormat)
+	|| writeParaViewVectorFormat || writeParaViewAnimation
+	|| writeDofFormat || (writeArhFormat && !writeArh2Format) || writePovrayFormat)
       {
-        for (int i = 0; i < static_cast<int>(solutionVecs.size()); i++)
-          TEST_EXIT(solutionVecs[0]->getFeSpace() == solutionVecs[i]->getFeSpace())
-          ("All FeSpaces have to be equal!\n");
+	for (int i = 0; i < static_cast<int>(solutionVecs.size()); i++)
+	  TEST_EXIT(solutionVecs[0]->getFeSpace() == solutionVecs[i]->getFeSpace())
+	  ("All FeSpaces have to be equal!\n");
       }
-        
+	
       // Containers, which store the data to be written;
       std::vector<DataCollector<>*> dataCollectors(solutionVecs.size());
 
       if (writeElem) {
-        for (int i = 0; i < static_cast<int>(dataCollectors.size()); i++)
-          dataCollectors[i] = new DataCollector<>(feSpace, solutionVecs[i],
-                                                level, flag, writeElem);
+	for (int i = 0; i < static_cast<int>(dataCollectors.size()); i++)
+	  dataCollectors[i] = new DataCollector<>(feSpace, solutionVecs[i],
+						level, flag, writeElem);
       } else {
-        for (int i = 0; i < static_cast<int>(dataCollectors.size()); i++)
-          dataCollectors[i] = new DataCollector<>(feSpace, solutionVecs[i],
-                                                traverseLevel,
-                                                flag | traverseFlag,
-                                                writeElement);
+	for (int i = 0; i < static_cast<int>(dataCollectors.size()); i++)
+	  dataCollectors[i] = new DataCollector<>(feSpace, solutionVecs[i],
+						traverseLevel,
+						flag | traverseFlag,
+						writeElement);
       }
       
-      std::string fn = filename;
-      
-      if (createParaViewSubDir) {
-        using namespace boost::filesystem;
-        path vtu_path = fn;
-        path data_basedir("data");
-        path vtu_filename = vtu_path.filename();
-        vtu_path.remove_filename() /= data_basedir;
-        try {
-          create_directory(vtu_path); 
-          vtu_path /= vtu_filename;       
-          fn = vtu_path.string();
-        } catch (...) {}
-      }
-
-  #if HAVE_PARALLEL_DOMAIN_AMDIS
-      std::string paraFilename = fn;
-      fn += "-p" + boost::lexical_cast<std::string>(MPI::COMM_WORLD.Get_rank()) + "-";
-      std::string postfix = "";
-  #endif
-      
-
-      ///TODO: use the getParaViewFilename.. consistent with the parallel domain??
-      if (appendIndex) {
-        TEST_EXIT(indexLength <= 99)("index lenght > 99\n");
-        TEST_EXIT(indexDecimals <= 97)("index decimals > 97\n");
-        TEST_EXIT(indexDecimals < indexLength)("index length <= index decimals\n");
-
-        char formatStr[9];
-        char timeStr[20];
-
-        sprintf(formatStr, "%%0%d.%df", indexLength, indexDecimals);
-        sprintf(timeStr, formatStr, adaptInfo ? adaptInfo->getTime() : 0.0);
-
-        fn += timeStr;
-  #if HAVE_PARALLEL_DOMAIN_AMDIS
-        paraFilename += timeStr;
-        postfix += timeStr + paraviewFileExt;
-  #endif
-      } else {
-  #if HAVE_PARALLEL_DOMAIN_AMDIS
-        postfix += paraviewFileExt;
-  #endif
-      }
-      
-      
-  #if HAVE_PARALLEL_DOMAIN_AMDIS
-      std::string fn_ = paraFilename;
-  #else
-      std::string fn_ = fn;
-  #endif
+     std::string fn, fn_;
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+      std::string paraFilename, postfix;
+      super::getFilename(adaptInfo, fn, paraFilename, postfix);
+      postfix += paraviewFileExt;
+      fn_ = paraFilename;
+#else
+      super::getFilename(adaptInfo, fn);
+      fn_ = fn;
+#endif
+    
 
       if (writeAMDiSFormat) {
-        MacroWriter::writeMacro(dataCollectors[0],
-                                const_cast<char*>((fn +  amdisMeshExt).c_str()),
-                                adaptInfo ? adaptInfo->getTime() : 0.0);
-        MSG("macro file written to %s\n", (fn + amdisMeshExt).c_str());
-
-        ValueWriter::writeValues(dataCollectors[0],
-                                (fn + amdisDataExt).c_str(),
-                                adaptInfo ? adaptInfo->getTime() : 0.0);
-        MSG("value file written to %s\n", (fn + amdisDataExt).c_str());
+	MacroWriter::writeMacro(dataCollectors[0],
+				const_cast<char*>((fn +  amdisMeshExt).c_str()),
+				adaptInfo ? adaptInfo->getTime() : 0.0);
+	MSG("macro file written to %s\n", (fn + amdisMeshExt).c_str());
+
+	ValueWriter::writeValues(dataCollectors[0],
+				(fn + amdisDataExt).c_str(),
+				adaptInfo ? adaptInfo->getTime() : 0.0);
+	MSG("value file written to %s\n", (fn + amdisDataExt).c_str());
       }
 
       if (writePeriodicFormat) {
-        MacroWriter::writePeriodicFile(dataCollectors[0],
-                                      (fn + periodicFileExt).c_str());
-        MSG("periodic file written to %s\n", (fn + periodicFileExt).c_str());
+	MacroWriter::writePeriodicFile(dataCollectors[0],
+				      (fn + periodicFileExt).c_str());
+	MSG("periodic file written to %s\n", (fn + periodicFileExt).c_str());
       }
 
       if (writeParaViewFormat) {
-        std::string vtu_file = fn + paraviewFileExt;
-        VtkWriter::Aux vtkWriter(&dataCollectors, 
-                                 solutionNames,
-                                 VtkWriter::Vtuformat(paraViewMode), (paraViewPrecision == 1), writeParaViewVectorFormat);
-        vtkWriter.writeFile(vtu_file);
+	std::string vtu_file = fn + paraviewFileExt;
+	VtkWriter::Aux vtkWriter(&dataCollectors, 
+				 solutionNames,
+				 VtkWriter::Vtuformat(paraViewMode), (paraViewPrecision == 1), writeParaViewVectorFormat);
+	vtkWriter.writeFile(vtu_file);
 
   #if HAVE_PARALLEL_DOMAIN_AMDIS
-        if (MPI::COMM_WORLD.Get_rank() == 0) {
-//        vector<string> componentNames;
-//        for (unsigned int i = 0; i < dataCollectors.size(); i++)
-//          componentNames.push_back(dataCollectors[i]->getValues()->getName());
-
-          VtkWriter::detail::writeParallelFile(paraFilename + paraviewParallelFileExt,
-                                      MPI::COMM_WORLD.Get_size(),
-                                      filename, 
-                                      postfix,
-                                      solutionNames,
-                                      VtkWriter::Vtuformat(paraViewMode),
-                                      (paraViewPrecision == 1),
-                                      writeParaViewVectorFormat);
-        }
+	if (MPI::COMM_WORLD.Get_rank() == 0) {
+// 	  vector<string> componentNames;
+// 	  for (unsigned int i = 0; i < dataCollectors.size(); i++)
+// 	    componentNames.push_back(dataCollectors[i]->getValues()->getName());
+
+	  VtkWriter::detail::writeParallelFile(paraFilename + paraviewParallelFileExt,
+				      MPI::COMM_WORLD.Get_size(),
+				      filename, 
+				      postfix,
+				      solutionNames,
+				      VtkWriter::Vtuformat(paraViewMode),
+				      (paraViewPrecision == 1),
+				      writeParaViewVectorFormat);
+	}
   #endif
 
-        MSG("ParaView file written to %s\n", (fn + paraviewFileExt).c_str());
+	MSG("ParaView file written to %s\n", (fn + paraviewFileExt).c_str());
       }
 
       // write vtu-vector files
       if (writeParaViewVectorFormat && !writeParaViewFormat) {
-        VtkVectorWriter::writeFile(solutionVecs, fn_ + paraviewFileExt, true, writeAs3dVector);
-        MSG("ParaView file written to %s\n", (fn_ + paraviewFileExt).c_str());
+	VtkVectorWriter::writeFile(solutionVecs, fn_ + paraviewFileExt, true, writeAs3dVector);
+	MSG("ParaView file written to %s\n", (fn_ + paraviewFileExt).c_str());
       }
 
       if (writeParaViewAnimation) {
-        std::string pvd_file = fn_ + paraviewFileExt;
+	std::string pvd_file = fn_ + paraviewFileExt;
   #if HAVE_PARALLEL_DOMAIN_AMDIS
-        pvd_file = fn_ + paraviewParallelFileExt;
-        if (MPI::COMM_WORLD.Get_rank() == 0)
+	pvd_file = fn_ + paraviewParallelFileExt;
+	if (MPI::COMM_WORLD.Get_rank() == 0)
   #endif
-        {
-          VtkWriter::detail::updateAnimationFile(adaptInfo,
-                                        pvd_file,
-                                        &paraviewAnimationFrames,
-                                        filename + ".pvd");
-        }
+	{
+	  VtkWriter::detail::updateAnimationFile(adaptInfo,
+					pvd_file,
+					&paraviewAnimationFrames,
+					filename + ".pvd");
+	}
       }
   
 
       if (writeDofFormat) {
-        DofWriter::writeFile(solutionVecs, fn + ".dof");
+	DofWriter::writeFile(solutionVecs, fn + ".dof");
       }
 
       // write Arh files
       if (!writeArh2Format && writeArhFormat)
-        ArhWriter::write(fn_ + ".arh", feSpace->getMesh(), solutionVecs);
+	ArhWriter::write(fn_ + ".arh", feSpace->getMesh(), solutionVecs);
       else if (writeArh2Format)
-        Arh2Writer::writeFile(solutionVecs, fn_ + ".arh");
+	Arh2Writer::writeFile(solutionVecs, fn_ + ".arh");
     
     
   #ifdef HAVE_PNG
       if (writePngFormat) {
-        PngWriter pngWriter(dataCollectors[0]);
-        pngWriter.writeFile(fn + ".png", pngType);
+	PngWriter pngWriter(dataCollectors[0]);
+	pngWriter.writeFile(fn + ".png", pngType);
 
-        MSG("PNG image file written to %s\n", (fn + ".png").c_str());
+	MSG("PNG image file written to %s\n", (fn + ".png").c_str());
       }
   #endif
 
       if (writePovrayFormat) {
-        PovrayWriter povrayWriter(dataCollectors[0]);
-        povrayWriter.writeFile(fn + ".pov");
+	PovrayWriter povrayWriter(dataCollectors[0]);
+	povrayWriter.writeFile(fn + ".pov");
 
-        MSG("Povray script written to %s\n", (fn + ".pov").c_str());
+	MSG("Povray script written to %s\n", (fn + ".pov").c_str());
       }
 
 
       for (int i = 0; i < static_cast<int>(dataCollectors.size()); i++)
-        delete dataCollectors[i];
+	delete dataCollectors[i];
     }
 
     template<> 
diff --git a/AMDiS/src/io/FileWriter.h b/AMDiS/src/io/FileWriter.h
index 710b44d6a609508fb900bcf1469b5eeb9d848937..b66cf361fd338679c50ab6f87cc43979bcf4961c 100644
--- a/AMDiS/src/io/FileWriter.h
+++ b/AMDiS/src/io/FileWriter.h
@@ -52,6 +52,8 @@ namespace AMDiS {
     template<typename T>
     class FileWriter : public ::AMDiS::FileWriterInterface
     {
+    typedef ::AMDiS::FileWriterInterface super;
+    
     public:
       /// Constructor for a filewriter for one data component.
       FileWriter(std::string name, Mesh *mesh, DOFVector<T> *vec);
@@ -65,8 +67,8 @@ namespace AMDiS {
 
       /// Constructor for a filewriter with more than one data component.
       FileWriter(std::string name,
-			  Mesh *mesh,
-			  SystemVector *vecs);
+		 Mesh *mesh,
+		 SystemVector *vecs);
       
       /// Destructor
       virtual ~FileWriter();
@@ -75,24 +77,31 @@ namespace AMDiS {
       virtual void writeFiles(AdaptInfo *adaptInfo, bool force,
 			      int level = -1,
 			      Flag traverseFlag = Mesh::CALL_LEAF_EL,
-			      bool (*writeElem)(ElInfo*) = NULL);
+			      bool (*writeElem)(ElInfo*) = NULL) override;
     
       std::vector<std::pair<double, std::string> >& getParaviewAnimationFrames()
       {
 	return paraviewAnimationFrames;
       }
 
-      bool getWriteParaViewFormat() const { return writeParaViewFormat; }
-      std::string getParaViewFilename(AdaptInfo* info) const ;
-      const std::vector< std::string >& getSolutionNames() const 
-      { return solutionNames; }
+      bool getWriteParaViewFormat() const 
+      { 
+	return writeParaViewFormat;
+      }
+      
+      std::string getParaViewFilename(AdaptInfo* info) const;
+      
+      const std::vector<std::string>& getSolutionNames() const 
+      { 
+	return solutionNames; 
+      }
 
     protected:
       /// Initialization of the filewriter.
       void initialize();
 
       /// Reads all file writer dependend parameters from the init file.
-      void readParameters();
+      virtual void readParameters(std::string name) override;
 
       /// Name of the writer.
       std::string name;
@@ -129,9 +138,6 @@ namespace AMDiS {
 
       /// 1: extend number of component to 3, so that paraview can display the std::vector as worldstd::vector
       bool writeAs3dVector;
-      
-      /// create a subdirectory where to put the vtu file
-      bool createParaViewSubDir;
 
       /// 0: Don't write ParaView animation file; 1: Write ParaView animation file.
       int writeParaViewAnimation;
@@ -166,22 +172,6 @@ namespace AMDiS {
       /// name of the template file that will be prepended to all created *.pov files 
       std::string povrayTemplate;
 
-      /// 0: Don't append time index to filename prefix.
-      /// 1: Append time index to filename prefix.
-      int appendIndex;
-
-      /// Total length of appended time index.
-      int indexLength;
-
-      /// Number of decimals in time index.
-      int indexDecimals;
-
-      /// Timestep modulo: write only every tsModulo-th timestep! 
-      int tsModulo;
-      
-      /// Time modulo: write at first iteration after lastWriteTime + timeModulo
-      double timeModulo;
-      double lastWriteTime;
 
       /// Stores a set of std::pairs of timepoint and filename to write a ParaView 
       /// animation file.
diff --git a/AMDiS/src/io/FileWriter.hh b/AMDiS/src/io/FileWriter.hh
index 1c2c6c6156585884092c929bcd80059bbc13e04d..1a98bf8d31fdf988f62f09114da9d1ac8684385b 100644
--- a/AMDiS/src/io/FileWriter.hh
+++ b/AMDiS/src/io/FileWriter.hh
@@ -101,7 +101,7 @@ namespace AMDiS
       : name(name_),
 	mesh(mesh_)
     {
-      ERROR("SystemVector contains DOFVectors of type double, so the FileWriter<not double> can not be used!\n");
+      ERROR_EXIT("SystemVector contains DOFVectors of type double, so the FileWriter<not double> can not be used!\n");
     }
 
 
@@ -130,7 +130,6 @@ namespace AMDiS
       paraViewPrecision = 0;
       writeParaViewVectorFormat = 0;
       writeAs3dVector = false;
-      createParaViewSubDir = false;
       writeParaViewAnimation = 0;
       writePeriodicFormat = 0;
       writePngFormat = 0;
@@ -139,24 +138,19 @@ namespace AMDiS
       writeArhFormat = 0;
       writeArh2Format = 0;
       pngType = 0;
-      appendIndex = 0;
-      indexLength = 5;
-      indexDecimals = 3;
-      tsModulo = 1;
-      timeModulo = -1.0;
-      lastWriteTime = 0.0;
       nTmpSolutions = 0;
       paraviewAnimationFrames.resize(0),
       compression = NONE;
 
-      readParameters();
+      readParameters(name);
     }
 
 
     template<typename T>
-    void FileWriter<T>::readParameters()
+    void FileWriter<T>::readParameters(std::string name)
     {
-      Parameters::get(name + "->filename", filename);
+      super::readParameters(name);
+      
       Parameters::get(name + "->AMDiS format", writeAMDiSFormat);
       Parameters::get(name + "->AMDiS mesh ext", amdisMeshExt);
       Parameters::get(name + "->AMDiS data ext", amdisDataExt);
@@ -166,17 +160,11 @@ namespace AMDiS
       Parameters::get(name + "->ParaView vector format", writeParaViewVectorFormat);
       Parameters::get(name + "->write vector as 3d vector", writeAs3dVector);
       Parameters::get(name + "->ParaView animation", writeParaViewAnimation);
-      Parameters::get(name + "->ParaView create subdirectory", createParaViewSubDir);
       Parameters::get(name + "->ParaView ext", paraviewFileExt);    
       Parameters::get(name + "->Periodic format", writePeriodicFormat);
       Parameters::get(name + "->Periodic ext", periodicFileExt);
       Parameters::get(name + "->PNG format", writePngFormat);
       Parameters::get(name + "->PNG type", pngType);
-      Parameters::get(name + "->append index", appendIndex);
-      Parameters::get(name + "->index length", indexLength);
-      Parameters::get(name + "->index decimals", indexDecimals);
-      Parameters::get(name + "->write every i-th timestep", tsModulo);
-      Parameters::get(name + "->write after timestep", timeModulo);
 
       Parameters::get(name + "->Povray format", writePovrayFormat);
       Parameters::get(name + "->Povray template", povrayTemplate);
@@ -206,15 +194,8 @@ namespace AMDiS
     {
       FUNCNAME("FileWriter<T>::writeFiles()");
 
-      if (timeModulo > 0.0) {
-	if ((lastWriteTime != 0.0 && adaptInfo->getTime() < lastWriteTime + timeModulo) && !force)
-	  return;
-      } else {
-	if ((adaptInfo->getTimestepNumber() % tsModulo != 0) && !force) 
-	  return;
-      }
-
-      lastWriteTime = adaptInfo->getTime();
+      if (!super::doWriteTimestep(adaptInfo, force))
+	return;
       
       // Containers, which store the data to be written;
       std::vector<DataCollector<T>*> dataCollectors(solutionVecs.size());
@@ -231,35 +212,14 @@ namespace AMDiS
 						  writeElement);
       }
       
-      std::string fn = filename;
-
-  #if HAVE_PARALLEL_DOMAIN_AMDIS
-      std::string paraFilename = fn;
-      fn += "-p" + boost::lexical_cast<std::string>(MPI::COMM_WORLD.Get_rank()) + "-";
-      std::string postfix = "";
-  #endif
-
-      if (appendIndex) {
-	TEST_EXIT(indexLength <= 99)("index lenght > 99\n");
-	TEST_EXIT(indexDecimals <= 97)("index decimals > 97\n");
-	TEST_EXIT(indexDecimals < indexLength)("index length <= index decimals\n");
-      
-	char formatStr[9];
-	char timeStr[20];
-
-	sprintf(formatStr, "%%0%d.%df", indexLength, indexDecimals);
-	sprintf(timeStr, formatStr, adaptInfo ? adaptInfo->getTime() : 0.0);
-
-	fn += timeStr;
-  #if HAVE_PARALLEL_DOMAIN_AMDIS
-	paraFilename += timeStr;
-	postfix += timeStr + paraviewFileExt;
-  #endif
-      } else {
-  #if HAVE_PARALLEL_DOMAIN_AMDIS
-	postfix += paraviewFileExt;
-  #endif
-      }
+     std::string fn;
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+      std::string paraFilename, postfix;
+      super::getFilename(adaptInfo, fn, paraFilename, postfix);
+      postfix += paraviewFileExt;
+#else
+      super::getFilename(adaptInfo, fn);
+#endif
 
       if (writeParaViewVectorFormat) {
 	io::VtkVectorWriter::Aux<T> vtkVectorWriter(&dataCollectors, writeAs3dVector);
diff --git a/AMDiS/src/io/FileWriterInterface.cc b/AMDiS/src/io/FileWriterInterface.cc
new file mode 100644
index 0000000000000000000000000000000000000000..6d696200e3400ae83c71ffd2569489ef93078310
--- /dev/null
+++ b/AMDiS/src/io/FileWriterInterface.cc
@@ -0,0 +1,110 @@
+/******************************************************************************
+ *
+ * AMDiS - Adaptive multidimensional simulations
+ *
+ * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
+ * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
+ *
+ * Authors: 
+ * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *
+ * This file is part of AMDiS
+ *
+ * See also license.opensource.txt in the distribution.
+ * 
+ ******************************************************************************/
+
+/** \file FileWriterInterface.cc */
+
+
+#include "FileWriterInterface.h"
+#include "AdaptInfo.h"
+#include "Initfile.h"
+
+#include <boost/lexical_cast.hpp>
+#include <boost/filesystem.hpp>
+
+namespace AMDiS {
+
+  bool FileWriterInterface::doWriteTimestep(AdaptInfo *adaptInfo, bool force)
+  {
+    if (!force) {
+      if (timeModulo > 0.0) {
+	if (lastWriteTime > adaptInfo->getStartTime()
+	    && adaptInfo->getTime() < lastWriteTime + timeModulo)
+	  return false;
+      } else {
+	if (adaptInfo->getTimestepNumber() % tsModulo != 0) 
+	  return false;
+      }
+    }
+
+    lastWriteTime = adaptInfo->getTime();
+    return true;
+  }
+
+  
+  void FileWriterInterface::readParameters(std::string name)
+  {
+    Parameters::get(name + "->filename", filename);
+    Parameters::get(name + "->append index", appendIndex);
+    Parameters::get(name + "->index length", indexLength);
+    Parameters::get(name + "->index decimals", indexDecimals);
+    Parameters::get(name + "->write every i-th timestep", tsModulo);
+    Parameters::get(name + "->write after timestep", timeModulo);
+    
+    Parameters::get(name + "->ParaView create subdirectory", createSubDir);
+    if (createSubDir < 0)
+      Parameters::get(name + "->create subdirectory", createSubDir);
+  }
+  
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+  void FileWriterInterface::getFilename(AdaptInfo* adaptInfo, std::string& fn, std::string& paraFilename, std::string& postfix)
+#else
+  void FileWriterInterface::getFilename(AdaptInfo* adaptInfo, std::string& fn)
+#endif
+  {
+    fn = filename;
+      
+    if (createSubDir > 0) {
+      using namespace boost::filesystem;
+      path vtu_path = fn;
+      path data_basedir("data");
+      path vtu_filename = vtu_path.filename();
+      vtu_path.remove_filename() /= data_basedir;
+      try {
+	create_directory(vtu_path); 
+	vtu_path /= vtu_filename;	  
+	fn = vtu_path.string();
+      } catch (...) {}
+    }
+
+#if HAVE_PARALLEL_DOMAIN_AMDIS
+    paraFilename = filename;
+    fn += "-p" + boost::lexical_cast<std::string>(MPI::COMM_WORLD.Get_rank()) + "-";
+    postfix = "";
+#endif
+
+    if (appendIndex) {
+      TEST_EXIT(indexLength <= 99)("index lenght > 99\n");
+      TEST_EXIT(indexDecimals <= 97)("index decimals > 97\n");
+      TEST_EXIT(indexDecimals < indexLength)("index length <= index decimals\n");
+    
+      char formatStr[9];
+      char timeStr[20];
+
+      sprintf(formatStr, "%%0%d.%df", indexLength, indexDecimals);
+      sprintf(timeStr, formatStr, adaptInfo ? adaptInfo->getTime() : 0.0);
+
+      fn += timeStr;
+#if HAVE_PARALLEL_DOMAIN_AMDIS
+      paraFilename += timeStr;
+      postfix += timeStr;
+#endif
+    }
+  }
+}
diff --git a/AMDiS/src/io/FileWriterInterface.h b/AMDiS/src/io/FileWriterInterface.h
index 43e0faf9995d47cedd42a2243785ad3521fba570..a45bb10f520cf8155640318b4d5e256d4ce13325 100644
--- a/AMDiS/src/io/FileWriterInterface.h
+++ b/AMDiS/src/io/FileWriterInterface.h
@@ -41,6 +41,13 @@ namespace AMDiS {
   public:
     FileWriterInterface()
       : filename(""),
+	appendIndex(0),
+	indexLength(5),
+	indexDecimals(3),
+	createSubDir(-1),
+	tsModulo(1),
+	timeModulo(-1.0),
+	lastWriteTime(-1.0),
 	traverseLevel(-1),
 	traverseFlag(Mesh::CALL_LEAF_EL),
 	writeElement(NULL)
@@ -58,14 +65,8 @@ namespace AMDiS {
 			    Flag traverseFlag = Mesh::CALL_LEAF_EL,
 			    bool (*writeElem)(ElInfo*) = NULL) = 0;
 
-    void setTraverseProperties(int level, 
-			       Flag flag,
-			       bool (*writeElem)(ElInfo*))
-    {
-      traverseLevel = level;
-      traverseFlag |= flag;
-      writeElement = writeElem;
-    }
+    /// Test whether timestep should be written
+    virtual bool doWriteTimestep(AdaptInfo *adaptInfo, bool force);
 
     std::string getFilename() 
     { 
@@ -76,15 +77,59 @@ namespace AMDiS {
     { 
       filename = n; 
     }
+    
+    void setWriteModulo(int tsModulo_ = 1, double timeModulo_ = -1.0)
+    {
+      tsModulo = tsModulo_;
+      timeModulo = timeModulo_;
+    }
+
+    void setTraverseProperties(int level, 
+			       Flag flag,
+			       bool (*writeElem)(ElInfo*))
+    {
+      traverseLevel = level;
+      traverseFlag |= flag;
+      writeElement = writeElem;
+    }
 
   protected:
+    /// Reads all file writer dependend parameters from the init file.
+    virtual void readParameters(std::string name);
+    
+    /// create a filename that includes the timestep and possibly a processor ID in parallel mode
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+    void getFilename(AdaptInfo* adaptInfo, std::string& fn, std::string& paraFilename, std::string& postfix);
+#else
+    void getFilename(AdaptInfo* adaptInfo, std::string& fn);
+#endif
+      
     /// Used filename prefix.
     std::string filename;
 
-    int traverseLevel;
+    /// 0: Don't append time index to filename prefix.
+    /// 1: Append time index to filename prefix.
+    int appendIndex;
 
-    Flag traverseFlag;
+    /// Total length of appended time index.
+    int indexLength;
 
+    /// Number of decimals in time index.
+    int indexDecimals;
+      
+    /// create a subdirectory where to put the files
+    int createSubDir;
+    
+    /// Timestep modulo: write only every tsModulo-th timestep! 
+    int tsModulo;
+    
+    /// Time modulo: write at first iteration after lastWriteTime + timeModulo
+    double timeModulo;
+    double lastWriteTime;
+
+    /// Traverse properties
+    int traverseLevel;
+    Flag traverseFlag;
     bool (*writeElement)(ElInfo*);  
   };
 
diff --git a/AMDiS/src/io/MacroInfo.cc b/AMDiS/src/io/MacroInfo.cc
index 5645c1834f937ff0705027d810de6dafe408153c..6e1a73874ed633c2f6b4f57449748936c3fbd74c 100644
--- a/AMDiS/src/io/MacroInfo.cc
+++ b/AMDiS/src/io/MacroInfo.cc
@@ -65,6 +65,7 @@ namespace AMDiS {
       mel[i]->elType = 0;
     }
     neigh_set = false;
+    neigh_inverse_set = false;
     bound_set = false;
   }
 
@@ -82,6 +83,7 @@ namespace AMDiS {
 
     mesh = NULL;
     neigh_set = false;
+    neigh_inverse_set = false;
     
     nElements = 0;
     nVertices = 0;
@@ -95,18 +97,19 @@ namespace AMDiS {
   /*    fscanf(), else false                                                      */
   /********************************************************************************/
 
-  int MacroInfo::read_indices(FILE *file, DimVec<int> &id)
+  int MacroInfo::read_indices(FILE *file, Vector<int> &id)
   {
     int dim = mesh->getDim();
+    TEST_EXIT_DBG(id.getSize() == dim+1)("Vector has wrong dimension!");
 
     for (int i = 0; i <= dim; i++)
       if (fscanf(file, "%d", &id[i]) != 1)
-	return(false);
+	return false;
 
-    return(true);
+    return true;
   }
 
-#define N_KEYS      14
+#define N_KEYS      15
 #define N_MIN_KEYS  7
   static const char *keys[N_KEYS] = {
     "DIM",                   //  0 
@@ -122,7 +125,8 @@ namespace AMDiS {
     "element region",        // 10
     "surface region",        // 11
     "mesh name",             // 12
-    "time"                   // 13
+    "time",                   // 13
+    "element neighbours inverse"    //  14   (for graph-structured meshes with >1 neighbors)
   };
 
 
@@ -165,9 +169,10 @@ namespace AMDiS {
     double dbl;
     char line[256];
     int line_no, n_keys, sort_key[N_KEYS], nv_key, ne_key;
-    int key_def[N_KEYS] = {0,0,0,0,0,0,0,0,0,0,0,0};
+    int key_def[N_KEYS] = {0,0,0,0,0,0,0,0,0,0,0,0,0};
     const char *key;
     DimVec<int> *ind = NULL;
+    FixVec<int, NEIGH> *ind_neigh = NULL;
 
     TEST_EXIT(filename != "")("No filename specified!\n");
 
@@ -259,6 +264,7 @@ namespace AMDiS {
 	TEST_EXIT(result == 1)("cannot read DIM correctly in file %s\n", filename.c_str());
 
 	ind = new DimVec<int>(dim, NO_INIT);
+	ind_neigh = new FixVec<int, NEIGH>(dim, NO_INIT);
 
 	key_def[0] = true;
 	break;
@@ -343,14 +349,12 @@ namespace AMDiS {
 	for (int i = 0; i < nElements; i++) {  
 	  // boundary information of ith element 
 
-	  result = read_indices(file, *ind);
+	  result = read_indices(file, *ind_neigh);
 	  TEST_EXIT(result)
 	    ("cannot read boundary type of element %d in file %s\n", i, filename.c_str());
 
 	  // fill boundary of macro-element
-	  io::MacroReader::fillMelBoundary(mesh, 
-				       mel[i], 
-				       VecConv<int,NEIGH,PARTS>::convertVec((*ind), mesh));
+	  io::MacroReader::fillMelBoundary(mesh, mel[i], *ind_neigh);
 	}
 
 	this->fillBoundaryInfo(mesh);
@@ -371,10 +375,8 @@ namespace AMDiS {
 	for (int i = 0; i < nElements; i++) {
 	  //  neighbour information about ith element
 
-	  if (read_indices(file, *ind)) {
-	    io::MacroReader::fillMelNeigh(mel[i], mel, 
-				      VecConv<int,NEIGH,PARTS>::convertVec((*ind), 
-									   mesh));
+	  if (read_indices(file, *ind_neigh)) {
+	    io::MacroReader::fillMelNeigh(mel[i], mel, *ind_neigh);
 	  } else {
 	    // setting of neighbours fails
 
@@ -498,6 +500,32 @@ namespace AMDiS {
 	// line "time"
 	result = fscanf(file, "%*s %*s");
 	break;
+
+      case 14:
+	// block "element neighbours inverse"
+	result = fscanf(file, "%*s %*s %*s");
+
+	// ===  Fill MEL neighbour pointers:                               ===
+	// ===    if they are specified in the file: read them from file,  ===
+	// ===    else init them by a call of fill_mel_neighbour()         ===
+
+	neigh_inverse_set = true;
+	for (int i = 0; i < nElements; i++) {
+	  //  neighbour information about ith element
+
+	  if (read_indices(file, *ind_neigh)) {
+	    io::MacroReader::fillMelNeighInv(mel[i], mel, *ind_neigh);
+	  } else {
+	    // setting of neighbours fails
+	    ERROR_EXIT("Problem while reading 'element neighbours inverse' of element %d\n", i);
+	    neigh_inverse_set = false; 
+	    break;
+	  }
+	}
+
+	key_def[7] = true;
+	break;
+
       }
     }
 
@@ -520,6 +548,8 @@ namespace AMDiS {
       for (int k = 0; k < mesh->getGeo(NEIGH); k++)
 	if (mel[i]->neighbour[k])
 	  mel[i]->boundary[k] = INTERIOR;
+	else if (neigh_inverse_set && mel[i]->neighbour_inv[k])
+	  mel[i]->boundary[k] = INTERIOR;
 	else
 	  mel[i]->boundary[k] = 1;
   }
diff --git a/AMDiS/src/io/MacroInfo.h b/AMDiS/src/io/MacroInfo.h
index 2067498825c9024663406def903ad44dc8be7728..0cbd7dca366dfdbcfc7dbedd0c5ab93e05103b43 100644
--- a/AMDiS/src/io/MacroInfo.h
+++ b/AMDiS/src/io/MacroInfo.h
@@ -55,6 +55,9 @@ namespace AMDiS {
 
     /// true, if neighbour information is in macro file
     bool neigh_set;
+    
+    /// true, if inverse neighbour information is in macro file (see MacroReader.h)
+    bool neigh_inverse_set;
 
     /// true, if boundary information is in macro file
     bool bound_set;
@@ -93,7 +96,7 @@ namespace AMDiS {
 
   protected:
     /// Reads indices from macro file
-    int read_indices(FILE *file, DimVec<int> &id);
+    int read_indices(FILE *file, Vector<int> &id);
 
     bool initialized;
   };
diff --git a/AMDiS/src/io/MacroReader.cc b/AMDiS/src/io/MacroReader.cc
index 0881b25ac5604bac19396c351fd592bd7014f46b..61bba3f93c7f9ce3000b1c376ad24fb599cba1f6 100644
--- a/AMDiS/src/io/MacroReader.cc
+++ b/AMDiS/src/io/MacroReader.cc
@@ -317,14 +317,25 @@ namespace AMDiS { namespace io {
 	  MacroElement *neigh = const_cast<MacroElement*>(mel[i]->getNeighbour(k));
 
 	  if (neigh) {
-	    int j = 0;
-	    for (; j < mesh->getGeo(NEIGH); j++)
-	      if (neigh->getNeighbour(j) == *(mel + i))  
-		break;
-	
-	    TEST_EXIT(j < mesh->getGeo(NEIGH))("el %d no neighbour of neighbour %d\n", 
-					       mel[i]->getIndex(), neigh->getIndex());
-	    mel[i]->setOppVertex(k, j);
+	    if (!macroInfo->neigh_inverse_set) {
+	      int j = 0;
+	      for (; j < mesh->getGeo(NEIGH); j++)
+		if (neigh->getNeighbour(j) == *(mel + i))  
+		  break;
+	  
+	      TEST_EXIT(j < mesh->getGeo(NEIGH))("el %d no neighbour of neighbour %d\n", 
+						mel[i]->getIndex(), neigh->getIndex());
+	      mel[i]->setOppVertex(k, j);
+	    } else {
+	      int j = 0;
+	      for (; j < mesh->getGeo(NEIGH); j++)
+		if (neigh->getNeighbourInv(j) == *(mel + i))  
+		  break;
+	  
+	      TEST_EXIT(j < mesh->getGeo(NEIGH))("el %d no neighbour-inv of neighbour %d\n", 
+						mel[i]->getIndex(), neigh->getIndex());
+	      mel[i]->setOppVertex(k, j);
+	    }
 	  } else {
 	    mel[i]->setOppVertex(k, -1);
 	  }
@@ -948,7 +959,7 @@ namespace AMDiS { namespace io {
   }
 
   void MacroReader::fillMelBoundary(Mesh *mesh, MacroElement *mel, 
-				    FixVec<BoundaryType ,NEIGH> ind)
+				    FixVec<BoundaryType,NEIGH> const& ind)
   {
     for (int i = 0; i < mesh->getGeo(NEIGH); i++)
       mel->boundary[i] = ind[i];        
@@ -957,7 +968,7 @@ namespace AMDiS { namespace io {
 
   void MacroReader::fillMelNeigh(MacroElement *mel,
 				 std::deque<MacroElement*>& macro_elements, 
-				 FixVec<int,NEIGH> ind)
+				 FixVec<int,NEIGH> const& ind)
   {
     int dim = mel->element->getMesh()->getDim();
 
@@ -970,6 +981,21 @@ namespace AMDiS { namespace io {
   }
 
 
+  void MacroReader::fillMelNeighInv(MacroElement *mel,
+				 std::deque<MacroElement*>& macro_elements, 
+				 FixVec<int,NEIGH> const& ind)
+  {
+    int dim = mel->element->getMesh()->getDim();
+
+    for (int k = 0; k < Global::getGeo(NEIGH, dim); k++) {
+      if (ind[k] >= 0) 
+	mel->neighbour_inv[k] = macro_elements[ind[k]];
+      else
+	mel->neighbour_inv[k] = NULL;
+    }
+  }
+
+
   //   ordnet Eintraege in Macro-Element macro bzgl. Verfeinerungskante ka um
   //   (coord, bound, boundary, neigh, oppVertex)
 
diff --git a/AMDiS/src/io/MacroReader.h b/AMDiS/src/io/MacroReader.h
index 79ffa4f8a5e6d74b59ff8f55a47eb3d01a4c0354..f2ac2bfd37595319c0e854e7939e19f739779bef 100644
--- a/AMDiS/src/io/MacroReader.h
+++ b/AMDiS/src/io/MacroReader.h
@@ -120,11 +120,21 @@ namespace AMDiS { namespace io {
 			int mel_edge_no, int *n_neigh);
 
     static void fillMelBoundary(Mesh *, MacroElement *mel,
-				FixVec<BoundaryType ,NEIGH>);
+				FixVec<BoundaryType,NEIGH> const&);
 
     static void fillMelNeigh(MacroElement *mel,
 			     std::deque<MacroElement*>& macro_elements,
-			     FixVec<int,NEIGH> ind);
+			     FixVec<int,NEIGH> const&);
+
+    // for graph-structured meshes that have elements with >1 neighbors
+    // (0)--[a]--(1)---[b]--(2)
+    //            \____[c]__(3)
+    //
+    //  neigh:     [a]->[b], [b]->[c], [c]->[a]
+    //  neigh_inv: [b]->[a], [c]->[b], [a]->[c]
+    static void fillMelNeighInv(MacroElement *mel,
+			     std::deque<MacroElement*>& macro_elements,
+			     FixVec<int,NEIGH> const&);
 
     static void umbVkantMacro(Mesh *mesh,
 			      MacroElement *,
diff --git a/AMDiS/src/parallel/PetscSolverFeti.cc b/AMDiS/src/parallel/PetscSolverFeti.cc
index 10571d3b3902784b73685db4b7dda57952354855..a77a922177df3ba964305cd9f65f8eeb85922471 100644
--- a/AMDiS/src/parallel/PetscSolverFeti.cc
+++ b/AMDiS/src/parallel/PetscSolverFeti.cc
@@ -201,7 +201,7 @@ namespace AMDiS { namespace Parallel {
     FUNCNAME("PetscSolverFeti::createDirichletData()");
 
     if (dirichletMode == 1) {
-      int nComponents = mat.getSize();
+      int nComponents = mat.getNumRows();
       for (int component = 0; component < nComponents; component++) {
 	DOFMatrix* dofMat = mat[component][component];
 	if (!dofMat)
diff --git a/AMDiS/src/reinit/NormEps.cc b/AMDiS/src/reinit/NormEps.cc
index d2874f241d23cd7ae2c93bde4c633cae4f6f0a4a..a2f2b6a4d4b1e514c63a3b5a4922d8675183bc48 100644
--- a/AMDiS/src/reinit/NormEps.cc
+++ b/AMDiS/src/reinit/NormEps.cc
@@ -20,6 +20,7 @@
 
 
 #include "NormEps.h"
+#include "MatrixVectorOperations.h"
 
 namespace reinit {
 
diff --git a/AMDiS/src/solver/BlockPreconditioner.h b/AMDiS/src/solver/BlockPreconditioner.h
index e11f8c1068153d6048d784f2b5fd3edece14e4f4..c16336675286ae07c37f328ceb4d496bab5589e6 100644
--- a/AMDiS/src/solver/BlockPreconditioner.h
+++ b/AMDiS/src/solver/BlockPreconditioner.h
@@ -30,12 +30,13 @@
 namespace AMDiS {
 
   /// Basis preconditioner structure for block-preconditioners
-  template< typename MatrixType >
-  struct BlockPreconditioner : ITL_PreconditionerBase<MatrixType, MTLTypes::MTLVector>
-  {
-    typedef ITL_PreconditionerBase<MatrixType, MTLTypes::MTLVector>  super;
-    typedef BlockPreconditioner<MatrixType>                          self;
-    
+  template <class MatrixType, class VectorType = MTLTypes::MTLVector>
+  struct BlockPreconditioner : public ITL_PreconditionerBase<MatrixType, VectorType>
+  {    
+    typedef BlockPreconditioner                             self;
+    typedef ITL_PreconditionerBase<MatrixType, VectorType>  super;
+    typedef super                                           precon_base;
+        
     BlockPreconditioner() 
       : A(NULL), fullMatrix(NULL)
     { }
@@ -59,12 +60,12 @@ namespace AMDiS {
       }
     }
   
-    virtual void solve(const MTLTypes::MTLVector& b, MTLTypes::MTLVector& x) const
+    virtual void solve(const VectorType& b, VectorType& x) const
     { FUNCNAME("BlockPreconditioner::solve()");
       TEST_EXIT(false)("Must be implemented in derived classes!\n");
     }
     
-    virtual void adjoint_solve(const MTLTypes::MTLVector& x, MTLTypes::MTLVector& y) const
+    virtual void adjoint_solve(const VectorType& x, VectorType& y) const
     { FUNCNAME("BlockPreconditioner::adjoint_solve()");
       TEST_EXIT(false)("Must be implemented in derived classes!\n");
     }
@@ -84,7 +85,7 @@ namespace AMDiS {
       return A->getSubMatrix(i, j);
     }
     
-    template<typename SolverType, typename RunnerType>
+    template <class SolverType, class RunnerType>
     static void createSubSolver(std::string param, SolverType*& solver, RunnerType*& runner, 
 				std::string solverType = "0", std::string preconType = "no", 
 				int max_iter = 100, double tol = 1.e-8)
diff --git a/AMDiS/src/solver/LinearSolver.h b/AMDiS/src/solver/LinearSolver.h
index d7439f74f94a594f90d53ecaf54c9123314ea7b2..5dece3930ed82fec5ec328970d181fe588ab53b8 100644
--- a/AMDiS/src/solver/LinearSolver.h
+++ b/AMDiS/src/solver/LinearSolver.h
@@ -82,7 +82,7 @@ namespace AMDiS {
   
 #ifdef HAVE_PARALLEL_MTL4
   template< typename MatrixType >
-  struct LinearSolverBase<MatrixType, ParallelMapper, typename boost::enable_if< mtl::traits::is_distributed<MatrixType> > > 
+  struct LinearSolverBase<MatrixType, ParallelMapper, typename enable_if< mtl::traits::is_distributed<MatrixType> > > 
     : public ParallelSolver
   {
     typedef ParallelMapper Mapper;
diff --git a/AMDiS/src/solver/LinearSolverInterface.h b/AMDiS/src/solver/LinearSolverInterface.h
index 7244cf212b13b52f98f2d00339a54af52c4356e0..19848f3e4d981db30ee9557b92538456a2e7c922 100644
--- a/AMDiS/src/solver/LinearSolverInterface.h
+++ b/AMDiS/src/solver/LinearSolverInterface.h
@@ -127,6 +127,7 @@ namespace AMDiS {
 	  MSG("Residual norm: ||b-Ax|| = %e\n", residual);
 	}
 	
+#if DEBUG != 0
 	if (getIterations() > 0) {
 	  MSG("Nr. of iterations needed = %d\n", getIterations());
 	}
@@ -134,16 +135,21 @@ namespace AMDiS {
 	if (error_code != 0) {
 	  MSG("ERROR-Code = %d\n", error_code);
 	}
+	
+	if (!isNumber(residual) || !isNumber(rel_residual)) {
+	  MSG("Residual or relative residual is NaN/Inf!\n");
+	}
+#endif
 
 	// test for absolute tolerance
-	bool isAbsTolReached=(isNumber(residual) && (residual < 0.0  || tolerance < 1.e-30 || residual <= tolerance));
-	//	TEST_EXIT(isAbsTolReached || !breakTolNotReached);
-	//  ("Tolerance tol = %e could not be reached!\n Set tolerance by '->solver->tolerance:' \n", tolerance);
+	TEST_EXIT((isNumber(residual) && (residual < 0.0  || tolerance < 1.e-30 || residual <= tolerance))
+		  || !breakTolNotReached)
+	  ("Tolerance tol = %e could not be reached!\n Set tolerance by '->solver->tolerance:' \n", tolerance);
 	  
 	// test for relative tolerance
-	bool isRelTolReached=(isNumber(rel_residual) && (rel_residual < 0.0  || relative < 1.e-30 || rel_residual <= relative)) || (residual < 1.e-30);
-	TEST_EXIT(isAbsTolReached || isRelTolReached ||!breakTolNotReached )
-	  ("Relative tolerance rtol = %e could not be reached!\n  tolerance tol = %e could not be reached!\n Set tolerance by '->solver->relative tolerance:' \n Set tolerance by '->solver->tolerance:' \n", relative, tolerance);
+	TEST_EXIT((isNumber(rel_residual) && (rel_residual < 0.0  || relative < 1.e-30 || rel_residual <= relative))
+		  || (residual < 1.e-30) || !breakTolNotReached)
+	  ("Relative tolerance rtol = %e could not be reached!\n Set tolerance by '->solver->relative tolerance:' \n", relative);
       }
       return error_code;
     }
diff --git a/AMDiS/src/solver/Mapper.h b/AMDiS/src/solver/Mapper.h
index b2deab963481f4df2ce6f483dc22db315cbc58a2..0078f1d2335c8886be68fa14939649a62de4b240 100644
--- a/AMDiS/src/solver/Mapper.h
+++ b/AMDiS/src/solver/Mapper.h
@@ -98,7 +98,7 @@ namespace AMDiS {
       rowOffset(0), colOffset(0), nrow(0), ncol(0), sizes(nComp)
     {
       const Matrix<DOFMatrix* >& orMat(*sm.getOriginalMat());
-      const int ns = orMat.getSize();
+      const int ns = orMat.getNumRows();
       for (int i= 0; i < ns; i++) {
 	sizes[i] = orMat[i][i]->getFeSpace()->getAdmin()->getUsedSize();
 	nrow += sizes[i];
diff --git a/AMDiS/src/solver/MatrixStreams.h b/AMDiS/src/solver/MatrixStreams.h
index 1193da9f6ae5add2c75f67f8039814f199337356..0f7d62817573a0d2f1413643d7e5dc14b56d288e 100644
--- a/AMDiS/src/solver/MatrixStreams.h
+++ b/AMDiS/src/solver/MatrixStreams.h
@@ -55,7 +55,7 @@ namespace AMDiS {
   void operator<<(MatrixType& matrix, MatMap<const SolverMatrix<Matrix<DOFMatrix* > >, Mapper >& Asolver)
   {
     const Matrix< DOFMatrix* >& A = *(Asolver.mat.getOriginalMat());
-    int ns = A.getSize();
+    int ns = A.getNumRows();
 
     Mapper& mapper(Asolver.mapper);
     set_to_zero(matrix);
@@ -86,7 +86,7 @@ namespace AMDiS {
   void operator<<(MatrixType& matrix, MatMap<const Matrix<MatrixType* >, Mapper >& Asolver)
   {
     Matrix< MatrixType* >& A = *(Asolver.mat);
-    int ns = A.getSize();
+    int ns = A.getNumRows();
 
     Mapper& mapper(Asolver.mapper);
     set_to_zero(matrix);
diff --git a/AMDiS/src/traits/basic.hpp b/AMDiS/src/traits/basic.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..af2fb919a846977841e359ff79b186b879eed5e8
--- /dev/null
+++ b/AMDiS/src/traits/basic.hpp
@@ -0,0 +1,75 @@
+/******************************************************************************
+ *
+ * AMDiS - Adaptive multidimensional simulations
+ *
+ * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
+ * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
+ *
+ * Authors: 
+ * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *
+ * This file is part of AMDiS
+ *
+ * See also license.opensource.txt in the distribution.
+ * 
+ ******************************************************************************/
+
+
+
+/** \file basic.hpp */
+
+#ifndef AMDIS_BASIC_TRAITS_HPP
+#define AMDIS_BASIC_TRAITS_HPP
+
+#include <boost/version.hpp> 
+#include <boost/mpl/logical.hpp>
+
+#include "boost/numeric/ublas/detail/returntype_deduction.hpp"
+#if BOOST_VERSION >= 105600
+#include <boost/core/enable_if.hpp>
+#else
+#include <boost/utility/enable_if.hpp>
+#endif
+
+#ifdef HAS_CPP11
+#include <type_traits>
+#endif
+
+namespace AMDiS 
+{
+
+  // introduce some shortcuts for boost::mpl
+  // ---------------------------------------
+  using boost::mpl::true_;
+  using boost::mpl::false_;
+  using boost::mpl::and_;
+  using boost::mpl::or_;
+  
+  using boost::enable_if;
+  using boost::disable_if;
+  
+  namespace traits 
+  {
+  
+    // dummy type
+    typedef boost::numeric::ublas::error_cant_deduce_type no_valid_type;
+  
+      
+#ifdef HAS_CPP11
+    template <typename T>
+    struct is_trivially_copyable : std::is_trivially_copyable<T> {};
+#else
+    template <typename T>
+    struct is_trivially_copyable : boost::is_pod<T> {};
+#endif
+    
+  
+  }
+}
+
+
+#endif // AMDIS_BASIC_TRAITS_HPP
diff --git a/AMDiS/src/traits/category.hpp b/AMDiS/src/traits/category.hpp
index 0d00ddcbaf823f6ef45c082279f11172c2a1bc26..267cfbc5c04b6181201264380485991a0b5029b1 100644
--- a/AMDiS/src/traits/category.hpp
+++ b/AMDiS/src/traits/category.hpp
@@ -249,6 +249,30 @@ namespace AMDiS
     template<typename T>
     struct is_matrix : has_tag<T, tag::matrix> {};
     
+    // -------------------------------------------------------------------------
+    template<typename T, typename S, typename Enable = void>
+    struct is_convertible : boost::is_convertible<T, S> {};
+    
+    template<typename T, typename S>
+    struct is_convertible<T, S, typename boost::enable_if< 
+				  typename boost::mpl::and_<
+				    typename is_vector<T>::type,
+				    typename is_vector<S>::type
+				  >::type
+				>::type > 
+      : boost::is_convertible<typename T::value_type, typename S::value_type> {};
+      
+    template<typename T, typename S>
+    struct is_convertible<T, S, typename boost::enable_if< 
+				  typename boost::mpl::and_<
+				    typename is_matrix<T>::type,
+				    typename is_matrix<S>::type
+				  >::type
+				>::type > 
+      : boost::is_convertible<typename T::value_type, typename S::value_type> {};
+    
+    
+    
   } // end namespace traits
 
 } // end namespace AMDiS
diff --git a/AMDiS/src/traits/scalar_types.hpp b/AMDiS/src/traits/scalar_types.hpp
index ac7520965f3788510d990aae6b2668e4825cddd7..7295a0bc7c87043b3dddb54a1c3f40782986c35b 100644
--- a/AMDiS/src/traits/scalar_types.hpp
+++ b/AMDiS/src/traits/scalar_types.hpp
@@ -25,6 +25,10 @@
 #ifndef AMDIS_TYPE_TRAITS_SCALAR_TYPES_HPP
 #define AMDIS_TYPE_TRAITS_SCALAR_TYPES_HPP
 
+#ifdef HAS_CPP11
+#include <type_traits>
+#endif
+
 namespace AMDiS 
 {
   namespace traits 
@@ -45,7 +49,6 @@ namespace AMDiS
 	typename boost::is_floating_point<T>::type,
 	typename is_integer<T>::type
       >::type {};
-      
     
   } // end namespace traits
   
diff --git a/extensions/ExtendedProblemStat.h b/extensions/ExtendedProblemStat.h
index d6f305e1c516879d2bdb8aa36bfa865261f4241c..fb58f1d516eaab09f01a06dfffe72000feba5a49 100644
--- a/extensions/ExtendedProblemStat.h
+++ b/extensions/ExtendedProblemStat.h
@@ -41,13 +41,13 @@ class ExtendedProblemStat : public ProblemStat_
 public:
   
   ExtendedProblemStat(std::string nameStr, ProblemIterationInterface *problemIteration = NULL)
-  :
-  #if defined NONLIN_PROBLEM
-  ProblemStat_(nameStr)
-  #else
-  ProblemStat_(nameStr, problemIteration)
-  #endif
-  , oldMeshChangeIdx(0)
+    :
+      #if defined NONLIN_PROBLEM
+      ProblemStat_(nameStr),
+      #else
+      ProblemStat_(nameStr, problemIteration),
+      #endif
+      oldMeshChangeIdx(0)
   {
     exactSolutions.resize(nComponents);
     for (int i = 0; i < nComponents; ++i)
@@ -56,9 +56,8 @@ public:
   
   template<typename SubProblemType>
   ExtendedProblemStat(std::string nameStr, SubProblemType *subProblem)
-  :
-  ProblemStat_(nameStr, subProblem)
-  , oldMeshChangeIdx(0)
+    : ProblemStat_(nameStr, subProblem),
+      oldMeshChangeIdx(0)
   {
     exactSolutions.resize(nComponents);
     for (int i = 0; i < nComponents; ++i)
@@ -88,8 +87,10 @@ public:
 		  Flag adoptFlag = INIT_NOTHING)
   {    
     ProblemStat_::initialize(initFlag, adoptProblem, adoptFlag);
-    for (int i = 0; i < nComponents; ++i)
-      exactSolutions[i] = new DOFVector< double >(getFeSpace(i), "exact_solution");
+    if (initFlag.isSet(INIT_EXACT_SOLUTION)) {
+      for (int i = 0; i < nComponents; ++i)
+	exactSolutions[i] = new DOFVector<double>(getFeSpace(i), "exact_solution");
+    }
   }
   
 
@@ -120,7 +121,8 @@ public:
   //////////////////////////////////////////////////////////////////////////////
   void buildAfterCoarsen(AdaptInfo *adaptInfo, Flag flag,
 			  bool asmMatrix, bool asmVector)
-  {  
+  { FUNCNAME_DBG("ExtendedProblemStat::buildAfterCoarsen()");
+  
     ProblemStat_::buildAfterCoarsen(adaptInfo, flag, asmMatrix, asmVector);
 
     // update periodic data
@@ -149,13 +151,19 @@ public:
     }
     
     // apply dirichlet boundary conditions
-    for (size_t k = 0; k < singularDirichletBC.size(); k++)
-      applyDirichletBC(singularDirichletBC[k], asmMatrix, asmVector);
+    size_t num_dbc = 0;
+    for (size_t k = 0; k < singularDirichletBC.size(); k++) {
+      if (applyDirichletBC(singularDirichletBC[k], asmMatrix, asmVector))
+	++num_dbc;
+    }
+    MSG_DBG("DBC applied at %d DOFs\n", num_dbc);
     
     // update solverMatrix
     if (asmMatrix && (singularDirichletBC.size() > 0 || manualPeriodicBC.size() > 0)) {
       solverMatrix.setMatrix(*getSystemMatrix());
     }
+    
+    bc_dof.clear();
   }
 
   
@@ -191,6 +199,7 @@ public:
   void addDirichletBC(BoundaryType type, int row, int col,
 		      ValueContainer *values)
   {
+  MSG("addDirichletBC(%d, %d)\n", row, col);
     BoundaryTypeContainer *bound = new BoundaryTypeContainer(type);
     DirichletBcDataList.push_back(
       new DirichletBcData<BoundaryTypeContainer, ValueContainer>(
@@ -345,13 +354,18 @@ public:
     
 protected:
   // traverse matrix rows and set unity row where dirichlet condition shall be applied.
-  void applyDirichletBC(size_t row_, size_t col_, 
+  bool applyDirichletBC(size_t row_, size_t col_, 
 			DegreeOfFreedom idx, double value, 
 			bool asmMatrix = true, bool asmVector = true)
   {
     using namespace mtl;
     typedef DOFMatrix::base_matrix_type Matrix;
-
+    
+    std::pair<BcDofType::iterator, bool> ret;
+    ret = bc_dof.insert(std::make_pair(std::make_pair(row_,col_),idx));
+    if (!ret.second)
+      return false; // dof already inserted
+      
     Matrix::size_type idx_= idx;
     bool value1set = false;
 
@@ -397,12 +411,13 @@ protected:
       (*getRhsVector(row_))[idx] = value; // set Dirichlet-Value at rhs-vector
       
     (*solution->getDOFVector(col_))[idx] = value; // set Dirichlet-value for solution component
+    return true;
   }
   
   
-  void applyDirichletBC(SingularDirichletBC &sbc, bool asmMatrix = true, bool asmVector = true)
+  bool applyDirichletBC(SingularDirichletBC &sbc, bool asmMatrix = true, bool asmVector = true)
   {
-    applyDirichletBC(sbc.row, sbc.col, sbc.idx, sbc.value, asmMatrix, asmVector);
+    return applyDirichletBC(sbc.row, sbc.col, sbc.idx, sbc.value, asmMatrix, asmVector);
   }
   
 
@@ -444,6 +459,9 @@ protected:
 	  (*(getRhsVector(row)))[indices[i].second] += (*(getRhsVector(row)))[indices[i].first];
 	  (*(getRhsVector(row)))[indices[i].first] = 0.0;
 	}
+	
+	bc_dof.insert(std::make_pair(std::make_pair(row,row),indices[i].first));
+	bc_dof.insert(std::make_pair(std::make_pair(row,row),indices[i].second));
       }
 
       // add periodic associations of first and second indices, but only in the diagonal blocks
@@ -538,6 +556,9 @@ private:
   // data for dirichlet boundary conditions
   std::vector<SingularDirichletBC> singularDirichletBC;
   std::vector<DirichletBcDataBase*> DirichletBcDataList;
+  
+  typedef std::set<std::pair<std::pair<size_t,size_t>,DegreeOfFreedom> > BcDofType;
+  BcDofType bc_dof;
 
   std::map<const FiniteElemSpace*, bool> feSpaceVisited;
   
diff --git a/extensions/MeshFunction_Level.h b/extensions/MeshFunction_Level.h
index 80b72a5ab37b742fd50f76f3a19bf0866884083c..61a33ba444d5a2ba17e115b59bdeb5b11d98b17e 100644
--- a/extensions/MeshFunction_Level.h
+++ b/extensions/MeshFunction_Level.h
@@ -19,11 +19,74 @@
 #ifndef EXTENSIONS_MESH_FUNCTION_LEVEL_H
 #define EXTENSIONS_MESH_FUNCTION_LEVEL_H
 
-#include "Refinement.h"
-
 namespace AMDiS { namespace extensions {
 
 
+/** \brief
+ * Abstract class that can be passed to RefinementLevel* as indicator where
+ * to refine the mesh up to which level. It is an AbstractFunction that 
+ * overloads the operator() method to return a level or a meshsize depending
+ * on the coords/data passed to the operator.
+ * You can switch between meshsize and level with the methods hToLevel(double) and 
+ * levelToH(int)
+ **/
+template<typename T, typename T2>
+class MeshRefinementFunction : public AbstractFunction<T2, T>
+{
+public:
+
+  MeshRefinementFunction(Mesh* mesh_) :
+    AbstractFunction<T2, T>(0),
+    mesh(mesh_), 
+    globalSize(0)
+  {
+      h0 = getMacroMeshSize(mesh);
+      reduction = 1.0 / std::sqrt(2.0); // if dim==2
+  }
+
+  int getGlobalSize() { return globalSize; }
+
+  double meshSize() { return h0; }
+  
+  virtual void init(ElInfo* elInfo) {}
+
+  virtual T2 operator()(const T &value) const { return globalSize; }
+  virtual T2 getLevel() const { return globalSize; }
+  
+  virtual double indicator(const T &value) const { return 1.0; }
+
+protected:
+
+  int hToLevel(double h) {
+      int level = static_cast<int>(std::floor(std::log(h / h0) / std::log(reduction)));
+      return level;
+  }
+
+  double levelToH(int level) {
+      double h = std::pow(reduction,level)*h0;
+      return h;
+  }
+
+  double getMacroMeshSize(Mesh* mesh) {
+      FixVec<WorldVector<double>, VERTEX> coords = mesh->getMacroElement(0)->getCoord();
+      double h = 0.0;
+      for (int i = 0; i < coords.size(); ++i)
+          for (int j = i + 1; j < coords.size(); ++j)
+              h = std::max(h, norm(coords[i]-coords[j]));
+      return h;
+  }
+
+protected:
+
+  Mesh* mesh;
+
+  int globalSize;
+
+  double h0;
+  double reduction;
+};
+
+
 /** \brief
  * Base-Implementation of a MeshRefinementFunction for refinement of phase-field
  * interfaces. operator() must be overwritten in subclasses. Class provides
@@ -36,7 +99,7 @@ class PhaseFieldRefinementBase : public MeshRefinementFunction<T, int>
 {
 public:
 
-  PhaseFieldRefinementBase(Mesh *mesh) : 
+  PhaseFieldRefinementBase(Mesh *mesh, std::string name = "mesh->refinement") : 
     MeshRefinementFunction<T, int>(mesh),
     lInner(10),
     lOuter(10),
@@ -46,22 +109,22 @@ public:
     minOuterPhase(0.001),
     maxOuterPhase(0.999)
   {
-      Parameters::get("mesh->refinement->level in inner domain",lInner);
-      Parameters::get("mesh->refinement->level in outer domain",lOuter);
-      Parameters::get("mesh->refinement->level on interface",lInterface);
+      Parameters::get(name + "->level in inner domain",lInner);
+      Parameters::get(name + "->level in outer domain",lOuter);
+      Parameters::get(name + "->level on interface",lInterface);
 
       lInterface-= mesh->getMacroElementLevel();
       lInner-= mesh->getMacroElementLevel();
       lOuter-= mesh->getMacroElementLevel();
 
       int local_globalSize = 10;
-      Parameters::get("mesh->refinement->initial level", local_globalSize);
+      Parameters::get(name + "->initial level", local_globalSize);
       MeshRefinementFunction<T, int>::globalSize = local_globalSize;
 
-      Parameters::get("mesh->refinement->min interface value",minPhase);
-      Parameters::get("mesh->refinement->max interface value",maxPhase);
-      Parameters::get("mesh->refinement->min outer interface value",minOuterPhase);
-      Parameters::get("mesh->refinement->max outer interface value",maxOuterPhase);
+      Parameters::get(name + "->min interface value",minPhase);
+      Parameters::get(name + "->max interface value",maxPhase);
+      Parameters::get(name + "->min outer interface value",minOuterPhase);
+      Parameters::get(name + "->max outer interface value",maxOuterPhase);
   }
 
   double meshSize() { return levelToH(MeshRefinementFunction<T, int>::globalSize); }
@@ -87,7 +150,9 @@ class PhaseFieldRefinement : public PhaseFieldRefinementBase<double>
 {
 public:
 
-    PhaseFieldRefinement(Mesh* mesh_) : PhaseFieldRefinementBase<double>(mesh_) {};
+    PhaseFieldRefinement(Mesh* mesh_, std::string name = "mesh->refinement") 
+      : PhaseFieldRefinementBase<double>(mesh_, name) 
+    { };
     
     int operator()(const double& phase) const {
       int result= lOuter;
@@ -114,13 +179,13 @@ public:
 class PhaseFieldCoordsRefinement : public PhaseFieldRefinementBase< std::pair<WorldVector<double>, double> >
 {
 public:
-    PhaseFieldCoordsRefinement(Mesh* mesh_, std::vector<WorldVector<double> > points_, double radius_) :
-      PhaseFieldRefinementBase< std::pair<WorldVector<double>, double> >(mesh_),
-      lPoints(14),
-      points(points_),
-      radius(radius_)
+    PhaseFieldCoordsRefinement(Mesh* mesh_, std::vector<WorldVector<double> > points_, double radius_, std::string name = "mesh->refinement") 
+      : PhaseFieldRefinementBase< std::pair<WorldVector<double>, double> >(mesh_, name),
+	lPoints(14),
+	points(points_),
+	radius(radius_)
     {
-        Parameters::get("mesh->refinement->level on points",lPoints);
+        Parameters::get(name + "->level on points", lPoints);
         lPoints-= mesh->getMacroElementLevel();
     }
     
@@ -163,15 +228,14 @@ private:
 class CoordsRefinement : public MeshRefinementFunction< WorldVector<double>, int >
 {
 public:
-    CoordsRefinement(Mesh* mesh_, std::vector<WorldVector<double> > points_, double radius_) 
-    :
-    MeshRefinementFunction< WorldVector<double>, int >(mesh_),
-    points(points_),
-    radius(radius_)
+    CoordsRefinement(Mesh* mesh_, std::vector<WorldVector<double> > points_, double radius_, std::string name = "mesh->refinement") 
+      : MeshRefinementFunction< WorldVector<double>, int >(mesh_),
+	points(points_),
+	radius(radius_)
     {
         lInner= 15; lPoints = 20;
-        Parameters::get("mesh->refinement->level on points",lPoints);
-        Parameters::get("mesh->refinement->level in inner domain",lInner);
+        Parameters::get(name + "->level on points",lPoints);
+        Parameters::get(name + "->level in inner domain",lInner);
         lPoints-= mesh->getMacroElementLevel();
         lInner-= mesh->getMacroElementLevel();
 
@@ -206,15 +270,14 @@ private:
 class PhaseFieldChRefinement : public PhaseFieldRefinementBase< std::vector<double> >
 {
 public:
-  PhaseFieldChRefinement(Mesh* mesh_) 
-  :
-  PhaseFieldRefinementBase< std::vector<double> >(mesh_),
-  lInterfaceDomain(14)
+  PhaseFieldChRefinement(Mesh* mesh_, std::string name = "mesh->refinement") 
+    : PhaseFieldRefinementBase< std::vector<double> >(mesh_, name),
+      lInterfaceDomain(14)
   {
-    Parameters::get("mesh->refinement->level on domain interface",lInterfaceDomain);
+    Parameters::get(name + "->level on domain interface",lInterfaceDomain);
     lInterfaceDomain-= mesh->getMacroElementLevel();
     
-    Parameters::get("mesh->refinement->initial level", globalSize);
+    Parameters::get(name + "->initial level", globalSize);
   }
   
   int operator()(const std::vector<double>& phases) const 
@@ -254,8 +317,9 @@ class SignedDistRefinementBase : public MeshRefinementFunction<T, int>
 {
 public:
 
-  SignedDistRefinementBase(Mesh *mesh) :
+  SignedDistRefinementBase(Mesh *mesh, std::string name = "mesh->refinement") :
     MeshRefinementFunction<T, int>(mesh),
+    name(name),
     lInner(10),
     lOuter(10),
     lInterface(14),
@@ -263,26 +327,27 @@ public:
     fadeOutWidth(0.0),
     signInInnerDomain(-1.0)
   {
-      Parameters::get("mesh->refinement->level in inner domain",lInner);
-      Parameters::get("mesh->refinement->level in outer domain",lOuter);
-      Parameters::get("mesh->refinement->level on interface",lInterface);
+      Parameters::get(name + "->level in inner domain",lInner);
+      Parameters::get(name + "->level in outer domain",lOuter);
+      Parameters::get(name + "->level on interface",lInterface);
 
       lInterface-= mesh->getMacroElementLevel();
       lInner-= mesh->getMacroElementLevel();
       lOuter-= mesh->getMacroElementLevel();
 
       int local_globalSize = 10;
-      Parameters::get("mesh->refinement->initial level", local_globalSize);
+      Parameters::get(name + "->initial level", local_globalSize);
       MeshRefinementFunction<T, int>::globalSize = local_globalSize;
 
-      Parameters::get("mesh->refinement->interface width",interfaceWidth);
-      Parameters::get("mesh->refinement->fade out width",fadeOutWidth);
-      Parameters::get("mesh->refinement->sign in inner domain",signInInnerDomain);
+      Parameters::get(name + "->interface width",interfaceWidth);
+      Parameters::get(name + "->fade out width",fadeOutWidth);
+      Parameters::get(name + "->sign in inner domain",signInInnerDomain);
   }
 
   double meshSize() { return levelToH(MeshRefinementFunction<T, int>::globalSize); }
 
 protected:
+  std::string name;
 
   int lInner;
   int lOuter;
@@ -302,7 +367,7 @@ class SignedDistRefinement : public SignedDistRefinementBase<double>
 {
 public:
 
-    SignedDistRefinement(Mesh* mesh_) : SignedDistRefinementBase<double>(mesh_) {};
+    SignedDistRefinement(Mesh* mesh_, std::string name = "mesh->refinement") : SignedDistRefinementBase<double>(mesh_, name) {};
 
     int operator()(const double& dist) const {
       int result= lOuter;
@@ -324,11 +389,10 @@ public:
 class ESIndicator : public MeshRefinementFunction< std::vector<double>, int >
 {
 public:
-  ESIndicator(Mesh* mesh_) 
-  :
-  MeshRefinementFunction< std::vector<double>, int >(mesh_)
+  ESIndicator(Mesh* mesh_, std::string name = "mesh->refinement") 
+    : MeshRefinementFunction< std::vector<double>, int >(mesh_)
   {
-    Parameters::get("mesh->refinement->initial level", globalSize);
+    Parameters::get(name + "->initial level", globalSize);
   }
   
   int operator()(const std::vector<double>& means) const 
diff --git a/extensions/MeshIndicator.h b/extensions/MeshIndicator.h
index 2d9332284ffffd52945420056bf2067e33e29fd2..fd3ea21115bb70b7cae9391dfc29940011187208 100644
--- a/extensions/MeshIndicator.h
+++ b/extensions/MeshIndicator.h
@@ -237,7 +237,7 @@ namespace tools {
 
 
   template<typename T1, typename T2>
-  typename ProductType<T1,T2>::type integrate_VecTimesCoords(const DOFVector<T1> &vec,
+  typename traits::mult_type<T1,T2>::type integrate_VecTimesCoords(const DOFVector<T1> &vec,
 		    AbstractFunction<T2, WorldVector<double> > *fct, MeshIndicator *meshIndicator)
   {
     FUNCNAME("integrate_VecTimesCoords()");
@@ -245,7 +245,7 @@ namespace tools {
     TEST_EXIT(fct)("No function defined!\n");
     TEST_EXIT(meshIndicator)("No MeshIndicator defined!\n");
 
-    typedef typename ProductType<T1,T2>::type TOut;
+    typedef typename traits::mult_type<T1,T2>::type TOut;
 
     const FiniteElemSpace *feSpace = vec.getFeSpace();
     Mesh *mesh = feSpace->getMesh();
diff --git a/extensions/RefineFunctions.h b/extensions/RefineFunctions.h
new file mode 100644
index 0000000000000000000000000000000000000000..d073ad4d5d14f5312eefe1a0e5c96e7b779e47ff
--- /dev/null
+++ b/extensions/RefineFunctions.h
@@ -0,0 +1,86 @@
+/******************************************************************************
+ *
+ * Extension of AMDiS - Adaptive multidimensional simulations
+ *
+ * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
+ * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
+ *
+ * Authors: Simon Praetorius et al.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *
+ * See also license.opensource.txt in the distribution.
+ * 
+ ******************************************************************************/
+
+
+#ifndef EXTENSIONS_REFINE_FUNCTIONS_H
+#define EXTENSIONS_REFINE_FUNCTIONS_H
+
+#include <vector>
+#include <string>
+
+#include "Global.h"
+#include "Mesh.h"
+#include "Initfile.h"
+#include "operations/functors.hpp"
+
+namespace AMDiS { namespace extensions {
+  
+  struct PhaseFieldRefineFct : public FunctorBase
+  {
+    typedef int result_type;
+    
+    PhaseFieldRefineFct(std::string name, Mesh* mesh)
+      : lInner(10),
+	lOuter(10),
+	lInterface(14),
+	minPhase(0.05),
+	maxPhase(0.95),
+	minOuterPhase(0.001),
+	maxOuterPhase(0.999)
+    {
+      Parameters::get(name + "->level in inner domain", lInner);
+      Parameters::get(name + "->level in outer domain", lOuter);
+      Parameters::get(name + "->level on interface", lInterface);
+
+      Parameters::get(name + "->min interface value", minPhase);
+      Parameters::get(name + "->max interface value", maxPhase);
+      Parameters::get(name + "->min outer interface value", minOuterPhase);
+      Parameters::get(name + "->max outer interface value", maxOuterPhase);
+	
+      lInterface-= mesh->getMacroElementLevel();
+      lInner-= mesh->getMacroElementLevel();
+      lOuter-= mesh->getMacroElementLevel();
+    }
+    
+    inline int operator()(double phase) const
+    {
+      int result = lOuter;
+      if (minPhase < phase && phase < maxPhase)
+        result = lInterface;         // auf dem Interface
+      else if (phase > minOuterPhase && phase <= minPhase)
+        result = std::max(lOuter, static_cast<int>(std::floor((lOuter+lInterface)/2.0)));
+      else if (phase < maxOuterPhase && phase >= maxPhase)
+        result = std::max(lInner, static_cast<int>(std::floor((lInner+lInterface)/2.0)));
+      else if (phase > (minPhase+maxPhase)/2.0)
+        result = lInner;
+      return result;
+    }
+    
+  protected:
+    int lInner;
+    int lOuter;
+    int lInterface;
+    
+    double minPhase;
+    double maxPhase;
+    double minOuterPhase;
+    double maxOuterPhase;
+  };
+    
+} }
+
+#endif
\ No newline at end of file
diff --git a/extensions/RefineOperations.h b/extensions/RefineOperations.h
new file mode 100644
index 0000000000000000000000000000000000000000..dc1554abf501af7972fe6cc6b6b4304794127268
--- /dev/null
+++ b/extensions/RefineOperations.h
@@ -0,0 +1,65 @@
+/******************************************************************************
+ *
+ * Extension of AMDiS - Adaptive multidimensional simulations
+ *
+ * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
+ * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
+ *
+ * Authors: Simon Praetorius et al.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *
+ * See also license.opensource.txt in the distribution.
+ * 
+ ******************************************************************************/
+
+
+#ifndef EXTENSIONS_REFINE_OPERATION_H
+#define EXTENSIONS_REFINE_OPERATION_H
+
+#include <vector>
+#include "AMDiS_fwd.h"
+
+namespace AMDiS { namespace extensions {
+
+  /// Operations performed before and after refinement/ coarsening
+  struct StandardRefineOperation
+  {
+    virtual ~StandardRefineOperation() {};
+    virtual void beforeRefine(AdaptInfo* adaptInfo, Flag markFlag) {}
+    virtual void beforeCoarsen(AdaptInfo* adaptInfo, Flag markFlag) {}
+    virtual void afterCoarsen(AdaptInfo* adaptInfo, Flag markFlag) {}  
+  };
+
+  /// vector of operations performed before and after refinement/ coarsening
+  struct CoupledRefineOperation : public StandardRefineOperation
+  {
+    CoupledRefineOperation(std::vector<StandardRefineOperation*> operations_) 
+      : operations(operations_) {}
+      
+    void beforeRefine(AdaptInfo* adaptInfo, Flag markFlag) override 
+    {
+      for (size_t i = 0; i < operations.size(); i++)
+	  operations[i]->beforeRefine(adaptInfo, markFlag);
+    }
+    
+    void beforeCoarsen(AdaptInfo* adaptInfo, Flag markFlag) override
+    {
+      for (size_t i = 0; i < operations.size(); i++)
+	operations[i]->beforeCoarsen(adaptInfo, markFlag);
+    }
+    void afterCoarsen(AdaptInfo* adaptInfo, Flag markFlag) override
+    {
+      for (size_t i = 0; i < operations.size(); i++)
+	operations[i]->afterCoarsen(adaptInfo, markFlag);
+    }
+
+  protected:
+    std::vector<StandardRefineOperation*> operations;
+  }; 
+
+} }
+
+#endif
diff --git a/extensions/Refinement.h b/extensions/Refinement.h
index 9dadce2ca5553b863b334e86a2b32f33e030a1ca..282cdf4ef5bcc45b5dda291b36a15bec03ad9e51 100644
--- a/extensions/Refinement.h
+++ b/extensions/Refinement.h
@@ -20,111 +20,11 @@
 #define EXTENSIONS_REFINEMENT_H
 
 #include "ElementFunction.h"
+#include "RefineOperations.h"
+#include "MeshFunction_Level.h"
 
 namespace AMDiS { namespace extensions {
 
-
-/** \brief
- * Abstract class that can be passed to RefinementLevel* as indicator where
- * to refine the mesh up to which level. It is an AbstractFunction that 
- * overloads the operator() method to return a level or a meshsize depending
- * on the coords/data passed to the operator.
- * You can switch between meshsize and level with the methods hToLevel(double) and 
- * levelToH(int)
- **/
-template<typename T, typename T2>
-class MeshRefinementFunction : public AbstractFunction<T2, T>
-{
-public:
-
-  MeshRefinementFunction(Mesh* mesh_) :
-    AbstractFunction<T2, T>(0),
-    mesh(mesh_), 
-    globalSize(0)
-  {
-      h0 = getMacroMeshSize(mesh);
-      reduction = 1.0 / std::sqrt(2.0); // if dim==2
-  }
-
-  int getGlobalSize() { return globalSize; }
-
-  double meshSize() { return h0; }
-  
-  virtual void init(ElInfo* elInfo) {}
-
-  virtual T2 operator()(const T &value) const { return globalSize; }
-  virtual T2 getLevel() const { return globalSize; }
-  
-  virtual double indicator(const T &value) const { return 1.0; }
-
-protected:
-
-  int hToLevel(double h) {
-      int level = static_cast<int>(std::floor(std::log(h / h0) / std::log(reduction)));
-      return level;
-  }
-
-  double levelToH(int level) {
-      double h = std::pow(reduction,level)*h0;
-      return h;
-  }
-
-  double getMacroMeshSize(Mesh* mesh) {
-      FixVec<WorldVector<double>, VERTEX> coords = mesh->getMacroElement(0)->getCoord();
-      double h = 0.0;
-      for (int i = 0; i < coords.size(); ++i)
-          for (int j = i + 1; j < coords.size(); ++j)
-              h = std::max(h, norm(coords[i]-coords[j]));
-      return h;
-  }
-
-protected:
-
-  Mesh* mesh;
-
-  int globalSize;
-
-  double h0;
-  double reduction;
-};
-
-/// Operations performed before and after refinement/ coarsening
-struct StandardRefineOperation
-{
-  virtual ~StandardRefineOperation() {};
-  virtual void beforeRefine(AdaptInfo* adaptInfo, Flag markFlag) {}
-  virtual void beforeCoarsen(AdaptInfo* adaptInfo, Flag markFlag) {}
-  virtual void afterCoarsen(AdaptInfo* adaptInfo, Flag markFlag) {}  
-};
-
-/// vector of operations performed before and after refinement/ coarsening
-struct CoupledRefineOperation : public StandardRefineOperation
-{
-  CoupledRefineOperation(std::vector<StandardRefineOperation*> operations_) 
-    : operations(operations_) {}
-    
-  void beforeRefine(AdaptInfo* adaptInfo, Flag markFlag) override 
-  {
-    for (size_t i = 0; i < operations.size(); i++)
-	operations[i]->beforeRefine(adaptInfo, markFlag);
-  }
-  
-  void beforeCoarsen(AdaptInfo* adaptInfo, Flag markFlag) override
-  {
-    for (size_t i = 0; i < operations.size(); i++)
-      operations[i]->beforeCoarsen(adaptInfo, markFlag);
-  }
-  void afterCoarsen(AdaptInfo* adaptInfo, Flag markFlag) override
-  {
-    for (size_t i = 0; i < operations.size(); i++)
-      operations[i]->afterCoarsen(adaptInfo, markFlag);
-  }
-
-protected:
-   std::vector<StandardRefineOperation*> operations;
-}; 
-
-
 /** \brief
  * Base class for Refinement structure to perform local anisotropic refinement
  */
@@ -140,6 +40,7 @@ public:
     adaptInfo(NULL),
     refineOperation(NULL),
     numRefinements0(15),
+    finished(true),
     globalRefined(false)
   {	
     FUNCNAME("RefinementLevel::RefinementLevel()");
@@ -167,13 +68,26 @@ public:
     refineOperation = new StandardRefineOperation;
   }
   
-  virtual ~RefinementLevel() {
+  virtual ~RefinementLevel() 
+  {
+    finalize();
+    
     delete coarseningManager;
     delete refinementManager;
     if (refineOperation)
       delete refineOperation;
   }
   
+  void finalize()
+  {
+    if (!finished) {
+      #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+      Parallel::MeshDistributor::globalMeshDistributor->checkMeshChange();
+      #endif
+    }
+    finished = true;
+  }
+  
   void setRefineOperation(AdaptInfo* adaptInfo_,
 			  StandardRefineOperation* refineOperation_)
   {
@@ -319,6 +233,8 @@ public:
 	
   bool refineMesh(Flag markFlag, bool onlyRefine) 
   {
+    finished = false;
+    
     int oldSize = mesh->getNumberOfVertices();
     refineOperation->beforeRefine(adaptInfo, markFlag);
     if (markFlag.isSet(1))
@@ -355,6 +271,7 @@ protected:
   int numRefinements;
   int numRefinements0;
   
+  bool finished;
   bool globalRefined;
 };
 
@@ -372,6 +289,7 @@ public:
     adaptInfo(NULL),
     refineOperation(NULL),
     numRefinements0(15),
+    finished(true),
     globalRefined(false)
   {	
     FUNCNAME("RefinementLevel::RefinementLevel()");
@@ -398,13 +316,26 @@ public:
     refineOperation = new StandardRefineOperation;
   }
   
-  virtual ~RefinementLocal() {
+  virtual ~RefinementLocal() 
+  {
+    finalize();
+    
     delete coarseningManager;
     delete refinementManager;
     if (refineOperation)
       delete refineOperation;
   }
   
+  void finalize()
+  {
+    if (!finished) {
+      #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+      Parallel::MeshDistributor::globalMeshDistributor->checkMeshChange();
+      #endif
+    }
+    finished = true;
+  }
+  
   void setRefineOperation(AdaptInfo* adaptInfo_,
 			  StandardRefineOperation* refineOperation_)
   {
@@ -579,6 +510,8 @@ public:
 	
   bool refineMesh(Flag markFlag, bool onlyRefine) 
   {
+    finished = false;
+    
     int oldSize = mesh->getNumberOfVertices();
     refineOperation->beforeRefine(adaptInfo, markFlag);
     if (markFlag.isSet(1))
@@ -611,6 +544,7 @@ protected:
   int numRefinements;
   int numRefinements0;
   
+  bool finished;
   bool globalRefined;
   bool onlyRefine;
 };
diff --git a/extensions/RefinementExpression.h b/extensions/RefinementExpression.h
new file mode 100644
index 0000000000000000000000000000000000000000..09837c1133f3d3d54c2fd14d540998b2c6fe5c75
--- /dev/null
+++ b/extensions/RefinementExpression.h
@@ -0,0 +1,355 @@
+/******************************************************************************
+ *
+ * Extension of AMDiS - Adaptive multidimensional simulations
+ *
+ * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
+ * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
+ *
+ * Authors: Simon Praetorius et al.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *
+ * See also license.opensource.txt in the distribution.
+ * 
+ ******************************************************************************/
+
+
+#ifndef EXTENSIONS_REFINEMENT_EXPRESSION_H
+#define EXTENSIONS_REFINEMENT_EXPRESSION_H
+
+#include "ProblemStat.h"
+#include "ElementFunction.h"
+#include "RefineFunctions.h"
+#include "RefineOperations.h"
+#include "Expressions.h"
+
+namespace AMDiS { namespace extensions {
+
+
+/** \brief
+ * Base class for Refinement structure to perform local anisotropic refinement
+ */
+class RefinementExpression
+{
+public:
+
+  RefinementExpression(ProblemStat& prob, int component = 0, bool doCalcMeshSize_ = false)
+    : mesh(prob.getMesh(component)), 
+      adaptInfo(NULL),
+      refineOperation(NULL),
+      numRefinements0(15),
+      doCalcMeshSize(doCalcMeshSize_),
+      onlyRefine(false),
+      finished(true),
+      refinementManagerCreated(false)
+  {
+    coarseningManager = prob.getCoarseningManager();
+    refinementManager = prob.getRefinementManager();
+    numRefinements = numRefinements0;    
+    refineOperation = new StandardRefineOperation;
+  }
+  
+  RefinementExpression(Mesh *mesh_, bool doCalcMeshSize_ = false)
+    : mesh(mesh_), 
+      adaptInfo(NULL),
+      refineOperation(NULL),
+      numRefinements0(15),
+      doCalcMeshSize(doCalcMeshSize_),
+      onlyRefine(false),
+      finished(true),
+      refinementManagerCreated(true)
+  {	
+    FUNCNAME("RefinementExpression::RefinementLevel()");
+    
+    switch (mesh->getDim()) {
+    case 1:
+      coarseningManager = new CoarseningManager1d();
+      refinementManager = new RefinementManager1d();
+      break;
+    case 2:
+      coarseningManager = new CoarseningManager2d();
+      refinementManager = new RefinementManager2d();
+      break;
+    case 3:
+      coarseningManager = new CoarseningManager3d();
+      refinementManager = new RefinementManager3d();
+      break;
+    default:
+      ERROR_EXIT("invalid dim!\n");
+    }
+
+    numRefinements = numRefinements0;
+    
+    refineOperation = new StandardRefineOperation;
+  }
+  
+  virtual ~RefinementExpression() 
+  {
+    finalize();
+    
+    if (refinementManagerCreated) {
+      delete coarseningManager;
+      delete refinementManager;
+    }
+    
+    if (refineOperation)
+      delete refineOperation;
+  }
+  
+  void finalize()
+  {
+    if (!finished) {
+      #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+      Parallel::MeshDistributor::globalMeshDistributor->checkMeshChange();
+      #endif
+    }
+    finished = true;
+  }
+  
+  template <typename Term>
+  bool refine(Term term) 
+  {
+    FUNCNAME("RefinementExpression::refine()");
+
+    double minH = 0.0, maxH = 1.0;
+    int minLevel = 100, maxLevel = 0;
+    int oldMeshChangeIdx = mesh->getChangeIndex();
+    
+    bool meshChanged = true;
+    Flag markFlag;
+    int oldNr = 0, oldOldNr = 0, i = 0;
+    while (meshChanged && i < numRefinements) {
+      markElements(term, markFlag);
+      meshChanged = refineMesh(markFlag, onlyRefine);
+      
+      // compare nr of vertices
+      int nr = mesh->getNumberOfVertices();
+      meshChanged = meshChanged && oldOldNr!=nr && oldNr!=nr;
+      
+      if (meshChanged) {
+	if (doCalcMeshSize) {
+	  calcMeshSizes(minH, maxH, minLevel, maxLevel, false); 
+	  MSG("(local) mesh sizes: [%f, %f], Vs: %d, ELs: %d\n", 
+	    minH, maxH, nr, mesh->getNumberOfElements());
+	} else {
+	  MSG("(local) #Vertics: %d, #Elements: %d\n", nr, mesh->getNumberOfElements());
+	}
+      }
+			
+      oldOldNr = oldNr;
+      oldNr = nr; 
+      i++;
+    }
+    
+    calcMeshSizes(minH, maxH, minLevel, maxLevel, true); 
+    MSG("Final (global) mesh: [%f, %f], Vs: %d, ELs: %d, Level: [%d, %d]\n",
+      minH, maxH, mesh->getNumberOfVertices(), mesh->getNumberOfElements(), minLevel, maxLevel);
+      
+    return oldMeshChangeIdx != mesh->getChangeIndex();
+  }
+  
+
+  template <typename Term>
+  bool refine(int numRefinements_, Term term, bool onlyRefine_= false) 
+  { 
+    numRefinements = numRefinements_; 
+    setOnlyRefine(onlyRefine_);
+    bool refined = refine(term);  
+    numRefinements = numRefinements0; 
+    return refined;
+  }
+  
+
+  template <int N, typename Term>
+  bool refine(Term term, bool onlyRefine_= false) 
+  { 
+    numRefinements = N; 
+    setOnlyRefine(onlyRefine_);
+    bool refined = refine(term);  
+    numRefinements = numRefinements0; 
+    return refined;
+  }
+  
+  
+  template<typename Term>
+  void markElements(Term term, Flag &markFlag) 
+  {    
+    bool elMarkRefine = false, elMarkCoarsen = false;
+    
+    GenericOperatorTerm<Term> ot(term);
+    
+    int dim = mesh->getDim();
+    Quadrature* quad = Quadrature::provideQuadrature(dim, 0); // 1 point in the center
+
+    Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_GRD_LAMBDA;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag);
+    while (elInfo) {
+      term.initElement(&ot, elInfo, NULL, quad);
+      
+      int refineLevel = boost::numeric_cast<int>(term(0)); // eval expression
+      int oldLevel = elInfo->getLevel();
+      elInfo->getElement()->setMark( calcMark(refineLevel, oldLevel) );
+
+      elMarkRefine |= elInfo->getElement()->getMark() == 1;
+      elMarkCoarsen |= elInfo->getElement()->getMark() == -1;
+      elInfo = stack.traverseNext(elInfo);
+    }
+      
+    markFlag= 0;
+    if(elMarkRefine) 
+      markFlag = 1;
+    if(elMarkCoarsen) 
+      markFlag|= 2;
+  }
+
+  int getNumRefinements() 
+  {
+    return numRefinements;
+  }
+
+  void calcMeshSizes(double& minH, double& maxH, int& minLevel, int& maxLevel, bool allReduce = false) 
+  {
+    FixVec<WorldVector<double>, VERTEX> coords(mesh->getDim(), NO_INIT);
+
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
+    minH = 1e15; maxH = 0.0;
+    int k = 0;
+    minLevel = 100;
+    maxLevel = 0;
+    while (elInfo) {
+      maxLevel = std::max(maxLevel,elInfo->getLevel());
+      minLevel = std::min(minLevel,elInfo->getLevel());
+      coords = elInfo->getCoords();
+      double h = 0.0;
+      for (int i = 0; i < coords.size(); i++) {
+        for (int j = 0; j < coords.size(); j++) {
+	  if (i != j)
+            h = std::max(h,norm(coords[i]-coords[j]));
+        }
+      }
+      minH = std::min(h, minH);
+      maxH = std::max(h, maxH);
+      elInfo = stack.traverseNext(elInfo);
+      k++;
+    }
+    minLevel += mesh->getMacroElementLevel();
+    maxLevel += mesh->getMacroElementLevel();
+    
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+    if (allReduce) {
+      Parallel::mpi::globalMin(minH);
+      Parallel::mpi::globalMax(maxH);
+      Parallel::mpi::globalMin(minLevel);
+      Parallel::mpi::globalMax(maxLevel);
+    }
+#endif
+  }
+
+
+  double calcMeshSize(ElInfo *elInfo, bool allReduce = false) 
+  {
+    FixVec<WorldVector<double>, VERTEX> coords(mesh->getDim(), NO_INIT);
+    coords = elInfo->getCoords();
+    double h = 0.0;
+    for (int i = 0; i < coords.size(); i++) {
+      for (int j = 0; j < coords.size(); j++) {
+        if (i != j)
+          h = std::max(h,norm(coords[i]-coords[j]));
+      }
+    }
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+    if (allReduce)
+      Parallel::mpi::globalMax(h);
+#endif
+
+    return h;
+  }
+
+
+  int calcMark(double refineH, double currentH)
+  {
+    return (refineH < currentH ? 
+        1 : (refineH > currentH * (mesh->getDim() == 1 ? 
+          2.0 : (mesh->getDim() == 2 ? 
+          std::sqrt(2.0) : 
+          std::sqrt(2.0)/2.0 + 0.5)) ? 
+        -1 : 
+        0));
+  }
+
+
+  int calcMark(int refineLevel, int currentLevel)
+  {
+    int levelDiff = refineLevel - currentLevel;
+    return (levelDiff > 0 ? 1 : (levelDiff < 0 ? -1 : 0));
+  }
+
+	
+  bool refineMesh(Flag markFlag, bool onlyRefine) 
+  {
+    finished = false;
+    
+    int oldSize = mesh->getNumberOfVertices();
+    refineOperation->beforeRefine(adaptInfo, markFlag);
+    if (markFlag.isSet(1))
+      refinementManager->refineMesh(mesh);
+      
+    refineOperation->beforeCoarsen(adaptInfo, markFlag);
+    if (markFlag.isSet(2) && !onlyRefine)
+      coarseningManager->coarsenMesh(mesh);
+      
+    refineOperation->afterCoarsen(adaptInfo, markFlag);
+    
+    if (markFlag.isSet(1) || markFlag.isSet(2)) {
+      int newSize = mesh->getNumberOfVertices();
+      if (oldSize != newSize) 
+        return true;
+    }
+    return false;
+  }
+  
+  void setRefineOperation(AdaptInfo* adaptInfo_,
+			  StandardRefineOperation* refineOperation_)
+  {
+    if (refineOperation)
+      delete refineOperation;
+    
+    adaptInfo = adaptInfo_;
+    refineOperation = refineOperation_;
+  }
+
+  void setOnlyRefine(bool onlyRefine_)
+  {
+    onlyRefine = onlyRefine_;
+  }
+
+  void setCalcMeshSize(bool calc) { doCalcMeshSize = calc; }
+  
+  RefinementManager* getRefinementManager() { return refinementManager; }
+  CoarseningManager* getCoarseningManager() { return coarseningManager; }
+
+protected:
+
+  Mesh* mesh;
+  RefinementManager* refinementManager;
+  CoarseningManager* coarseningManager;
+  
+  AdaptInfo* adaptInfo;
+  StandardRefineOperation* refineOperation;
+
+  int numRefinements;
+  int numRefinements0;
+  
+  bool doCalcMeshSize;
+  bool onlyRefine;
+  bool finished;
+  bool refinementManagerCreated;
+};
+
+} }
+
+#endif // EXTENSIONS_REFINEMENT_EXPRESSION_H
diff --git a/extensions/base_problems/CahnHilliard.h b/extensions/base_problems/CahnHilliard.h
index e22f54b0ff8ba93d166d4f4b44c8fa3c20c4d863..a178877a83da36c69c563541d12870bd00b619e4 100644
--- a/extensions/base_problems/CahnHilliard.h
+++ b/extensions/base_problems/CahnHilliard.h
@@ -34,7 +34,7 @@ namespace detail {
   {
   public: // definition of types
 
-    typedef BaseProblem<ProblemStatType> super;
+    typedef BaseProblem<ProblemStatType>  super;
     typedef CahnHilliard<ProblemStatType> self;
 
   public: // public methods
diff --git a/extensions/base_problems/CahnHilliard.hh b/extensions/base_problems/CahnHilliard.hh
index 2e8835a57fcfe02f1345208efcb09a486f515362..7062310d89f6bf1fd58a9dbafa31bfba604365f5 100644
--- a/extensions/base_problems/CahnHilliard.hh
+++ b/extensions/base_problems/CahnHilliard.hh
@@ -21,200 +21,201 @@
 
 #include "HL_SignedDistTraverse.h"
 #include "Recovery.h"
-#include "GenericOperatorTerm.h"
+#include "Expressions.h"
 
 namespace AMDiS { namespace base_problems {
 
 namespace detail {
-
-template<typename P>
-CahnHilliard<P>::CahnHilliard(const std::string &name_) :
-  super(name_),
-  useMobility(false),
-  useReinit(false),
-  doubleWell(0),
-  gamma(1.0),
-  eps(0.1),
-  minusEps(-0.1),
-  epsInv(10.0),
-  minusEpsInv(-10.0),
-  epsSqr(0.01),
-  minusEpsSqr(-0.01)
-{
-  // parameters for CH
-  Parameters::get(name_ + "->use mobility", useMobility); // mobility
-  Parameters::get(name_ + "->gamma", gamma); // mobility
-  Parameters::get(name_ + "->epsilon", eps); // interface width
-  
-  // type of double well: 0= [0,1], 1= [-1,1]
-  Parameters::get(name_ + "->double-well type", doubleWell); 
-  
-  Parameters::get(name_ + "->use reinit", useReinit);
-
-  // transformation of the parameters
-  minusEps = -eps;
-  epsInv = 1.0/eps;
-  minusEpsInv = -epsInv;
-  epsSqr = sqr(eps);
-  minusEpsSqr = -epsSqr;
-}
-
-
-template<typename P>
-void CahnHilliard<P>::solveInitialProblem(AdaptInfo *adaptInfo) 
-{
-  using namespace AMDiS::extensions;
-  Flag initFlag = self::initDataFromFile(adaptInfo);
-
-  if (!initFlag.isSet(DATA_ADOPTED)) {
-    int initialInterface = 0;
-    Initfile::get(self::name + "->initial interface", initialInterface);
-    double initialEps = eps;
-    Initfile::get(self::name + "->initial epsilon", initialEps);
-
-    if (initialInterface == 0) {
-      /// horizontale Linie
-      double a= 0.0, dir= -1.0;
-      Initfile::get(self::name + "->line->pos", a);
-      Initfile::get(self::name + "->line->direction", dir);
-      self::prob->getSolution()->getDOFVector(0)->interpol(new Plane(a, dir));
-    }
-    else if (initialInterface == 1) {
-      /// schraege Linie
-      double theta = m_pi/4.0;
-      self::prob->getSolution()->getDOFVector(0)->interpol(new PlaneRotation(0.0, theta, 1.0));
-      transformDOFInterpolation(self::prob->getSolution()->getDOFVector(0),new PlaneRotation(0.0, -theta, -1.0), new AMDiS::Min<double>);
-    }
-    else if (initialInterface == 2) {
-      /// Ellipse
-      double a= 1.0, b= 1.0;
-      Initfile::get(self::name + "->ellipse->a", a);
-      Initfile::get(self::name + "->ellipse->b", b);
-      self::prob->getSolution()->getDOFVector(0)->interpol(new Ellipse(a,b));
-    }
-    else if (initialInterface == 3) {
-      /// zwei horizontale Linien
-      double a= 0.75, b= 0.375;
-      Initfile::get(self::name + "->lines->pos1", a);
-      Initfile::get(self::name + "->lines->pos2", b);
-      self::prob->getSolution()->getDOFVector(0)->interpol(new Plane(a, -1.0));
-      transformDOFInterpolation(self::prob->getSolution()->getDOFVector(0),new Plane(b, 1.0), new AMDiS::Max<double>);
-    }
-    else if (initialInterface == 4) {
-      /// Kreis
-      double radius= 1.0;
-      Initfile::get(self::name + "->kreis->radius", radius);
-      self::prob->getSolution()->getDOFVector(0)->interpol(new Circle(radius));
-    } else if (initialInterface == 5) {
-      /// Rechteck
-      double width = 0.5;
-      double height = 0.3;
-      WorldVector<double> center; center.set(0.5);
-      Initfile::get(self::name + "->rectangle->width", width);
-      Initfile::get(self::name + "->rectangle->height", height);
-      Initfile::get(self::name + "->rectangle->center", center);
-      self::prob->getSolution()->getDOFVector(0)->interpol(new Rectangle(width, height, center));
-    }
     
-    if (useReinit) {
-      FiniteElemSpace* feSpace = FiniteElemSpace::provideFeSpace(
-	const_cast<DOFAdmin*>(self::getMesh()->getVertexAdmin()),
-	Lagrange::getLagrange(self::getMesh()->getDim(), 1),
-	self::getMesh(),
-	"P1");
-      DOFVector<double> tmp(feSpace, "tmp");
-      tmp.interpol(self::prob->getSolution()->getDOFVector(0));
+  template<typename P>
+  CahnHilliard<P>::CahnHilliard(const std::string &name_) 
+    : super(name_),
+      useMobility(false),
+      useReinit(false),
+      doubleWell(0),
+      gamma(1.0),
+      eps(0.1),
+      minusEps(-0.1),
+      epsInv(10.0),
+      minusEpsInv(-10.0),
+      epsSqr(0.01),
+      minusEpsSqr(-0.01)
+  {
+    // parameters for CH
+    Parameters::get(name_ + "->use mobility", useMobility); // mobility
+    Parameters::get(name_ + "->gamma", gamma); // mobility
+    Parameters::get(name_ + "->epsilon", eps); // interface width
     
-      HL_SignedDistTraverse reinit("reinit", self::getMesh()->getDim());
-      reinit.calcSignedDistFct(adaptInfo, &tmp);
+    // type of double well: 0= [0,1], 1= [-1,1]
+    Parameters::get(name_ + "->double-well type", doubleWell); 
     
-#ifndef HAVE_PARALLEL_DOMAIN_AMDIS
-      Recovery recovery(L2_NORM, 1);
-      recovery.recoveryUh(&tmp, *self::prob->getSolution()->getDOFVector(0));
-#else
-      self::prob->getSolution()->getDOFVector(0)->interpol(&tmp);
-#endif
+    Parameters::get(name_ + "->use reinit", useReinit);
+
+    // transformation of the parameters
+    minusEps = -eps;
+    epsInv = 1.0/eps;
+    minusEpsInv = -epsInv;
+    epsSqr = sqr(eps);
+    minusEpsSqr = -epsSqr;
+  }
+
+
+  template<typename P>
+  void CahnHilliard<P>::solveInitialProblem(AdaptInfo *adaptInfo) 
+  {
+    using namespace AMDiS::extensions;
+    Flag initFlag = self::initDataFromFile(adaptInfo);
+    
+    DOFVector<double>* c = self::prob->getSolution()->getDOFVector(1);
+
+    if (!initFlag.isSet(DATA_ADOPTED)) {
+      int initialInterface = 0;
+      Parameters::get(self::name + "->initial interface", initialInterface);
+      double initialEps = eps;
+      Parameters::get(self::name + "->initial epsilon", initialEps);
+
+      if (initialInterface == 0) {
+	/// horizontale Linie
+	double a= 0.0, dir= -1.0;
+	Parameters::get(self::name + "->line->pos", a);
+	Parameters::get(self::name + "->line->direction", dir);
+	c->interpol(new Plane(a, dir));
+      }
+      else if (initialInterface == 1) {
+	/// schraege Linie
+	double theta = m_pi/4.0;
+	c->interpol(new PlaneRotation(0.0, theta, 1.0));
+	transformDOFInterpolation(c, new PlaneRotation(0.0, -theta, -1.0), new AMDiS::Min<double>);
+      }
+      else if (initialInterface == 2) {
+	/// Ellipse
+	double a= 1.0, b= 1.0;
+	Parameters::get(self::name + "->ellipse->a", a);
+	Parameters::get(self::name + "->ellipse->b", b);
+	c->interpol(new Ellipse(a,b));
+      }
+      else if (initialInterface == 3) {
+	/// zwei horizontale Linien
+	double a= 0.75, b= 0.375;
+	Parameters::get(self::name + "->lines->pos1", a);
+	Parameters::get(self::name + "->lines->pos2", b);
+	c->interpol(new Plane(a, -1.0));
+	transformDOFInterpolation(c, new Plane(b, 1.0), new AMDiS::Max<double>);
+      }
+      else if (initialInterface == 4) {
+	/// Kreis
+	double radius= 1.0;
+	Parameters::get(self::name + "->kreis->radius", radius);
+	c->interpol(new Circle(radius));
+      } else if (initialInterface == 5) {
+	/// Rechteck
+	double width = 0.5;
+	double height = 0.3;
+	WorldVector<double> center; center.set(0.5);
+	Parameters::get(self::name + "->rectangle->width", width);
+	Parameters::get(self::name + "->rectangle->height", height);
+	Parameters::get(self::name + "->rectangle->center", center);
+	c->interpol(new Rectangle(width, height, center));
+      }
+      
+      if (useReinit) {
+	FiniteElemSpace* feSpace = FiniteElemSpace::provideFeSpace(
+	  const_cast<DOFAdmin*>(self::getMesh()->getVertexAdmin()),
+	  Lagrange::getLagrange(self::getMesh()->getDim(), 1),
+	  self::getMesh(),
+	  "P1");
+	DOFVector<double> tmp(feSpace, "tmp");
+	tmp.interpol(c);
+      
+	HL_SignedDistTraverse reinit("reinit", self::getMesh()->getDim());
+	reinit.calcSignedDistFct(adaptInfo, &tmp);
+      
+  #ifndef HAVE_PARALLEL_DOMAIN_AMDIS
+	Recovery recovery(L2_NORM, 1);
+	recovery.recoveryUh(&tmp, *c);
+  #else
+	c->interpol(&tmp);
+  #endif
+      }
+      
+
+      /// create phase-field from signed-dist-function
+      if (doubleWell == 0) {
+	forEachDOF(c, new SignedDistToPhaseField(initialEps));
+      } else {
+	forEachDOF(c, new SignedDistToCh(initialEps));
+      }
     }
+  }
+
+  template<typename P>
+  void CahnHilliard<P>::fillOperators()
+  {  
+    const FiniteElemSpace* feSpace0 = self::prob->getFeSpace(0);
+    const FiniteElemSpace* feSpace1 = self::prob->getFeSpace(1);
     
+    DOFVector<double>* c = self::prob->getSolution()->getDOFVector(1);
 
-    /// create phase-field from signed-dist-function
+    // -nabla*(grad(c))
+    Operator *opChL = new Operator(feSpace0, feSpace1);
+    addSOT(opChL, 1.0);
+    
+    // div(M(c)grad(mu)), with M(c)=gamma/4*(c^2-1)^2
+    Operator *opChLM = new Operator(feSpace1, feSpace0);
+    if (useMobility) {
+      if (doubleWell == 0)
+	addSOT(opChLM, function_(MobilityCH0_(gamma), valueOf(c)) );
+      else
+	addSOT(opChLM, function_(MobilityCH1_(gamma), valueOf(c)) );
+    } else
+      addSOT(opChLM, gamma );
+    
+    // -2*c_old^3 + 3/2*c_old^2
+    Operator *opChWExpl = new Operator(feSpace0, feSpace1);
+    Operator *opChWImpl = new Operator(feSpace0, feSpace1);
     if (doubleWell == 0) {
-      forEachDOF(self::prob->getSolution()->getDOFVector(0),
-        new SignedDistToPhaseField(initialEps));
+      addZOT(opChWExpl, -2.0*pow<3>(valueOf(c)) + 1.5*pow<2>(valueOf(c)));
+      addZOT(opChWImpl, -3.0*pow<2>(valueOf(c)) + 3.0*valueOf(c) - 0.5);
     } else {
-      forEachDOF(self::prob->getSolution()->getDOFVector(0),
-        new SignedDistToCh(initialEps));
+      addZOT(opChWExpl, -2.0*pow<3>(valueOf(c)));
+      addZOT(opChWImpl, -3.0*pow<2>(valueOf(c)) + 1.0);
     }
-  }
-}
-
-template<typename P>
-void CahnHilliard<P>::fillOperators()
-{  
-  const FiniteElemSpace* feSpace0 = self::prob->getFeSpace(0);
-  const FiniteElemSpace* feSpace1 = self::prob->getFeSpace(1);
-  
-  DOFVector<double>* c = self::prob->getSolution()->getDOFVector(0);
-//   DOFVector<double>* mu = self::prob->getSolution()->getDOFVector(1);
-
-  // -nabla*(grad(c))
-  Operator *opChL = new Operator(feSpace0, feSpace0);
-  addSOT(opChL, 1.0);
-  
-  // div(M(c)grad(mu)), with M(c)=gamma/4*(c^2-1)^2
-  Operator *opChLM = new Operator(feSpace1, feSpace1);
-  if (useMobility) {
-    if (doubleWell == 0)
-      addSOT(opChLM, function_(MobilityCH0_(gamma), valueOf(c)) );
-    else
-      addSOT(opChLM, function_(MobilityCH1_(gamma), valueOf(c)) );
-  } else
-    addSOT(opChLM, gamma );
-  
-  // -2*c_old^3 + 3/2*c_old^2
-  Operator *opChWExpl = new Operator(feSpace0, feSpace0);
-  Operator *opChWImpl = new Operator(feSpace0, feSpace0);
-  if (doubleWell == 0) {
-    addZOT(opChWExpl, -2.0*pow<3>(valueOf(c)) + 1.5*pow<2>(valueOf(c)));
-    addZOT(opChWImpl, -3.0*pow<2>(valueOf(c)) + 3.0*valueOf(c) - 0.5);
-  } else {
-    addZOT(opChWExpl, -2.0*pow<3>(valueOf(c)));
-    addZOT(opChWImpl, -3.0*pow<2>(valueOf(c)) + 1.0);
+
+    
+    // mu + eps^2*laplace(c) + c - 3*(c_old^2)*c = -2*c_old^3 [+ BC]
+    // ----------------------------------------------------------------------
+    self::prob->addMatrixOperator(*opChWImpl, 0, 1);          			/// < -3*phi*c*c_old^2 , psi >
+    self::prob->addMatrixOperator(*opChL, 0, 1, &minusEpsSqr, &minusEpsSqr);   	/// < -eps^2*phi*grad(c) , grad(psi) >
+    
+    // . . . vectorOperators . . . . . . . . . . . . . . .
+    self::prob->addVectorOperator(*opChWExpl, 0);            			/// < -2*phi*c_old^3 , psi >
+
+    Operator *opM01new = new Operator(feSpace0, feSpace0);
+    addZOT(opM01new, 1.0);
+    self::prob->addMatrixOperator(*opM01new, 0, 0);              			/// < phi*mu , psi >
+    
+    // dt(c) = laplace(mu) - u*grad(c)
+    // -----------------------------------
+    Operator *opM10new = new Operator(feSpace1, feSpace1);
+    addZOT(opM10new, 1.0);
+    self::prob->addMatrixOperator(*opM10new, 1, 1); 				/// < phi*c/tau , psi >
+    self::prob->addMatrixOperator(*opChLM, 1, 0, self::getTau(), self::getTau());	/// < phi*grad(mu) , grad(psi) >
+    
+    // . . . vectorOperators . . . . . . . . . . . . . . .
+    Operator *opChMold = new Operator(feSpace1, feSpace1);
+    addZOT(opChMold, valueOf(c));
+    self::prob->addVectorOperator(*opChMold, 1);   				/// < phi*c^old/tau , psi >
   }
 
-  
-  // mu + eps^2*laplace(c) + c - 3*(c_old^2)*c = -2*c_old^3 [+ BC]
-  // ----------------------------------------------------------------------
-  self::prob->addMatrixOperator(*opChWImpl, 0, 0);          /// < -3*phi*c*c_old^2 , psi >
-  self::prob->addMatrixOperator(*opChL, 0, 0, &minusEpsSqr, &minusEpsSqr);   /// < -eps^2*phi*grad(c) , grad(psi) >
-  // . . . vectorOperators . . . . . . . . . . . . . . .
-  self::prob->addVectorOperator(*opChWExpl, 0);            /// < -2*phi*c_old^3 , psi >
-
-  Operator *opM01new = new Operator(feSpace0, feSpace1);
-  addZOT(opM01new, 1.0);
-  self::prob->addMatrixOperator(*opM01new, 0, 1);              /// < phi*mu , psi >
-  
-  // dt(c) = laplace(mu) - u*grad(c)
-  // -----------------------------------
-  Operator *opM10new = new Operator(feSpace1, feSpace0);
-  addZOT(opM10new, 1.0);
-  self::prob->addMatrixOperator(*opM10new, 1, 0, self::getInvTau(), self::getInvTau()); /// < phi*c/tau , psi >
-  self::prob->addMatrixOperator(*opChLM, 1, 1);                /// < phi*grad(mu) , grad(psi) >
-  // . . . vectorOperators . . . . . . . . . . . . . . .
-  Operator *opChMold = new Operator(feSpace1, feSpace0);
-  addZOT(opChMold, valueOf(c));
-  self::prob->addVectorOperator(*opChMold, 1, self::getInvTau(), self::getInvTau());   /// < phi*c^old/tau , psi >
-}
-
-
-template<typename P>
-void CahnHilliard<P>::finalizeData()
-{
-//   self::setAssembleMatrixOnlyOnce_butTimestepChange(0,1);
-//   self::setAssembleMatrixOnlyOnce_butTimestepChange(1,0);
-//   if (!useMobility)
-//     self::setAssembleMatrixOnlyOnce_butTimestepChange(1,1);
-}
+
+  template<typename P>
+  void CahnHilliard<P>::finalizeData()
+  {
+  //   self::setAssembleMatrixOnlyOnce_butTimestepChange(0,1);
+  //   self::setAssembleMatrixOnlyOnce_butTimestepChange(1,0);
+  //   if (!useMobility)
+  //     self::setAssembleMatrixOnlyOnce_butTimestepChange(1,1);
+  }
 
 } // end namespace detail
 
diff --git a/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase.cc b/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase.cc
index 6743b4ea2669d3b0c0754c4247febd913542a1f5..b3a5959496aae52ec6b12f93d20e86717cae03a9 100644
--- a/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase.cc
+++ b/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase.cc
@@ -19,6 +19,7 @@
 #include "SignedDistFunctors.h"
 #include "PhaseFieldConvert.h"
 #include "POperators.h"
+#include "Expressions.h"
 
 namespace AMDiS { namespace base_problems {
 
@@ -79,7 +80,7 @@ CahnHilliardNavierStokes_TwoPhase::CahnHilliardNavierStokes_TwoPhase(const std::
   // Parameters for NS-Coupling
   // cahn-hiliard-force: sigma*mu*grad(c)
   Initfile::get(name + "->sigma", sigma); // surface tension
-  surfaceTension = sigma*3.0/(2.0*sqrt(2.0)) / eps;
+  surfaceTension = sigma*3.0/(2.0*std::sqrt(2.0)) / eps;
 
   MSG("surface tension: %e\n", surfaceTension);
     
@@ -149,6 +150,8 @@ void CahnHilliardNavierStokes_TwoPhase::fillOperators()
   // variable order:
   // (c, mu, u0, u1 [, u2], p)
   
+  DOFVector<double>* c = prob->getSolution()->getDOFVector(0);
+  
   WorldVector<DOFVector<double>* > vel;
   for (size_t i = 0; i < dow; i++)
     vel[i] = prob->getSolution()->getDOFVector(2+i);
@@ -158,26 +161,22 @@ void CahnHilliardNavierStokes_TwoPhase::fillOperators()
   // -----------------------------------
   /// < phi*c/tau , psi >
   Operator *opChMnew = new Operator(prob->getFeSpace(0),prob->getFeSpace(0));
-  opChMnew->addZeroOrderTerm(new Simple_ZOT);
-  prob->addMatrixOperator(*opChMnew, 0, 0, getInvTau()); 
+  addZOT(opChMnew, 1.0 );
+  prob->addMatrixOperator(*opChMnew, 0, 0, getInvTau(), getInvTau()); 
   
   /// < phi*c^old/tau , psi >
   Operator *opChMold = new Operator(prob->getFeSpace(0),prob->getFeSpace(0));
-  opChMold->addZeroOrderTerm(new VecAtQP_ZOT(prob->getSolution()->getDOFVector(0)));
-  prob->addVectorOperator(*opChMold,0, getInvTau());   
+  addZOT(opChMold, valueOf(c) );
+  prob->addVectorOperator(*opChMold,0, getInvTau(), getInvTau());   
   
   /// < phi*grad(mu) , grad(psi) >
   // div(M(c)grad(mu)), with M(c)=gamma/4*(c^2-1)^2
   Operator *opChLM = new Operator(prob->getFeSpace(0),prob->getFeSpace(1));
   if (useMobility) {
     if (doubleWell == 0)
-      opChLM->addSecondOrderTerm(new VecAtQP_SOT(
-	prob->getSolution()->getDOFVector(0),
-	new MobilityCH0(gamma)));
+      addSOT(opChLM, function_(wrap(new MobilityCH0(gamma)), valueOf(c)) );
     else
-      opChLM->addSecondOrderTerm(new VecAtQP_SOT(
-	prob->getSolution()->getDOFVector(0),
-	new MobilityCH1(gamma)));
+      addSOT(opChLM, function_(wrap(new MobilityCH1(gamma)), valueOf(c)) );
   } else
     opChLM->addSecondOrderTerm(new Simple_SOT(gamma));
   prob->addMatrixOperator(*opChLM, 0, 1);
@@ -185,9 +184,9 @@ void CahnHilliardNavierStokes_TwoPhase::fillOperators()
   /// < u_old * grad(c) - u_old * grad(c_old), psi >
   Operator *uGradC = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
   if (useConservationForm)
-    uGradC->addTerm(new WorldVec_FOT(vel, -1.0), GRD_PSI);
+    addFOT(uGradC, -1.0*valueOf(vel), GRD_PSI);
   else
-    uGradC->addTerm(new WorldVec_FOT(vel), GRD_PHI);
+    addFOT(uGradC, valueOf(vel), GRD_PHI);
   prob->addMatrixOperator(*uGradC, 0, 0);
   uGradC->setUhOld(prob->getSolution()->getDOFVector(0));
   prob->addVectorOperator(*uGradC, 0);
@@ -196,10 +195,9 @@ void CahnHilliardNavierStokes_TwoPhase::fillOperators()
   for (size_t i = 0; i < dow; i++) {
     Operator *uGradC2 = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
     if (useConservationForm)
-      uGradC2->addTerm(new VecAndPartialDerivative_FOT(prob->getSolution()->getDOFVector(0), i, -1.0), GRD_PSI);
-    else {
-      uGradC2->addTerm(new PartialDerivative_ZOT(prob->getSolution()->getDOFVector(0), i));
-    }
+      addFOT(uGradC2, -valueOf(c), i, GRD_PSI);
+    else
+      addZOT(uGradC2, derivativeOf(c, i) );
     prob->addMatrixOperator(*uGradC2, 0, 2+i);
   }
   
@@ -209,33 +207,28 @@ void CahnHilliardNavierStokes_TwoPhase::fillOperators()
   /// < -3*phi*c*c_old^2 , psi >
   // -3*c_old^2 * c
   Operator *opChWImpl = new Operator(prob->getFeSpace(1),prob->getFeSpace(0));
-  opChWImpl->addZeroOrderTerm(new VecAtQP_ZOT(
-    prob->getSolution()->getDOFVector(0),
-    (doubleWell == 0 ? static_cast<AbstractFunction<double, double>*>(new DoubleWell0Diff(-1.0))
-		     : static_cast<AbstractFunction<double, double>*>(new DoubleWell1Diff(-1.0)))));
+  if (doubleWell == 0)
+    addZOT(opChWImpl, function_(wrap(new DoubleWell0Diff(-1.0)), valueOf(c)) );
+  else
+    addZOT(opChWImpl, function_(wrap(new DoubleWell1Diff(-1.0)), valueOf(c)) );
   prob->addMatrixOperator(*opChWImpl, 1, 0);  
   
   /// < -2*phi*c_old^3 , psi >
   // -2*c_old^3 + 3/2*c_old^2
   Operator *opChWExpl = new Operator(prob->getFeSpace(1),prob->getFeSpace(0));
-  opChWExpl->addZeroOrderTerm(new VecAtQP_ZOT(
-    prob->getSolution()->getDOFVector(0),
-    new Pow3Functor(-2.0)));
-  if (doubleWell == 0) {
-    opChWExpl->addZeroOrderTerm(new VecAtQP_ZOT(
-      prob->getSolution()->getDOFVector(0),
-      new Pow2Functor(3.0/2.0)));
-  }
+  addZOT(opChWExpl, -2.0 * pow<3>(valueOf(c)) );
+  if (doubleWell == 0)
+    addZOT(opChWExpl, 1.5 * pow<2>(valueOf(c)) );
   prob->addVectorOperator(*opChWExpl, 1);            
   
   /// < -eps^2*phi*grad(c) , grad(psi) >
   Operator *opChL = new Operator(prob->getFeSpace(1),prob->getFeSpace(0));
-  opChL->addSecondOrderTerm(new Simple_SOT);
-  prob->addMatrixOperator(*opChL, 1, 0, &minusEpsSqr);  
+  addSOT(opChL, minusEpsSqr);
+  prob->addMatrixOperator(*opChL, 1, 0);  
   
   /// < phi*mu , psi >
   Operator *opChM = new Operator(prob->getFeSpace(0),prob->getFeSpace(0));
-  opChM->addZeroOrderTerm(new Simple_ZOT);
+  addZOT(opChM, 1.0);
   prob->addMatrixOperator(*opChM, 1, 1);              
 
   // -----------------------------------------------------------------------------------
diff --git a/extensions/base_problems/DiffuseDomainFsi.cc b/extensions/base_problems/DiffuseDomainFsi.cc
index 1fe67f263b12e1bdce12be4dc016a8c045ae0cec..873af228edf0ec9585589a55f7bbf9c73b4bf7a2 100644
--- a/extensions/base_problems/DiffuseDomainFsi.cc
+++ b/extensions/base_problems/DiffuseDomainFsi.cc
@@ -15,7 +15,7 @@
  * 
  ******************************************************************************/
 #include "DiffuseDomainFsi.h"
-
+#include "Expressions.h"
 
 namespace AMDiS { namespace base_problems {
 
@@ -87,7 +87,7 @@ void DiffuseDomainFsi::initData()
   velocity = new DOFVector<WorldVector<double> >(getFeSpace(0), "velocity");
   displacement = new DOFVector<WorldVector<double> >(getFeSpace(dow+1), "displacement");
   
-  dbc_factor = beta/pow(epsilon, alpha);
+  dbc_factor = beta/std::pow(epsilon, alpha);
   MSG_DBG("dbc_factor = %f\n", dbc_factor);
   pressure_factor = -(lambda+(2.0/3.0)*mu);
   MSG("pressure_factor = %f\n", pressure_factor);
@@ -121,7 +121,7 @@ void DiffuseDomainFsi::initTimestep(AdaptInfo *adaptInfo)
   super::initTimestep(adaptInfo);
   transformDOF(1.0, phase, phaseInv, new Subtract<double>);
   transformDOF(phaseInv, 1.e-7, phaseInvDisturbed, new Max<double>);
-  VtkWriter::writeFile(phaseInv, "phaseInv.vtu");
+  io::writeFile(phaseInv, "phaseInv.vtu");
 }
 
 
@@ -219,9 +219,7 @@ void DiffuseDomainFsi::fillOperators()
 	/// < (1-phase) * u^old*grad(eta_i) , psi >
 	for(size_t j = 0; j < dow; ++j) {
 	  Operator *opUGradE2 = new Operator(prob->getFeSpace(dow+1+i),prob->getFeSpace(dow+1+i));
-	  opUGradE2->addTerm(new Vec2ProductPartial_FOT(
-		phaseInvDisturbed,
-		prob->getSolution()->getDOFVector(j), j), GRD_PHI);
+	  addFOT(opUGradE2, valueOf(phaseInvDisturbed) * valueOf(prob->getSolution()->getDOFVector(j)), j, GRD_PHI);
 	  prob->addMatrixOperator(*opUGradE2, dow+1+i, dow+1+i);
 	}
     
@@ -234,12 +232,12 @@ void DiffuseDomainFsi::fillOperators()
   for (size_t i = 0; i < dow; ++i) {
     /// < phase*d_i(u_i) , psi >
     Operator *opDivU = new Operator(prob->getFeSpace(dow),prob->getFeSpace(i));
-    opDivU->addTerm(new VecAndPartialDerivative_FOT(phase, i), GRD_PHI);
+    addFOT(opDivU, valueOf(phase), i, GRD_PHI);
     prob->addMatrixOperator(*opDivU, dow, i);
 
     /// < (1-phase)*d_i(eta_i) , psi >
     Operator *opDivEta = new Operator(prob->getFeSpace(dow),prob->getFeSpace(dow+1+i));
-    opDivEta->addTerm(new VecAndPartialDerivative_FOT(phaseInv, i, pressure_factor), GRD_PHI);
+    addFOT(opDivU, pressure_factor * valueOf(phaseInv), i, GRD_PHI);
     prob->addMatrixOperator(*opDivEta, dow, dow+1+i);
   }
 
diff --git a/extensions/base_problems/NavierStokes_TH_MultiPhase.h b/extensions/base_problems/NavierStokes_TH_MultiPhase.h
index b7e421e125bbdc65f3a61c3b85ebad988a9ec4b1..ae267b49195bd439f7e074c6232b2faa623fb90b 100644
--- a/extensions/base_problems/NavierStokes_TH_MultiPhase.h
+++ b/extensions/base_problems/NavierStokes_TH_MultiPhase.h
@@ -51,11 +51,13 @@ namespace detail {
     * initTimeInterface of super
     **/
     void initData() override;
+    void transferInitialSolution(AdaptInfo *adaptInfo) override;
 
     /** initTimestep of super and
     * initialization of densityPhase and viscosityPhase
     **/
     void initTimestep(AdaptInfo *adaptInfo) override;
+    void closeTimestep(AdaptInfo *adaptInfo) override;
 
     /** pointer to the multiPhase DOFVector, that
     * indicates the different phases. Will be initialized
@@ -94,6 +96,23 @@ namespace detail {
       else
 	return density2;
     }
+    
+    void rejectTimestep()
+    {
+      *stepSolution = *oldSolution;
+    }
+    
+    void acceptTimestep()
+    { FUNCNAME("NavierStokes_TH_MultiPhase::acceptTimestep");
+      MSG("Timestep accepted.\n");
+      *oldSolution = *self::prob->getSolution();
+      *stepSolution = *self::prob->getSolution();
+    }
+    
+    SystemVector* getStepSolution()
+    {
+      return stepSolution;
+    }
 
   protected: // variables
 
@@ -119,6 +138,9 @@ namespace detail {
     
     /// phase inticator
     DOFVector<double> *multiPhase;
+    
+    SystemVector* oldSolution;
+    SystemVector* stepSolution;
 
   };
 
@@ -126,46 +148,30 @@ namespace detail {
   /** linear interpolation between two values (like density, viscosity)
   *  using a phase-field variable in [-1,1]
   **/
-  class LinearInterpolation1 : public AbstractFunction<double, double>
-  {
-  public:
+  struct LinearInterpolation1 : public FunctorBase
+  {  
+    typedef double result_type;
+    int getDegree(int d0) const { return 1; }
 
-    LinearInterpolation1(double c1, double c2) :
-      AbstractFunction<double, double>(1)
-      { a = (c1-c2)/2.0; b = (c1+c2)/2.0; cmin=std::min(c1,c2); cmax=std::max(c1,c2);}
+    LinearInterpolation1(double c1, double c2) 
+    {
+      a = (c1-c2)/2.0; 
+      b = (c1+c2)/2.0; 
+      cmin = std::min(c1,c2); 
+      cmax = std::max(c1,c2);
+    }
       
-    double operator()(const double &phase) const { 
+    double operator()(const double &phase) const 
+    { 
       double result = b+a*phase;
-      if (result<cmin) result = cmin; 
-      if (result>cmax) result = cmax;
+      if (result < cmin) result = cmin; 
+      if (result > cmax) result = cmax;
       return result;
     }
 
   private:
     double a,b,cmin,cmax;
   };
-
-  /** linear interpolation between two values (like density, viscosity)
-  *  using a phase-field variable in [0,1]
-  **/
-  class LinearInterpolation0 : public AbstractFunction<double, double>
-  {
-  public:
-
-    LinearInterpolation0(double val1_, double val2_) :
-      AbstractFunction<double, double>(1),
-      val1(val1_), val2(val2_) {}
-
-    double operator()(const double &phase) const {    
-      return phase*val1 + (1.0-phase)*val2;
-    }
-
-  private:
-    
-    double val1;
-    double val2;
-  };
-
 }
 
 typedef base_problems::detail::NavierStokes_TH_MultiPhase<AMDiS::ProblemStat> NavierStokes_TH_MultiPhase;
diff --git a/extensions/base_problems/NavierStokes_TH_MultiPhase.hh b/extensions/base_problems/NavierStokes_TH_MultiPhase.hh
index 47c75066ceaa07ad29564ee9f592af6209347339..9beca9369970e4790ed30b784e5a60fae163b934 100644
--- a/extensions/base_problems/NavierStokes_TH_MultiPhase.hh
+++ b/extensions/base_problems/NavierStokes_TH_MultiPhase.hh
@@ -14,25 +14,26 @@
  * See also license.opensource.txt in the distribution.
  * 
  ******************************************************************************/
-// #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
-// #include "parallel/MeshDistributor.h"
-// #endif
+
+#include "Expressions.h"
 
 namespace AMDiS { namespace base_problems {
 
 namespace detail {
 
 template<typename P>
-NavierStokes_TH_MultiPhase<P>::NavierStokes_TH_MultiPhase(const std::string &name_, bool createProblem) :
-  super(name_, createProblem),
-  viscosity1(1.0),
-  viscosity2(1.0),
-  density1(1.0),
-  density2(1.0),
-  phaseFieldType(0),
-  densityPhase(NULL),
-  viscosityPhase(NULL),
-  multiPhase(NULL)
+NavierStokes_TH_MultiPhase<P>::NavierStokes_TH_MultiPhase(const std::string &name_, bool createProblem) 
+  : super(name_, createProblem),
+    viscosity1(1.0),
+    viscosity2(1.0),
+    density1(1.0),
+    density2(1.0),
+    phaseFieldType(0),
+    densityPhase(NULL),
+    viscosityPhase(NULL),
+    multiPhase(NULL),
+    stepSolution(NULL),
+    oldSolution(NULL)
 { FUNCNAME("NavierStokes_TH_MultiPhase::_constructor()");
 
   Initfile::get(self::name + "->viscosity1", viscosity1); // viscosity of fluid 1
@@ -61,6 +62,14 @@ NavierStokes_TH_MultiPhase<P>::~NavierStokes_TH_MultiPhase()
     delete viscosityPhase; 
     viscosityPhase = NULL; 
   }
+  if (oldSolution) {
+    delete oldSolution;
+    oldSolution = NULL;
+  }
+  if (stepSolution) {
+    delete stepSolution;
+    stepSolution = NULL;
+  }
 }
 
 
@@ -70,6 +79,9 @@ void NavierStokes_TH_MultiPhase<P>::initData()
   densityPhase = new DOFVector<double>(self::prob->getFeSpace(0), "densityPhase");
   viscosityPhase = new DOFVector<double>(self::prob->getFeSpace(0), "viscosityPhase");
   
+  oldSolution = new SystemVector(*self::prob->getSolution());
+  stepSolution = new SystemVector(*self::prob->getSolution());
+  
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
     Parallel::MeshDistributor::globalMeshDistributor->addInterchangeVector(densityPhase);
     Parallel::MeshDistributor::globalMeshDistributor->addInterchangeVector(viscosityPhase);
@@ -82,37 +94,48 @@ void NavierStokes_TH_MultiPhase<P>::initData()
 }
 
 
+template<typename P>
+void NavierStokes_TH_MultiPhase<P>::transferInitialSolution(AdaptInfo *adaptInfo)
+{
+  super::transferInitialSolution(adaptInfo);
+  *oldSolution = *self::prob->getSolution();
+  *stepSolution = *self::prob->getSolution();
+}
+
+
 template<typename P>
 void NavierStokes_TH_MultiPhase<P>::initTimestep(AdaptInfo *adaptInfo)
 {
   super::initTimestep(adaptInfo);
   if (multiPhase) {
     if (phaseFieldType == 0) {
-      LinearInterpolation0 dLI(density1, density2);
-      LinearInterpolation0 vLI(viscosity1, viscosity2);
-      transformDOF(multiPhase, densityPhase, &dLI);
-      transformDOF(multiPhase, viscosityPhase, &vLI);
+      *viscosityPhase << viscosity2 + valueOf(multiPhase)*(viscosity1 - viscosity2);
+      *densityPhase << density2 + valueOf(multiPhase)*(density1 - density2);
     } else {
-      LinearInterpolation1 dLI(density1, density2);
-      LinearInterpolation1 vLI(viscosity1, viscosity2);
-      transformDOF(multiPhase, densityPhase, &dLI);
-      transformDOF(multiPhase, viscosityPhase, &vLI);
+      *viscosityPhase << function_(LinearInterpolation1(viscosity1, viscosity2), valueOf(multiPhase));
+      *densityPhase << function_(LinearInterpolation1(density1, density2), valueOf(multiPhase));
     }
   }
 }
 
 
+template<typename P>
+void NavierStokes_TH_MultiPhase<P>::closeTimestep(AdaptInfo *adaptInfo)
+{
+  super::closeTimestep(adaptInfo);
+  acceptTimestep();
+}
+
+
 template<typename P>
 void NavierStokes_TH_MultiPhase<P>::fillOperators()
 {
   using namespace extensions;
   
-  int degree_u = self::prob->getFeSpace(0)->getBasisFcts()->getDegree();
-//   int degree_p = self::prob->getFeSpace(self::dow)->getBasisFcts()->getDegree();
-  
-  WorldVector<DOFVector<double>* > vel;
+  WorldVector<DOFVector<double>* > vel, vel_old;
   for (unsigned i = 0; i < self::dow; i++) {
-    vel[i]= self::prob->getSolution()->getDOFVector(i);
+    vel[i]= stepSolution->getDOFVector(i);
+    vel_old[i]= oldSolution->getDOFVector(i);
   }
   
   // fill operators for prob
@@ -120,26 +143,26 @@ void NavierStokes_TH_MultiPhase<P>::fillOperators()
     /// < (1/tau)*rho*u'_i , psi >
     Operator *opTime = new Operator(self::getFeSpace(i), self::getFeSpace(i));
     if (density1 == density2 || !densityPhase)
-      opTime->addTerm(new Simple_ZOT(density1));  
+      addZOT(opTime, density1);
     else
-      opTime->addTerm(new VecAtQP_ZOT(densityPhase));
+      addZOT(opTime, valueOf(densityPhase));
     self::prob->addMatrixOperator(*opTime, i, i, self::getInvTau(), self::getInvTau());
     
     /// < (1/tau)*rho*u_i^old , psi >
     Operator *opTimeOld = new Operator(self::getFeSpace(i), self::getFeSpace(i));
     if (density1 == density2 || !densityPhase)
-      opTimeOld->addTerm(new VecAtQP_ZOT(self::prob->getSolution()->getDOFVector(i), new AMDiS::Factor<double>(density1, degree_u)));  
+      addZOT(opTimeOld, density1 * valueOf(vel_old[i]));
     else
-      opTimeOld->addTerm(new Vec2AtQP_ZOT(densityPhase, self::prob->getSolution()->getDOFVector(i)));
+      addZOT(opTimeOld, valueOf(densityPhase) * valueOf(vel_old[i]));
     self::prob->addVectorOperator(*opTimeOld, i, self::getInvTau(), self::getInvTau());
  
     /// < u^old*grad(u_i^old) , psi >
     Operator *opUGradU0 = new Operator(self::getFeSpace(i),self::getFeSpace(i));
     if (density1 == density2 || !densityPhase)
-        opUGradU0->addTerm(new WorldVec_FOT(vel, density1), GRD_PHI);
+      addFOT(opUGradU0, density1 * valueOf(vel), GRD_PHI);
     else
-        opUGradU0->addTerm(new WorldVecPhase_FOT(densityPhase, vel, 1.0), GRD_PHI);
-    opUGradU0->setUhOld(self::prob->getSolution()->getDOFVector(i));
+      addFOT(opUGradU0, valueOf(densityPhase) * valueOf(vel), GRD_PHI);
+    opUGradU0->setUhOld(vel[i]);
     self::prob->addVectorOperator(*opUGradU0, i);
 
 
@@ -147,9 +170,9 @@ void NavierStokes_TH_MultiPhase<P>::fillOperators()
     for (size_t j = 0; j < self::dow; ++j) {
       Operator *opUGradU1 = new Operator(self::getFeSpace(i),self::getFeSpace(j));
       if (density1 == density2 || !densityPhase)
-	opUGradU1->addTerm(new PartialDerivative_ZOT(self::prob->getSolution()->getDOFVector(i), j, density1));
+	addZOT(opUGradU1, density1 * derivativeOf(vel[i], j));
       else
-	opUGradU1->addTerm(new VecAndPartialDerivative_ZOT(densityPhase, self::prob->getSolution()->getDOFVector(i), j));
+	addZOT(opUGradU1, valueOf(densityPhase) * derivativeOf(vel[i], j));
       self::prob->addMatrixOperator(*opUGradU1, i, j);
     }
       
@@ -157,9 +180,9 @@ void NavierStokes_TH_MultiPhase<P>::fillOperators()
     for (size_t j = 0; j < self::dow; ++j) {
       Operator *opUGradU2 = new Operator(self::getFeSpace(i),self::getFeSpace(i));
       if (density1 == density2 || !densityPhase)
-	opUGradU2->addTerm(new VecAndPartialDerivative_FOT(self::prob->getSolution()->getDOFVector(j), j, density1), GRD_PHI);
+	addFOT(opUGradU2, density1 * valueOf(vel[j]), j, GRD_PHI);
       else
-	opUGradU2->addTerm(new Vec2AndPartialDerivative_FOT(densityPhase, self::prob->getSolution()->getDOFVector(j), j), GRD_PHI);
+	addFOT(opUGradU2, valueOf(densityPhase) * valueOf(vel[j]), j, GRD_PHI);
       self::prob->addMatrixOperator(*opUGradU2, i, i);
     }
 
@@ -168,16 +191,16 @@ void NavierStokes_TH_MultiPhase<P>::fillOperators()
   
     /// < p , d_i(psi) >
     Operator *opGradP = new Operator(self::getFeSpace(i),self::getFeSpace(self::dow));
-    opGradP->addTerm(new PartialDerivative_FOT(i, -1.0), GRD_PSI);
+    addFOT(opGradP, -1.0, i, GRD_PSI);
     self::prob->addMatrixOperator(*opGradP, i, self::dow);
     
     /// external force, e.g. gravitational force
     if (std::abs(self::force[i]) > DBL_TOL) {
       Operator *opForce = new Operator(self::getFeSpace(i), self::getFeSpace(i));
       if (density1 == density2 || !densityPhase)
-	opForce->addTerm(new Simple_ZOT(density1*self::force[i]));
+	addZOT(opForce, density1*self::force[i] );
       else
-	opForce->addTerm(new VecAtQP_ZOT(densityPhase, NULL, self::force[i]));
+	addZOT(opForce, valueOf(densityPhase)*self::force[i] );
       self::prob->addVectorOperator(*opForce, i);
     }
   }
@@ -186,12 +209,11 @@ void NavierStokes_TH_MultiPhase<P>::fillOperators()
   for (size_t i = 0; i < self::dow; ++i) {
     /// < d_i(u'_i) , psi >
     Operator *opDivU = new Operator(self::getFeSpace(self::dow),self::getFeSpace(i));
-    opDivU->addTerm(new PartialDerivative_FOT(i), GRD_PHI);
+    addFOT(opDivU, 1.0, i, GRD_PHI);
     self::prob->addMatrixOperator(*opDivU, self::dow, i);
   }
   
   Operator *opZero = new Operator(self::getFeSpace(self::dow),self::getFeSpace(self::dow));
-  opZero->addTerm(new Simple_ZOT(0.0));
   self::prob->addMatrixOperator(*opZero, self::dow, self::dow);
 }
 
@@ -199,23 +221,21 @@ void NavierStokes_TH_MultiPhase<P>::fillOperators()
 template<typename P>
 void NavierStokes_TH_MultiPhase<P>::addLaplaceTerm(int i)
 {
-  using namespace extensions;
   /// < alpha*[grad(u)+grad(u)^t] , grad(psi) >
   if (viscosity1 != viscosity2 && viscosityPhase) {
     for (unsigned j = 0; j < self::dow; ++j) {
       Operator *opLaplaceUi1 = new Operator(self::getFeSpace(i), self::getFeSpace(j));
-      opLaplaceUi1->addTerm(new VecAtQP_IJ_SOT(viscosityPhase, NULL, j, i));
+      addSOT(opLaplaceUi1, valueOf(viscosityPhase), j, i);
       self::prob->addMatrixOperator(*opLaplaceUi1, i, j);
     }
   }
   
   /// < alpha*grad(u'_i) , grad(psi) >
   Operator *opLaplaceUi = new Operator(self::getFeSpace(i), self::getFeSpace(i));
-  if (viscosity1 == viscosity2 || !viscosityPhase) {
-    opLaplaceUi->addTerm(new Simple_SOT(viscosity1));
-  } else {
-    opLaplaceUi->addTerm(new VecAtQP_SOT(viscosityPhase));
-  }
+  if (viscosity1 == viscosity2 || !viscosityPhase)
+    addSOT(opLaplaceUi, viscosity1);
+  else
+    addSOT(opLaplaceUi, valueOf(viscosityPhase));
   self::prob->addMatrixOperator(*opLaplaceUi, i, i);
 }
 
diff --git a/extensions/base_problems/NavierStokes_TaylorHood.h b/extensions/base_problems/NavierStokes_TaylorHood.h
index be0c948336069ad5057bd06cc23133f84f4f13e9..0e0ea152b012b78f3aa5c6aef42f40da9fe467c9 100644
--- a/extensions/base_problems/NavierStokes_TaylorHood.h
+++ b/extensions/base_problems/NavierStokes_TaylorHood.h
@@ -21,7 +21,7 @@
 #include "AMDiS.h"
 #include "BaseProblem.h"
 #include "ExtendedProblemStat.h"
-#include "GenericOperatorTerm.h"
+#include "Expressions.h"
 
 namespace AMDiS { namespace base_problems {
 
diff --git a/extensions/base_problems/PhaseFieldCrystal.h b/extensions/base_problems/PhaseFieldCrystal.h
index a0c2c8049dc8042da6c8ffc414fa1116481447e4..e68333957d07fcec72d26bab7ddd487cec393b94 100644
--- a/extensions/base_problems/PhaseFieldCrystal.h
+++ b/extensions/base_problems/PhaseFieldCrystal.h
@@ -28,22 +28,62 @@ namespace detail {
   public:
   
     PhaseFieldCrystal(const std::string &name_, bool createProblem = true);
-    ~PhaseFieldCrystal() {}
+    
+    ~PhaseFieldCrystal()
+    {
+      if (oldSolution) {
+	delete oldSolution;
+	oldSolution = NULL;
+      }
+      if (stepSolution) {
+	delete stepSolution;
+	stepSolution = NULL;
+      }
+    }
 
     DOFVector<double>* getDensity() { return self::prob->getSolution(1); }
     double calcEnergy();
 
+    void initData() override ;
+    void transferInitialSolution(AdaptInfo *adaptInfo) override;
+    
+    void closeTimestep(AdaptInfo *adaptInfo) override;
+    
     void fillOperators() override ;
     void fillBoundaryConditions() override {};
-
+    
+    void rejectTimestep()
+    {
+      *stepSolution = *oldSolution;
+    }
+    
+    void acceptTimestep()
+    { FUNCNAME("PhaseFieldCrystal::acceptTimestep");
+      MSG("Timestep accepted.\n");
+      *oldSolution = *self::prob->getSolution();
+      *stepSolution = *self::prob->getSolution();
+    }
+    
+    SystemVector* getStepSolution()
+    {
+      return stepSolution;
+    }
+    
+    SystemVector* getOldSolution()
+    {
+      return oldSolution;
+    }
+    
   protected:
 
-    bool useMobility;
+    int mobility_type;
 
     double r;
-    double rho0;
     double density;
     double M0;
+    
+    SystemVector* oldSolution;
+    SystemVector* stepSolution;
   };
 
 } // end namespace detail
diff --git a/extensions/base_problems/PhaseFieldCrystal.hh b/extensions/base_problems/PhaseFieldCrystal.hh
index acec2f6688dccb060274bb81d024d753dc65f10e..ebe4b7258779344f5a8055f8d6f0476f2f310542 100644
--- a/extensions/base_problems/PhaseFieldCrystal.hh
+++ b/extensions/base_problems/PhaseFieldCrystal.hh
@@ -1,24 +1,43 @@
 
-#include "GenericOperatorTerm.h"
+#include "Expressions.h"
 
 namespace AMDiS { namespace base_problems {
   
   namespace detail 
   {
     template<typename P>
-    PhaseFieldCrystal<P>::PhaseFieldCrystal(const std::string &name_, bool createProblem) :
-      super(name_, createProblem),
-      useMobility(false),
-      r(-0.4),		// temperature deviation
-      rho0(1.0),		// liquid density
-      density(-0.3),	// mean density
-      M0(1.0)		// mobility
+    PhaseFieldCrystal<P>::PhaseFieldCrystal(const std::string &name_, bool createProblem) 
+      : super(name_, createProblem),
+	mobility_type(0),
+	r(-0.4),		// temperature deviation
+	density(-0.3),		// mean density
+	M0(1.0),		// mobility
+	oldSolution(NULL),
+	stepSolution(NULL)
     {  
       Parameters::get(name_ + "->r",r);
-      Parameters::get(name_ + "->rho0", rho0);
       Parameters::get(name_ + "->density", density);
       Parameters::get(name_ + "->M0", M0);
-      Parameters::get(name_ + "->use mobility", useMobility);
+      Parameters::get(name_ + "->mobility type", mobility_type);
+    }
+    
+    
+    template<typename P>
+    void PhaseFieldCrystal<P>::initData()
+    {
+      super::initData();
+    
+      oldSolution = new SystemVector(*self::prob->getSolution());
+      stepSolution = new SystemVector(*self::prob->getSolution());
+    }
+
+
+    template<typename P>
+    void PhaseFieldCrystal<P>::transferInitialSolution(AdaptInfo *adaptInfo)
+    {
+      super::transferInitialSolution(adaptInfo);
+      *oldSolution = *self::prob->getSolution();
+      *stepSolution = *self::prob->getSolution();
     }
 
 
@@ -29,7 +48,8 @@ namespace AMDiS { namespace base_problems {
       const FiniteElemSpace* feSpace1 = self::prob->getFeSpace(1);
       const FiniteElemSpace* feSpace2 = self::prob->getFeSpace(2);
       
-      DOFVector<double>* rho = self::prob->getSolution(1);
+      DOFVector<double>* rho = stepSolution->getDOFVector(1);
+      DOFVector<double>* rho_old = oldSolution->getDOFVector(1);
       
       // dt(rho) = laplace(mu) - u*grad(rho)
       // -----------------------------------
@@ -38,21 +58,24 @@ namespace AMDiS { namespace base_problems {
       self::prob->addMatrixOperator(opM11, 1, 1);
       
       Operator *opLM = new Operator(feSpace1, feSpace0);
-      if (useMobility)
-	addSOT(opLM, max(abs_(valueOf(rho) + 1.5)*M0, 1.e-5));
-      else
+      if (mobility_type == 0)
 	addSOT(opLM, M0);
+      else if (mobility_type == 1)
+	addSOT(opLM, max(abs_(valueOf(rho) + 1.5)*M0, 1.e-5));
+      else if (mobility_type == 2)
+	addSOT(opLM, max(valueOf(rho)*M0, 1.e-5));
+      
       self::prob->addMatrixOperator(opLM, 1, 0, self::getTau(), self::getTau()); // -laplace(mu)
       
       // . . . vectorOperators . . . . . . . . . . . . . . .
       Operator *opMold = new Operator(feSpace1);
-      addZOT(opMold, valueOf(rho));
+      addZOT(opMold, valueOf(rho_old));
       self::prob->addVectorOperator(opMold, 1);
       
       // mu-2*nu-laplace(nu)-(1+r)*rho = (rho_old^3) + ExtPot - eps^2/(rho_old+0.9)
       // ----------------------------------------------------------------------
       Operator *op01 = new Operator(feSpace0, feSpace1);
-      addZOT(op01, -(1.0 + ref_(r)) - 3.0 * pow<2>(valueOf(rho)) );
+      addZOT(op01, -(1.0 + ref_(&r)) - 3.0 * pow<2>(valueOf(rho)) );
       addSOT(op01, 2.0);
       self::prob->addMatrixOperator(op01, 0, 1);
       
@@ -90,6 +113,14 @@ namespace AMDiS { namespace base_problems {
       return integrate( 0.5*valueOf(rho)*valueOf(mu) - 0.25*pow<4>(valueOf(rho)) );
     }
 
+
+    template<typename P>
+    void PhaseFieldCrystal<P>::closeTimestep(AdaptInfo *adaptInfo)
+    {
+      super::closeTimestep(adaptInfo);
+      acceptTimestep();
+    }
+
   } // end namespace detail
 
 } }
diff --git a/extensions/base_problems/PhaseFieldCrystal_Phase.h b/extensions/base_problems/PhaseFieldCrystal_Phase.h
index 5e1b0510009e53b78fcab8181bc764fb50d3d809..fffb75accb9043249b0ddc8f2e07c5f6399eea6b 100644
--- a/extensions/base_problems/PhaseFieldCrystal_Phase.h
+++ b/extensions/base_problems/PhaseFieldCrystal_Phase.h
@@ -19,7 +19,7 @@
 #define PHASE_FIELD_CRYSTAL_PHASE_H
 
 #include "PhaseFieldCrystal.h"
-#include "GenericOperatorTerm.h"
+#include "Expressions.h"
 
 namespace AMDiS { namespace base_problems {
 
@@ -33,12 +33,13 @@ namespace AMDiS { namespace base_problems {
     {
     public: // typedefs
 
-      typedef PhaseFieldCrystal_Phase<ProblemStatType> self;
-      typedef PhaseFieldCrystal<ProblemStatType> super;
+      typedef PhaseFieldCrystal_Phase<ProblemStatType>  self;
+      typedef PhaseFieldCrystal<ProblemStatType>        super;
 
     public: // methods
 
       PhaseFieldCrystal_Phase(const std::string &name_);
+      
       ~PhaseFieldCrystal_Phase();
 
       DOFVector<double> *getPhase()
diff --git a/extensions/base_problems/PhaseFieldCrystal_Phase.hh b/extensions/base_problems/PhaseFieldCrystal_Phase.hh
index b65cc9a29abfde42d9761f0d08c74837f44b7695..183fdbf648528aadace2245fbb3c34f260c8a40c 100644
--- a/extensions/base_problems/PhaseFieldCrystal_Phase.hh
+++ b/extensions/base_problems/PhaseFieldCrystal_Phase.hh
@@ -1,91 +1,100 @@
 namespace AMDiS { namespace base_problems {
   
-  namespace detail
-  {
+namespace detail
+{
 
-template<typename P>
-PhaseFieldCrystal_Phase<P>::PhaseFieldCrystal_Phase(const std::string &name_) :
-  super(name_),
-  phase(NULL),
-  phaseDisturbed(NULL)
-{}
+  template<typename P>
+  PhaseFieldCrystal_Phase<P>::PhaseFieldCrystal_Phase(const std::string &name_) 
+    : super(name_),
+      phase(NULL),
+      phaseDisturbed(NULL)
+  { }
 
 
-template<typename P>
-PhaseFieldCrystal_Phase<P>::~PhaseFieldCrystal_Phase()
-{
-  delete phase;
-  delete phaseDisturbed;
-}
-
-
-template<typename P>
-void PhaseFieldCrystal_Phase<P>::fillOperators()
-{ 
-  const FiniteElemSpace* feSpace0 = self::prob->getFeSpace(0);
-  const FiniteElemSpace* feSpace1 = self::prob->getFeSpace(1);
-  const FiniteElemSpace* feSpace2 = self::prob->getFeSpace(2);
-
-  DOFVector<double>* rho = self::prob->getSolution(1);
-
-  // dt(rho) = laplace(mu) - u*grad(rho)
-  // -----------------------------------
-  Operator *opM11 = new Operator(feSpace1, feSpace1);
-  addZOT(opM11, valueOf(phaseDisturbed));
-  self::prob->addMatrixOperator(opM11, 1, 1);
-
-  Operator *opLM = new Operator(feSpace1, feSpace0);
-  if (super::useMobility)
-    addSOT(opLM, valueOf(phaseDisturbed) * max(abs_(valueOf(rho) + 1.5)*super::M0, 1.e-5));
-  else
-    addSOT(opLM, valueOf(phaseDisturbed) * super::M0);
-  self::prob->addMatrixOperator(opLM, 1, 0, self::getTau(), self::getTau()); // -laplace(mu)
-
-  // . . . vectorOperators . . . . . . . . . . . . . . .
-  Operator *opMold = new Operator(feSpace1);
-  addZOT(opMold, valueOf(rho) * valueOf(phaseDisturbed));
-  self::prob->addVectorOperator(opMold, 1);
-
-  // mu-2*nu-laplace(nu)-(1+r)*rho = (rho_old^3) + ExtPot - eps^2/(rho_old+0.9)
-  // ----------------------------------------------------------------------
-  Operator *op01 = new Operator(feSpace0, feSpace1);
-  addZOT(op01, valueOf(phaseDisturbed) * ( -(1.0 + ref_(super::r)) - 3.0 * pow<2>(valueOf(rho)) ) );
-  addSOT(op01, 2.0 * valueOf(phaseDisturbed));
-  self::prob->addMatrixOperator(op01, 0, 1);
-
-  Operator *op00 = new Operator(feSpace0, feSpace0);
-  addZOT(op00, valueOf(phaseDisturbed));
-  self::prob->addMatrixOperator(op00, 0, 0);
-
-  Operator *op02 = new Operator(feSpace0, feSpace2);
-  addSOT(op02, valueOf(phaseDisturbed));
-  self::prob->addMatrixOperator(op02, 0, 2);
-
-  // . . . vectorOperators . . . . . . . . . . . . . . .
-  Operator *op0 = new Operator(feSpace0);
-  addZOT(op0, -2.0 * valueOf(phaseDisturbed) * pow<3>(valueOf(rho)) );
-  self::prob->addVectorOperator(op0, 0);
-
-  // 0 = nu-laplace(rho)
-  // -------------------
-  Operator *op21 = new Operator(feSpace2, feSpace1);
-  addSOT(op21, valueOf(phaseDisturbed));
-  self::prob->addMatrixOperator(op21, 2, 1); // -laplace(rho)
-
-  Operator *op22 = new Operator(feSpace2, feSpace2);
-  addZOT(op22, valueOf(phaseDisturbed));
-  self::prob->addMatrixOperator(op22, 2, 2); // nu
-}
-
-
-template<typename P>
-double PhaseFieldCrystal_Phase<P>::calcEnergy()
-{
-  DOFVector<double>* rho = self::prob->getSolution(1);
-  DOFVector<double>* mu = self::prob->getSolution(0);
-  
-  return integrate( valueOf(phase) * ( 0.5*valueOf(rho)*valueOf(mu) - 0.25*pow<4>(valueOf(rho)) ) );
-}
+  template<typename P>
+  PhaseFieldCrystal_Phase<P>::~PhaseFieldCrystal_Phase()
+  {
+    if (phase) {
+      delete phase;
+      phase = NULL;
+    }
+    if (phaseDisturbed) {
+      delete phaseDisturbed;
+      phaseDisturbed = NULL;
+    }
+  }
+
+
+  template<typename P>
+  void PhaseFieldCrystal_Phase<P>::fillOperators()
+  { 
+    const FiniteElemSpace* feSpace0 = self::prob->getFeSpace(0);
+    const FiniteElemSpace* feSpace1 = self::prob->getFeSpace(1);
+    const FiniteElemSpace* feSpace2 = self::prob->getFeSpace(2);
+
+    DOFVector<double>* rho = super::getStepSolution()->getDOFVector(1);
+    DOFVector<double>* rho_old = super::getOldSolution()->getDOFVector(1);
+
+    // dt(rho) = laplace(mu) - u*grad(rho)
+    // -----------------------------------
+    Operator *opM11 = new Operator(feSpace1, feSpace1);
+    addZOT(opM11, valueOf(phaseDisturbed));
+    self::prob->addMatrixOperator(opM11, 1, 1);
+
+    Operator *opLM = new Operator(feSpace1, feSpace0);
+    if (super::mobility_type == 1)
+      addSOT(opLM, valueOf(phaseDisturbed) * max(abs_(valueOf(rho) + 1.5)*super::M0, 1.e-5));
+    else if (super::mobility_type == 2)
+      addSOT(opLM, valueOf(phaseDisturbed) * max(valueOf(rho)*super::M0, 1.e-5));
+    else
+      addSOT(opLM, valueOf(phaseDisturbed) * super::M0);
+    self::prob->addMatrixOperator(opLM, 1, 0, self::getTau(), self::getTau()); // -laplace(mu)
+
+    // . . . vectorOperators . . . . . . . . . . . . . . .
+    Operator *opMold = new Operator(feSpace1);
+    addZOT(opMold, valueOf(rho_old) * valueOf(phaseDisturbed));
+    self::prob->addVectorOperator(opMold, 1);
+
+    // mu-2*nu-laplace(nu)-(1+r)*rho = (rho_old^3) + ExtPot - eps^2/(rho_old+0.9)
+    // ----------------------------------------------------------------------
+    Operator *op01 = new Operator(feSpace0, feSpace1);
+    addZOT(op01, valueOf(phaseDisturbed) * ( -(1.0 + ref_(super::r)) - 3.0 * pow<2>(valueOf(rho)) ) );
+    addSOT(op01, 2.0 * valueOf(phaseDisturbed));
+    self::prob->addMatrixOperator(op01, 0, 1);
+
+    Operator *op00 = new Operator(feSpace0, feSpace0);
+    addZOT(op00, valueOf(phaseDisturbed));
+    self::prob->addMatrixOperator(op00, 0, 0);
+
+    Operator *op02 = new Operator(feSpace0, feSpace2);
+    addSOT(op02, valueOf(phaseDisturbed));
+    self::prob->addMatrixOperator(op02, 0, 2);
+
+    // . . . vectorOperators . . . . . . . . . . . . . . .
+    Operator *op0 = new Operator(feSpace0);
+    addZOT(op0, -2.0 * valueOf(phaseDisturbed) * pow<3>(valueOf(rho)) );
+    self::prob->addVectorOperator(op0, 0);
+
+    // 0 = nu-laplace(rho)
+    // -------------------
+    Operator *op21 = new Operator(feSpace2, feSpace1);
+    addSOT(op21, valueOf(phaseDisturbed));
+    self::prob->addMatrixOperator(op21, 2, 1); // -laplace(rho)
+
+    Operator *op22 = new Operator(feSpace2, feSpace2);
+    addZOT(op22, valueOf(phaseDisturbed));
+    self::prob->addMatrixOperator(op22, 2, 2); // nu
+  }
+
+
+  template<typename P>
+  double PhaseFieldCrystal_Phase<P>::calcEnergy()
+  {
+    DOFVector<double>* rho = self::prob->getSolution(1);
+    DOFVector<double>* mu = self::prob->getSolution(0);
+    
+    return integrate( valueOf(phase) * ( 0.5*valueOf(rho)*valueOf(mu) - 0.25*pow<4>(valueOf(rho)) ) );
+  }
 
 } // end namespace detail
 
diff --git a/extensions/base_problems/NavierStokesPhase_Chorin.cc b/extensions/base_problems/deprecated/NavierStokesPhase_Chorin.cc
similarity index 100%
rename from extensions/base_problems/NavierStokesPhase_Chorin.cc
rename to extensions/base_problems/deprecated/NavierStokesPhase_Chorin.cc
diff --git a/extensions/base_problems/NavierStokesPhase_Chorin.h b/extensions/base_problems/deprecated/NavierStokesPhase_Chorin.h
similarity index 100%
rename from extensions/base_problems/NavierStokesPhase_Chorin.h
rename to extensions/base_problems/deprecated/NavierStokesPhase_Chorin.h
diff --git a/extensions/base_problems/NavierStokes_Chorin.cc b/extensions/base_problems/deprecated/NavierStokes_Chorin.cc
similarity index 100%
rename from extensions/base_problems/NavierStokes_Chorin.cc
rename to extensions/base_problems/deprecated/NavierStokes_Chorin.cc
diff --git a/extensions/base_problems/NavierStokes_Chorin.h b/extensions/base_problems/deprecated/NavierStokes_Chorin.h
similarity index 100%
rename from extensions/base_problems/NavierStokes_Chorin.h
rename to extensions/base_problems/deprecated/NavierStokes_Chorin.h
diff --git a/extensions/base_problems/VacancyPhaseFieldCrystal.cc b/extensions/base_problems/deprecated/VacancyPhaseFieldCrystal.cc
similarity index 100%
rename from extensions/base_problems/VacancyPhaseFieldCrystal.cc
rename to extensions/base_problems/deprecated/VacancyPhaseFieldCrystal.cc
diff --git a/extensions/base_problems/VacancyPhaseFieldCrystal.h b/extensions/base_problems/deprecated/VacancyPhaseFieldCrystal.h
similarity index 100%
rename from extensions/base_problems/VacancyPhaseFieldCrystal.h
rename to extensions/base_problems/deprecated/VacancyPhaseFieldCrystal.h
diff --git a/extensions/preconditioner/BlockPreconditioner.h b/extensions/preconditioner/BlockPreconditioner.h
deleted file mode 100644
index d5f2161c7d6d2bd936ec1e55f452a53330e4fff7..0000000000000000000000000000000000000000
--- a/extensions/preconditioner/BlockPreconditioner.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/******************************************************************************
- *
- * Extension of AMDiS - Adaptive multidimensional simulations
- *
- * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
- * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
- *
- * Authors: Simon Praetorius et al.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- *
- * See also license.opensource.txt in the distribution.
- * 
- ******************************************************************************/
-#ifndef BLOCK_PRECONDITIONER_H
-#define BLOCK_PRECONDITIONER_H
-
-#include "solver/ITL_Preconditioner.h"
-#include "solver/SolverMatrix.h"
-
-namespace AMDiS {
-
-  struct BlockPreconditioner : BasePreconditioner
-  {
-    typedef SolverMatrix<Matrix<DOFMatrix*> > BlockMatrix;
-    
-    BlockPreconditioner() : A(NULL), fullMatrix(NULL) {}
-    
-    virtual ~BlockPreconditioner() {}
-    
-    /// extract iranges from BlockMatrix to be used to extract sub-vectors and sub-matrices.
-    void init(const BlockMatrix& A_, const MTLTypes::MTLMatrix& fullMatrix_) 
-    {
-      A = &A_;
-      fullMatrix = &fullMatrix_;
-      
-      BlockMapper mapper(A_);
-      rows.resize(mapper.getNumComponents());
-      int start = 0;
-      for (int i = 0; i < mapper.getNumComponents(); i++) {
-	mapper.setRow(i+1);
-	int finish = mapper.row(0);
-	rows[i].set(start, finish);
-	start = finish;
-      }
-    }
-  
-    virtual void solve(const MTLTypes::MTLVector& b, MTLTypes::MTLVector& x) const
-    { FUNCNAME("BlockPreconditioner::solve()");
-      TEST_EXIT(false)("Noch nicht implementiert!\n");
-    }
-    
-    virtual void adjoint_solve(const MTLTypes::MTLVector& x, MTLTypes::MTLVector& y) const
-    { FUNCNAME("BlockPreconditioner::adjoint_solve()");
-      TEST_EXIT(false)("Noch nicht implementiert!\n");
-    }
-    
-    mtl::irange& getRows(size_t i)
-    {
-      return rows[i];
-    }
-      
-    
-  protected:
-    
-    template<typename SolverType, typename RunnerType>
-    void createSubSolver(std::string param, SolverType*& solver, RunnerType*& runner, std::string solverType = "0")
-    {
-      // definition of standard-backends
-#if defined HAVE_PARALLEL_PETSC
-      string backend("p_petsc");
-#elif defined HAVE_PARALLEL_MTL
-      string backend("p_mtl");
-#elif defined HAVE_PETSC
-      string backend("petsc");
-#else
-      string backend("mtl");
-#endif
-    
-      // === read backend-name ===
-      string initFileStr = param + "->solver";    
-      Parameters::get(initFileStr + "->backend", backend);
-
-      // === read solver-name ===
-      Parameters::get(initFileStr, solverType);
-      
-      if (backend != "0" && backend != "no" && backend != "")
-	solverType = backend + "_" + solverType;
-    
-      LinearSolverCreator *solverCreator = 
-	dynamic_cast<LinearSolverCreator*>(CreatorMap<LinearSolver>::getCreator(solverType, initFileStr));
-      TEST_EXIT(solverCreator)
-	("No valid solver type found in parameter \"%s\"\n", initFileStr.c_str());
-      solverCreator->setName(initFileStr);
-      solver = dynamic_cast<SolverType*>(solverCreator->create());
-      assert(solver != NULL);
-      
-      runner = dynamic_cast<RunnerType*>(solver->getRunner());
-      assert(runner != NULL);
-    }
-    
-    
-    const SolverMatrix<Matrix<DOFMatrix*> >* A;
-    const MTLTypes::MTLMatrix* fullMatrix;
-    
-    std::vector<mtl::irange> rows;
-  };
-
-} // end namespace
-
-#endif // BLOCK_PRECONDITIONER_H
diff --git a/extensions/preconditioner/CahnHilliard_.cc b/extensions/preconditioner/CahnHilliard_.cc
deleted file mode 100644
index 03151202c3c94bc7543a99511a181c50d5769dbc..0000000000000000000000000000000000000000
--- a/extensions/preconditioner/CahnHilliard_.cc
+++ /dev/null
@@ -1,219 +0,0 @@
-/******************************************************************************
- *
- * Extension of AMDiS - Adaptive multidimensional simulations
- *
- * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
- * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
- *
- * Authors: Simon Praetorius et al.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- *
- * See also license.opensource.txt in the distribution.
- * 
- ******************************************************************************/
-#include "CahnHilliard_.h"
-// #include "Views.h"
-#include "SignedDistFunctors.h"
-#include "PhaseFieldConvert.h"
-
-#include "HL_SignedDistTraverse.h"
-#include "Recovery.h"
-
-namespace AMDiS { namespace base_problems {
-  
-CahnHilliard_::CahnHilliard_(const std::string &name_) :
-  super(name_),
-  useMobility(false),
-  useReinit(false),
-  doubleWell(0),
-  gamma(1.0),
-  eps(0.1),
-  minusEps(-0.1),
-  epsInv(10.0),
-  minusEpsInv(-10.0),
-  epsSqr(0.01),
-  minusEpsSqr(-0.01)
-{
-  // parameters for CH
-  Parameters::get(name_ + "->use mobility", useMobility); // mobility
-  Parameters::get(name_ + "->gamma", gamma); // mobility
-  Parameters::get(name_ + "->epsilon", eps); // interface width
-  
-  // type of double well: 0= [0,1], 1= [-1,1]
-  Parameters::get(name_ + "->double-well type", doubleWell); 
-  
-  Parameters::get(name + "->use reinit", useReinit);
-
-  // transformation of the parameters
-  minusEps = -eps;
-  epsInv = 1.0/eps;
-  minusEpsInv = -epsInv;
-  epsSqr = sqr(eps);
-  minusEpsSqr = -epsSqr;
-}
-
-
-void CahnHilliard_::solveInitialProblem(AdaptInfo *adaptInfo) 
-{
-  using namespace extensions;
-  Flag initFlag = initDataFromFile(adaptInfo);
-
-  if (!initFlag.isSet(DATA_ADOPTED)) {
-    int initialInterface = 0;
-    Initfile::get(name + "->initial interface", initialInterface);
-    double initialEps = eps;
-    Initfile::get(name + "->initial epsilon", initialEps);
-
-    if (initialInterface == 0) {
-      /// horizontale Linie
-      double a= 0.0, dir= -1.0;
-      Initfile::get(name + "->line->pos", a);
-      Initfile::get(name + "->line->direction", dir);
-      prob->getSolution()->getDOFVector(1)->interpol(new Plane(a, dir));
-    }
-    else if (initialInterface == 1) {
-      /// schraege Linie
-      double theta = m_pi/4.0;
-      prob->getSolution()->getDOFVector(1)->interpol(new PlaneRotation(0.0, theta, 1.0));
-      transformDOFInterpolation(prob->getSolution()->getDOFVector(1),new PlaneRotation(0.0, -theta, -1.0), new AMDiS::Min<double>);
-    }
-    else if (initialInterface == 2) {
-      /// Ellipse
-      double a= 1.0, b= 1.0;
-      Initfile::get(name + "->ellipse->a", a);
-      Initfile::get(name + "->ellipse->b", b);
-      prob->getSolution()->getDOFVector(1)->interpol(new Ellipse(a,b));
-    }
-    else if (initialInterface == 3) {
-      /// zwei horizontale Linien
-      double a= 0.75, b= 0.375;
-      Initfile::get(name + "->lines->pos1", a);
-      Initfile::get(name + "->lines->pos2", b);
-      prob->getSolution()->getDOFVector(1)->interpol(new Plane(a, -1.0));
-      transformDOFInterpolation(prob->getSolution()->getDOFVector(1),new Plane(b, 1.0), new AMDiS::Max<double>);
-    }
-    else if (initialInterface == 4) {
-      /// Kreis
-      double radius= 1.0;
-      Initfile::get(name + "->kreis->radius", radius);
-      prob->getSolution()->getDOFVector(1)->interpol(new Circle(radius));
-    } else if (initialInterface == 5) {
-      /// Rechteck
-      double width = 0.5;
-      double height = 0.3;
-      WorldVector<double> center; center.set(0.5);
-      Initfile::get(name + "->rectangle->width", width);
-      Initfile::get(name + "->rectangle->height", height);
-      Initfile::get(name + "->rectangle->center", center);
-      prob->getSolution()->getDOFVector(1)->interpol(new Rectangle(width, height, center));
-    }
-    
-    // TODO: Redistancing einfügen!
-    if (useReinit) {
-      FiniteElemSpace* feSpace = FiniteElemSpace::provideFeSpace(
-	const_cast<DOFAdmin*>(getMesh()->getVertexAdmin()),
-	Lagrange::getLagrange(getMesh()->getDim(), 1),
-	getMesh(),
-	"P1");
-      DOFVector<double> tmp(feSpace, "tmp");
-      tmp.interpol(prob->getSolution()->getDOFVector(1));
-    
-      HL_SignedDistTraverse reinit("reinit", getMesh()->getDim());
-      reinit.calcSignedDistFct(adaptInfo, &tmp);
-    
-#ifndef HAVE_PARALLEL_DOMAIN_AMDIS
-      Recovery recovery(L2_NORM, 1);
-      recovery.recoveryUh(&tmp, *prob->getSolution()->getDOFVector(1));
-#else
-      prob->getSolution()->getDOFVector(1)->interpol(&tmp);
-#endif
-    }
-    
-
-    /// create phase-field from signed-dist-function
-    if (doubleWell == 0) {
-      forEachDOF(prob->getSolution()->getDOFVector(1),
-        new SignedDistToPhaseField(initialEps));
-    } else {
-      forEachDOF(prob->getSolution()->getDOFVector(1),
-        new SignedDistToCh(initialEps));
-    }
-  }
-}
-
-
-void CahnHilliard_::fillOperators()
-{  
-  const FiniteElemSpace* feSpace = prob->getFeSpace();
-  int degree = feSpace->getBasisFcts()->getDegree();
-
-  // c
-  Operator *opChMnew = new Operator(feSpace, feSpace);
-  opChMnew->addTerm(new Simple_ZOT);
-  Operator *opChMold = new Operator(feSpace, feSpace);
-  opChMold->addTerm(new VecAtQP_ZOT(prob->getSolution()->getDOFVector(1)));
-  // -nabla*(grad(c))
-  Operator *opChL = new Operator(feSpace, feSpace);
-  opChL->addTerm(new Simple_SOT);
-  
-  // div(M(c)grad(mu)), with M(c)=gamma/4*(c^2-1)^2
-  Operator *opChLM = new Operator(feSpace, feSpace);
-  if (useMobility) {
-    if (doubleWell == 0)
-      opChLM->addTerm(new VecAtQP_SOT(
-	prob->getSolution()->getDOFVector(1),
-	new MobilityCH0(gamma, degree)));
-    else
-      opChLM->addTerm(new VecAtQP_SOT(
-	prob->getSolution()->getDOFVector(1),
-	new MobilityCH1(gamma, degree)));
-  } else
-    opChLM->addTerm(new Simple_SOT(gamma));
-  
-  // -2*c_old^3 + 3/2*c_old^2
-  Operator *opChMPowExpl = new Operator(feSpace, feSpace);
-  opChMPowExpl->addTerm(new VecAtQP_ZOT(
-    prob->getSolution()->getDOFVector(1),
-    new AMDiS::Pow<3>(-2.0, 3*degree)));
-  if (doubleWell == 0) {
-    opChMPowExpl->addTerm(new VecAtQP_ZOT(
-      prob->getSolution()->getDOFVector(1),
-      new AMDiS::Pow<2>(3.0/2.0, 2*degree)));
-  }
-
-  // -3*c_old^2 * c
-  Operator *opChMPowImpl = new Operator(feSpace, feSpace);
-  opChMPowImpl->addTerm(new VecAtQP_ZOT(
-    prob->getSolution()->getDOFVector(1),
-    new AMDiS::Pow<2>(-3.0, 2*degree)));
-  if (doubleWell == 0) {
-    opChMPowImpl->addTerm(new VecAtQP_ZOT(
-      prob->getSolution()->getDOFVector(1),
-      NULL, 3.0));
-    opChMPowImpl->addTerm(new Simple_ZOT(-0.5));
-  } else {
-    opChMPowImpl->addZeroOrderTerm(new Simple_ZOT(1.0));
-  }
-
-  // mu + eps^2*laplace(c) + c - 3*(c_old^2)*c = -2*c_old^3 [+ BC]
-  // ----------------------------------------------------------------------
-  prob->addMatrixOperator(*opChMPowImpl,0,1);          /// < -3*c*c_old^2 , psi >
-  prob->addMatrixOperator(*opChL,0,1, &minusEpsSqr);   /// < -eps^2*grad(c) , grad(psi) >
-  prob->addMatrixOperator(*opChMnew,0,0);              /// < mu , psi >
-  // . . . vectorOperators . . . . . . . . . . . . . . .
-  prob->addVectorOperator(*opChMPowExpl,0);            /// < -2*c_old^3 , psi >
-
-  
-  // dt(c) = laplace(mu) - u*grad(c)
-  // -----------------------------------
-  prob->addMatrixOperator(*opChMnew,1,1); 		/// < c , psi >
-  prob->addMatrixOperator(*opChLM,1,0, getTau());       /// < tau*grad(mu) , grad(psi) >
-  // . . . vectorOperators . . . . . . . . . . . . . . .
-  prob->addVectorOperator(*opChMold,1);   		/// < c^old , psi >
-  
-}
-
-} }
diff --git a/extensions/preconditioner/CahnHilliard_.h b/extensions/preconditioner/CahnHilliard_.h
deleted file mode 100644
index 4c7bde8095a5a7a257287be39093adafa1154569..0000000000000000000000000000000000000000
--- a/extensions/preconditioner/CahnHilliard_.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/******************************************************************************
- *
- * Extension of AMDiS - Adaptive multidimensional simulations
- *
- * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
- * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
- *
- * Authors: Simon Praetorius et al.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- *
- * See also license.opensource.txt in the distribution.
- * 
- ******************************************************************************/
-
-#ifndef CAHN_HILLIARD_PRECON_H
-#define CAHN_HILLIARD_PRECON_H
-
-#include "AMDiS.h"
-#include "BaseProblem.h"
-#include "chns.h"
-
-namespace AMDiS { namespace base_problems {
-    
-class CahnHilliard_ : public BaseProblem<ProblemStat>
-{
-public: // definition of types
-
-  typedef BaseProblem<ProblemStat> super;
-
-public: // public methods
-
-  CahnHilliard_(const std::string &name_);
-  ~CahnHilliard_() {};
-  
-  void solveInitialProblem(AdaptInfo *adaptInfo);
-
-  double getEpsilon() { return eps; }
-  int getDoubleWellType() { return doubleWell; }
-
-  void fillOperators() override;
-  void fillBoundaryConditions() override {}
-
-protected: // protected variables
-
-  bool useMobility;
-  bool useReinit;
-
-  unsigned dim;
-
-  int doubleWell;
-
-  double gamma;
-  double eps;
-  double minusEps;
-  double epsInv;
-  double minusEpsInv;
-  double epsSqr;
-  double minusEpsSqr;
-};
-  
-} }
-
-#endif // CAHN_HILLIARD_PRECON_H
diff --git a/extensions/preconditioner/MTLPreconCahnHilliard.h b/extensions/preconditioner/MTLPreconCahnHilliard.h
index f5f19dbc19b921ed608419da803b61d70d96f5c4..07b2f168128355ac01d334a3cbd0fd0f189f3a81 100644
--- a/extensions/preconditioner/MTLPreconCahnHilliard.h
+++ b/extensions/preconditioner/MTLPreconCahnHilliard.h
@@ -14,126 +14,138 @@
  * See also license.opensource.txt in the distribution.
  * 
  ******************************************************************************/
+ 
 #ifndef MTL_CH_PRECONDITIONER_H
 #define MTL_CH_PRECONDITIONER_H
 
 #include "AMDiS.h"
-#include "BlockPreconditioner.h"
+#include "solver/BlockPreconditioner.h"
 
 namespace AMDiS { namespace extensions {
-  
-using namespace std;
 
-template< typename MatrixType = MTLTypes::MTLMatrix, typename VectorType = MTLTypes::MTLVector >
-struct MTLPreconCahnHilliard : BlockPreconditioner
+/// Block preconditioner for the Cahn-Hilliard equation
+/**
+ * Based on the paper "Efficient preconditioners for large scale binary 
+ * Cahn-Hilliard models", P.Boyanova, M.Do-Quang, M.Neytcheva
+ * 
+ * The Cahn-Hilliard equation must be provided in the form:
+ *
+ *    mu - Phi'(c) + eps^2*laplace(c) = 0
+ *    -gamma*tau*laplace(mu) + c + tau*(u*nabla)c = c^old
+ *
+ * respective in matrix form:
+ *
+ *    [ M          ,  -(J + eps^2*L) ] [mu] = [Phi'(c^old) - J*c^old]
+ *    [ gamma*tau*L,  M + tau*W      ] [c ] = [M*c^old              ]
+ *
+ * with M...mass matrix, L...laplace matrix, J...discretization of 
+ * jacobian of Phi', W...discretization of transport term
+ *
+ */
+template<typename MatrixType>
+struct MTLPreconChBase : BlockPreconditioner<MatrixType>
 {
-  typedef BlockPreconditioner super;
+  typedef MTLTypes::MTLVector              VectorType;
+  
+  typedef BlockPreconditioner<MatrixType>  super;
+  typedef MTLPreconChBase<MatrixType>      self;
+  typedef typename super::precon_base      precon_base;
  
-  class Creator : public PreconditionCreator
+  struct Creator : public CreatorInterfaceName<precon_base>
   {
-  public:
-    virtual ~Creator() {}
-    
-    BasePreconditioner* create() { 
-      return new MTLPreconCahnHilliard(this->name);
-    }
-  };  
-  
-  
-  MTLPreconCahnHilliard(std::string name)
-  : name(name), 
-    eps(NULL), delta(NULL),
-    solverM(NULL), solverMpL(NULL), runnerM(NULL), runnerMpL(NULL)
+    virtual ~Creator() {}    
+    precon_base* create() { return new self(this->name); }
+  };
+  
+  /// constructor
+  MTLPreconChBase(std::string name)
+    : name(name), 
+      eps(0.1), gamma(1.0), tau(NULL),
+      solverM(NULL), solverMpL(NULL), runnerM(NULL), runnerMpL(NULL)
   {
-    createSubSolver(name + "->subsolver M", solverM, runnerM);
-    createSubSolver(name + "->subsolver MpL", solverMpL, runnerMpL);
+    super::createSubSolver(name + "->subsolver M", solverM, runnerM, "cg", "diag", 5, 1.e-3);
+    super::createSubSolver(name + "->subsolver MpL", solverMpL, runnerMpL, "cg", "diag", 20, 1.e-3);
   }
   
   
-  virtual ~MTLPreconCahnHilliard()
+  /// destructor
+  virtual ~MTLPreconChBase()
   {
     exit();
     delete solverM;
     delete solverMpL;
   }
   
+  /// prepare needed data, e.g. the matrix MpL = M + a*L and initialize the runners
+  virtual void init(const SolverMatrix<Matrix<DOFMatrix*> >& A, const MatrixType& fullMatrix);  
   
-  virtual void init(const typename super::BlockMatrix& A, const MatrixType& fullMatrix);  
-  
+  /// apply the preconditioner P to a vector b, i.e. solve Px = b
   virtual void solve(const VectorType& b, VectorType& x) const;
   
-  
   virtual void exit()
   {
     runnerM->exit();
     runnerMpL->exit();
   }
   
+  const MatrixType& getM() const { return *matM; } // c
+  const MatrixType& getL() const { return *matL; } // laplace(c)
   
-  const MatrixType& getM() const
-  {
-    return A->getSubMatrix(0,0);
-  }
-  
-  
-  const MatrixType& getL() const
-  { 
-    return L; // gamma*tau*L
-  }
-  
-  
-  double getEps() const
-  {
-    return *eps;
-  }
-  
-  
-  double getDelta() const
-  {
-    return *delta;
-  }
-  
+  /// return delta = \ref tau * \ref gamma
+  double getDelta() const { return (*tau) * gamma; }
   
-  void setData(double* eps_, double* delta_)
+  /// the preconditioner needs some data from the Cahn-Hilliard equation.
+  /// This is passed in the struct data.
+  template<typename Data>
+  void setData(Data* data)
   {
-    eps = eps_;
-    delta = delta_;
+    tau = data->tau;
+    eps = data->eps;
+    gamma = data->gamma;
+    matM = &data->getM();
+    matL = &data->getL();
   }
   
 protected:      
+  /// solve the mass equation Mx = b
   template <typename VectorX, typename VectorB>
   void solveM(VectorX& x, const VectorB& b) const
   {
     runnerM->solve(getM(), x, b);
   }
   
-  
+  /// solve a diffusion equation (M+a*L)x = b
   template <typename VectorX, typename VectorB>
   void solveMpL(VectorX& x, const VectorB& b) const
   {
     runnerMpL->solve(MpL, x, b);
   }
   
+protected:  
+  MatrixType* matM;
+  MatrixType* matL;
   
-  MatrixType M;
   MatrixType MpL;
-  MatrixType L;
    
-  mutable MTLVector y1;
-  mutable MTLVector y2;
+  mutable VectorType y1;
+  mutable VectorType y2;
   
-  LinearSolver* solverM;
-  LinearSolver* solverMpL;
+  LinearSolverInterface* solverM;
+  LinearSolverInterface* solverMpL;
   
-  MTL4Runner<MatrixType, VectorType>* runnerM;
-  MTL4Runner<MatrixType, VectorType>* runnerMpL;
+  RunnerBase<MatrixType, VectorType>* runnerM;
+  RunnerBase<MatrixType, VectorType>* runnerMpL;
   
   std::string name;
   
-  double* eps;
-  double* delta;
+  double eps;
+  double gamma;
+  double* tau;
 };
 
+
+typedef MTLPreconChBase<MTLTypes::MTLMatrix> MTLPreconCahnHilliard;
+
 } }
 
 #include "MTLPreconCahnHilliard.hh"
diff --git a/extensions/preconditioner/MTLPreconCahnHilliard.hh b/extensions/preconditioner/MTLPreconCahnHilliard.hh
index e64f0ec2d14033510cfe4e12e3621f938af3b093..f49202e0782d99ea36e2e55cb219522582d65a7f 100644
--- a/extensions/preconditioner/MTLPreconCahnHilliard.hh
+++ b/extensions/preconditioner/MTLPreconCahnHilliard.hh
@@ -17,28 +17,16 @@
 
 namespace AMDiS { namespace extensions { 
   
-template< typename MatrixType, typename VectorType >
-void MTLPreconCahnHilliard< MatrixType, VectorType >::init(const BlockMatrix& A_, const MTLMatrix& fullMatrix_)
-{ FUNCNAME("MTLPreconCahnHilliard::init()");
+template< typename MatrixType >
+void MTLPreconChBase< MatrixType >::init(const SolverMatrix<Matrix<DOFMatrix*> >& A_, const MatrixType& fullMatrix_)
+{ FUNCNAME("MTLPreconChBase::init()");
 
   super::init(A_, fullMatrix_);
-  
-  assert(eps != NULL);
-  assert(delta != NULL);
-  
-  const FiniteElemSpace* feSpace = (*A_.getOriginalMat())[0][0]->getFeSpace();
-  DOFMatrix laplaceMatrix(feSpace, feSpace);
-  Operator laplaceOp(feSpace, feSpace);
-  Simple_SOT sot;
-  laplaceOp.addTerm(&sot);
-  laplaceMatrix.assembleOperator(laplaceOp);
-    
-  L.change_dim(num_rows(getM()), num_cols(getM()));
-  L = laplaceMatrix.getBaseMatrix();
+  assert(tau != NULL);  
   
   // helper-matrix MpL = M + eps*sqrt(delta)*L
   MpL.change_dim(num_rows(getM()), num_cols(getM()));
-  MpL = getM() + ( getEps()*sqrt(getDelta()) ) * getL();
+  MpL = getM() + ( eps*std::sqrt(getDelta()) ) * getL();
   
   // temporary variables
   y1.change_dim(num_rows(getM()));
@@ -49,19 +37,19 @@ void MTLPreconCahnHilliard< MatrixType, VectorType >::init(const BlockMatrix& A_
 }
 
 
-template< typename MatrixType, typename VectorType >
-void MTLPreconCahnHilliard< MatrixType, VectorType >::solve(const MTLVector& b, MTLVector& x) const
-{ FUNCNAME("MTLPreconCahnHilliard::solve()");
+template< typename MatrixType >
+void MTLPreconChBase< MatrixType >::solve(const VectorType& b, VectorType& x) const
+{ FUNCNAME("MTLPreconChBase::solve()");
 
   x.change_dim(num_rows(b));
   
-  const MTLVector b1(b[rows[0]]);
-  const MTLVector b2(b[rows[1]]);
+  const VectorType b1(b[super::getRowRange(0)]);
+  const VectorType b2(b[super::getRowRange(1)]);
   
-  MTLVector x1(x[rows[0]]);
-  MTLVector x2(x[rows[1]]);
+  VectorType x1(x[super::getRowRange(0)]);
+  VectorType x2(x[super::getRowRange(1)]);
     
-  double factor = getEps()/sqrt(getDelta());
+  double factor = eps/std::sqrt(getDelta());
   
   solveM(y1, b1);
   y2 = getL() * y1; 
diff --git a/extensions/preconditioner/MTLPreconCahnHilliard2.h b/extensions/preconditioner/MTLPreconCahnHilliard2.h
new file mode 100644
index 0000000000000000000000000000000000000000..0f08541229a361ffa394335f25e66b4079978d28
--- /dev/null
+++ b/extensions/preconditioner/MTLPreconCahnHilliard2.h
@@ -0,0 +1,253 @@
+/******************************************************************************
+ *
+ * Extension of AMDiS - Adaptive multidimensional simulations
+ *
+ * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
+ * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
+ *
+ * Authors: Simon Praetorius et al.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *
+ * See also license.opensource.txt in the distribution.
+ * 
+ ******************************************************************************/
+ 
+#ifndef MTL_CH_PRECONDITIONER2_H
+#define MTL_CH_PRECONDITIONER2_H
+
+#include "AMDiS.h"
+#include "solver/BlockPreconditioner.h"
+
+namespace AMDiS { namespace extensions {
+
+struct MTLPreconCh2Sub : BlockPreconditioner<MTLTypes::MTLMatrix>
+{
+  typedef MTLTypes::MTLMatrix   MatrixType;
+  typedef MTLTypes::MTLVector   VectorType;
+  
+  typedef BlockPreconditioner<MatrixType>  super;
+  typedef MTLPreconCh2Sub                  self;
+  
+  
+  MTLPreconCh2Sub(std::string name)
+    : name(name), 
+      eps(0.1), gamma(1.0), tau(NULL),
+      solverMpL(NULL), runnerMpL(NULL)
+  {
+    super::createSubSolver(name + "->subsolver MpL", solverMpL, runnerMpL, "cg", "diag", 10, 1.e-3);
+  }
+  
+  
+  virtual ~MTLPreconCh2Sub()
+  {
+    exit();
+    delete solverMpL;
+  }
+  
+  /// prepare needed data, e.g. the matrix MpL = M + a*L and initialize the runners
+  virtual void init(const SolverMatrix<Matrix<DOFMatrix*> >& A, const MatrixType& fullMatrix);  
+  
+  /// apply the preconditioner P to a vector b, i.e. solve Px = b
+  virtual void solve(const VectorType& b, VectorType& x) const;
+  
+  virtual void exit()
+  {
+    runnerMpL->exit();
+  }
+  
+  const MatrixType& getM() const { return *matM; } // c
+  const MatrixType& getL() const { return *matL; } // laplace(c)
+  
+  /// return delta = \ref tau * \ref gamma
+  double getDelta() const { return (*tau) * gamma; }
+  
+  /// the preconditioner needs some data from the Cahn-Hilliard equation.
+  /// This is passed in the struct data.
+  template<typename Data>
+  void setData(Data* data)
+  {
+    tau = data->tau;
+    eps = data->eps;
+    gamma = data->gamma;
+    matM = &data->getM();
+    matL = &data->getL();
+  }
+  
+protected:  
+  /// solve a diffusion equation (M+a*L)x = b
+  template <typename VectorX, typename VectorB>
+  void solveMpL(VectorX& x, const VectorB& b) const
+  {
+    runnerMpL->solve(MpL, x, b);
+  }
+  
+protected:  
+  MatrixType* matM;
+  MatrixType* matL;
+  
+  MatrixType MpL;
+   
+  mutable VectorType y1;
+  mutable VectorType y2;
+  
+  LinearSolverInterface* solverMpL;
+  
+  RunnerBase<MatrixType, VectorType>* runnerMpL;
+  
+  std::string name;
+  
+  double eps;
+  double gamma;
+  double* tau;
+};
+
+
+
+template <typename Vector>
+itl::pc::solver<MTLPreconCh2Sub, Vector, false>
+inline solve(const MTLPreconCh2Sub& P, const Vector& x)
+{
+  return itl::pc::solver<MTLPreconCh2Sub, Vector, false>(P, x);
+}
+
+
+
+/// Block preconditioner for the Cahn-Hilliard equation
+/**
+ * Based on the paper "Block-Preconditioners for Conforming and Non-conforming
+ * FEM Discretizations of the Cahn-Hilliard Equation", P.Boyanova, M.Do-Quang, M.Neytcheva
+ * 
+ * The Cahn-Hilliard equation must be provided in the form:
+ *
+ *    mu - Phi'(c) + eps^2*laplace(c) = 0
+ *    -gamma*tau*laplace(mu) + c + tau*(u*nabla)c = c^old
+ *
+ * respective in matrix form:
+ *
+ *    [ M          ,  -(J + eps^2*L) ] [mu] = [Phi'(c^old) - J*c^old]
+ *    [ gamma*tau*L,  M + tau*W      ] [c ] = [M*c^old              ]
+ *
+ * with M...mass matrix, L...laplace matrix, J...discretization of 
+ * jacobian of Phi', W...discretization of transport term
+ */
+template<typename MatrixType>
+struct MTLPreconCh2Base : BlockPreconditioner<MatrixType>
+{
+  typedef MTLTypes::MTLVector              VectorType;
+  
+  typedef BlockPreconditioner<MatrixType>  super;
+  typedef MTLPreconCh2Base<MatrixType>     self;
+  typedef typename super::precon_base      precon_base;
+ 
+  struct Creator : public CreatorInterfaceName<precon_base>
+  {
+    virtual ~Creator() {}    
+    precon_base* create() { return new self(this->name); }
+  };  
+  
+  
+  /// constructor
+  MTLPreconCh2Base(std::string name)
+    : name(name), 
+      eps(0.1), gamma(1.0), tau(NULL),
+      preconS(name), PId(NULL),
+      solverM(NULL), runnerM(NULL)
+  {
+    super::createSubSolver(name + "->subsolver M", solverM, runnerM, "cg", "diag", 5, 1.e-3);
+  }
+  
+  
+  /// destructor
+  virtual ~MTLPreconCh2Base()
+  {
+    exit();
+    if (PId) { delete PId; PId = NULL; }
+    delete solverM;
+  }
+  
+  /// prepare needed data, e.g. the matrix MpL = M + a*L and initialize the runners
+  virtual void init(const SolverMatrix<Matrix<DOFMatrix*> >& A, const MatrixType& fullMatrix);  
+  
+  /// apply the preconditioner P to a vector b, i.e. solve Px = b
+  virtual void solve(const VectorType& b, VectorType& x) const;
+  
+  virtual void exit()
+  {
+    runnerM->exit();
+    preconS.exit();
+  }
+  
+  const MatrixType& getM() const { return *matM; } // c
+  const MatrixType& getL() const { return *matL; } // laplace(c)
+  
+  /// return delta = \ref tau * \ref gamma
+  double getDelta() const { return (*tau) * gamma; }
+  
+  /// the preconditioner needs some data from the Cahn-Hilliard equation.
+  /// This is passed in the struct data.
+  template<typename Data>
+  void setData(Data* data)
+  {
+    tau = data->tau;
+    eps = data->eps;
+    gamma = data->gamma;
+    matM = &data->getM();
+    matL = &data->getL();
+    
+    preconS.setData(data);
+  }
+  
+protected:      
+  /// solve the mass equation Mx = b
+  template <typename VectorX, typename VectorB>
+  void solveM(VectorX& x, const VectorB& b) const
+  {
+    runnerM->solve(getM(), x, b);
+  }
+  
+  /// solve a diffusion equation (M+a*L)x = b
+  template <typename VectorX, typename VectorB>
+  void solveS(VectorX& x, const VectorB& b) const
+  {
+    int nIter = 20;
+    Parameters::get(name + "->subsolver S->solver->max iteration", nIter);
+    itl::basic_iteration<double> iter(b, nIter, 1.e-4, 0);
+    x = 0.0;
+    itl::fgmres(S, x, b, *PId, preconS, iter, 30);
+  }
+  
+protected:  
+  MatrixType* matM;
+  MatrixType* matL;
+  
+  MatrixType S;
+  MatrixType MInv;
+   
+  mutable VectorType y1;
+  mutable VectorType y2;
+  
+  double eps;
+  double gamma;
+  double* tau;
+  
+  MTLPreconCh2Sub preconS;
+  itl::pc::identity<MatrixType, double> *PId;
+  
+  LinearSolverInterface* solverM;
+  RunnerBase<MatrixType, VectorType>* runnerM;
+  
+  std::string name;
+};
+
+
+typedef MTLPreconCh2Base<MTLTypes::MTLMatrix> MTLPreconCahnHilliard2;
+
+} }
+
+#include "MTLPreconCahnHilliard2.hh"
+
+#endif // MTL_CH_PRECONDITIONER2_H
+
diff --git a/extensions/preconditioner/MTLPreconCahnHilliard2.hh b/extensions/preconditioner/MTLPreconCahnHilliard2.hh
new file mode 100644
index 0000000000000000000000000000000000000000..789bd925f08067a16e0b2a5fb8a596b329c83116
--- /dev/null
+++ b/extensions/preconditioner/MTLPreconCahnHilliard2.hh
@@ -0,0 +1,97 @@
+/******************************************************************************
+ *
+ * Extension of AMDiS - Adaptive multidimensional simulations
+ *
+ * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
+ * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
+ *
+ * Authors: Simon Praetorius et al.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *
+ * See also license.opensource.txt in the distribution.
+ * 
+ ******************************************************************************/
+
+namespace AMDiS { namespace extensions { 
+  
+void MTLPreconCh2Sub::init(const SolverMatrix<Matrix<DOFMatrix*> >& A_, const MatrixType& fullMatrix_)
+{ FUNCNAME("MTLPreconCh2Sub::init()");
+
+  super::init(A_, fullMatrix_);
+  assert(tau != NULL);  
+  
+  // helper-matrix MpL = M + eps*sqrt(delta)*L
+  MpL.change_dim(num_rows(getM()), num_cols(getM()));
+  MpL = getM() + ( eps*std::sqrt(getDelta()) ) * getL();
+  
+  y1.change_dim(num_rows(getM()));
+  y2.change_dim(num_rows(getM()));
+  
+  runnerMpL->init(A_, MpL);
+}
+
+
+void MTLPreconCh2Sub::solve(const VectorType& b, VectorType& x) const
+{ FUNCNAME("MTLPreconCh2Sub::solve()");
+
+  x.change_dim(num_rows(b));
+  
+  solveMpL(y1, b);
+  y2 = getM() * y1; 
+  solveMpL(x, y2);
+}
+
+  
+template< typename MatrixType >
+void MTLPreconCh2Base< MatrixType >::init(const SolverMatrix<Matrix<DOFMatrix*> >& A_, const MatrixType& fullMatrix_)
+{ FUNCNAME("MTLPreconCh2Base::init()");
+
+  super::init(A_, fullMatrix_);
+  assert(tau != NULL);
+  
+  mtl::dense_vector<double> diag_M = mtl::matrix::diagonal(getM());
+  for (size_t i = 0; i < size(diag_M); i++)
+    diag_M[i] = 1.0 / diag_M[i];
+  MInv = mtl::vector::diagonal(diag_M);
+  
+  S.change_dim(num_rows(getM()), num_cols(getM()));
+  S = getM() + ( sqr(eps)*getDelta() ) * getL() * MInv * getL();
+  
+  PId = new itl::pc::identity<MatrixType, double>(getM());
+  
+  // temporary variables
+  y1.change_dim(num_rows(getM()));
+  y2.change_dim(num_rows(getM()));
+  
+  runnerM->init(A_, getM());
+  preconS.init(A_, S);
+}
+
+
+template< typename MatrixType >
+void MTLPreconCh2Base< MatrixType >::solve(const VectorType& b, VectorType& x) const
+{ FUNCNAME("MTLPreconCh2Base::solve()");
+
+  x.change_dim(num_rows(b));
+  
+  const VectorType b1(b[super::getRowRange(0)]);
+  const VectorType b2(b[super::getRowRange(1)]);
+  
+  VectorType x1(x[super::getRowRange(0)]);
+  VectorType x2(x[super::getRowRange(1)]);
+  
+  solveM(y1, b1);
+  y2 = getL() * y1; 
+  x1 = b2 - getDelta() * y2;
+  
+  solveS(x2, x1);
+  y1 = getL() * x2;
+  y2 = b1 + sqr(eps) * y1;
+
+  solveM(x1, y2);
+}
+
+} }
\ No newline at end of file
diff --git a/extensions/preconditioner/MTLPreconNavierStokes.h b/extensions/preconditioner/MTLPreconNavierStokes.h
new file mode 100644
index 0000000000000000000000000000000000000000..3c1988b351cc14c856c5d00a2c2bd5024411dfe8
--- /dev/null
+++ b/extensions/preconditioner/MTLPreconNavierStokes.h
@@ -0,0 +1,211 @@
+/******************************************************************************
+ *
+ * Extension of AMDiS - Adaptive multidimensional simulations
+ *
+ * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
+ * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
+ *
+ * Authors: Simon Praetorius et al.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *
+ * See also license.opensource.txt in the distribution.
+ * 
+ ******************************************************************************/
+#ifndef MTL_NS_PRECONDITIONER_H
+#define MTL_NS_PRECONDITIONER_H
+
+#include "AMDiS.h"
+#include "BlockPreconditioner.h"
+
+namespace AMDiS { namespace extensions { 
+
+struct MTLPreconNavierStokes : BlockPreconditioner<MTLTypes::MTLMatrix>
+{
+  typedef MTLTypes::MTLMatrix MatrixType;
+  typedef MTLTypes::MTLVector VectorType;
+  
+  typedef BlockPreconditioner<MatrixType>                  super;
+  typedef MTLPreconNavierStokes                            self;
+  typedef ITL_BasePreconditioner<MatrixType, VectorType>   precon_base;
+ 
+  class Creator : public CreatorInterfaceName<precon_base>
+  {
+  public:
+    virtual ~Creator() {}
+    
+    precon_base* create() { 
+      return new self(this->name);
+    }
+  };  
+  
+  MTLPreconNavierStokes(std::string name)
+    : super(),
+      name(name), 
+      tau(NULL),
+      pressureComponent(Global::getGeo(WORLD)),
+      velocitySolutionMode(""),
+      massSolutionMode(""),
+      laplaceSolutionMode(""),
+      massMatrix(NULL), laplaceMatrix(NULL), conDifMatrix(NULL)
+      massMatrix_(1,1), laplaceMatrix_(1,1), 
+      velocityMatrix_(Global::getGeo(WORLD), Global::getGeo(WORLD)),
+      divMatrix_(1, Global::getGeo(WORLD)),
+      gradMatrix_(Global::getGeo(WORLD), 1),
+      solver_velocity(NULL), runner_velocity(NULL), 
+      solver_mass(NULL), runner_mass(NULL),
+      solver_laplace(NULL), runner_laplace(NULL)
+  {
+  
+    Parameters::get(name + "->navierstokes->pressure component", 
+		    pressureComponent);
+		    
+    std::string initFileStr_velocity = name + "navierstokes->velocity solver";
+    Parameters::get(initFileStr_velocity, velocitySolutionMode);
+    
+    std::string initFileStr_mass = name + "navierstokes->mass solver";
+    Parameters::get(initFileStr_mass, massSolutionMode);
+    
+    std::string initFileStr_laplace = name + "navierstokes->laplace solver";
+    Parameters::get(initFileStr_laplace, laplaceSolutionMode);
+		    
+    // === read solver-name ===
+    std::string solverType_velocity = "mtl_" + velocitySolutionMode;
+    std::string solverType_mass = "mtl_" + massSolutionMode;
+    std::string solverType_laplace = "mtl_" + laplaceSolutionMode;
+  
+    // velocity solver
+    LinearSolverCreator *solverCreator_velocity = 
+      dynamic_cast<LinearSolverCreator*>(CreatorMap<LinearSolver>::getCreator(solverType_velocity, initFileStr_velocity));
+    TEST_EXIT(solverCreator_velocity)
+      ("No valid solver type found in parameter \"%s\"\n", initFileStr_velocity.c_str());
+    solverCreator_velocity->setName(initFileStr_velocity);
+    solver_velocity = solverCreator_velocity->create();
+    runner_velocity = dynamic_cast<RunnerBase< MatrixType, VectorType >*>(solver_velocity->getRunner());
+    
+    // mass solver
+    LinearSolverCreator *solverCreator_mass = 
+      dynamic_cast<LinearSolverCreator*>(CreatorMap<LinearSolver>::getCreator(solverType_mass, initFileStr_mass));
+    TEST_EXIT(solverCreator_mass)
+      ("No valid solver type found in parameter \"%s\"\n", initFileStr_mass.c_str());
+    solverCreator_mass->setName(initFileStr_mass);
+    solver_mass = solverCreator_mass->create();
+    runner_mass = dynamic_cast<RunnerBase< MatrixType, VectorType >*>(solver_mass->getRunner());
+    
+    // laplace solver
+    LinearSolverCreator *solverCreator_laplace = 
+      dynamic_cast<LinearSolverCreator*>(CreatorMap<LinearSolver>::getCreator(solverType_laplace, initFileStr_laplace));
+    TEST_EXIT(solverCreator_laplace)
+      ("No valid solver type found in parameter \"%s\"\n", initFileStr_laplace.c_str());
+    solverCreator_laplace->setName(initFileStr_laplace);
+    solver_laplace = solverCreator_laplace->create();
+    runner_laplace = dynamic_cast<RunnerBase< MatrixType, VectorType >*>(solver_laplace->getRunner());
+  }
+  
+  virtual ~MTLPreconNavierStokes()
+  {
+    exit();
+  }
+  
+  void setStokesData(double *invTauPtr, SystemVector *vec, double *nu1_=NULL, double *nu2_=NULL, double *rho1_=NULL, double *rho2_=NULL)
+  {
+    nu = new double;	
+    (*nu) = 0.0;
+    invTau = invTauPtr;
+    solution = vec;
+    nu1=nu1_;
+    nu2=nu2_;
+    rho1=rho1_;
+    rho2=rho2_;      
+  }
+  
+  void setStokesData(double *nuPtr, double *invTauPtr, SystemVector *vec)
+  {
+    nu = nuPtr;
+    invTau = invTauPtr;
+    solution = vec;
+  }
+  
+  
+  void setPhase(DOFVector<double> *d)
+  {
+    phase = d;
+  }
+  
+  virtual void init(const typename super::BlockMatrix& A, const MatrixType& fullMatrix);
+  
+  virtual void exit()
+  {    
+    runner_laplace->exit();
+    runner_mass->exit();
+    runner_velocity->exit();
+  
+    if (massMatrix) { delete massMatrix; massMatrix = NULL; }
+    if (laplaceMatrix) { delete laplaceMatrix; laplaceMatrix = NULL; }
+    if (conDifMatrix) { delete conDifMatrix; conDifMatrix = NULL; }
+    if (solver_velocity) { delete solver_velocity; solver_velocity = NULL; }
+    if (solver_mass) { delete solver_mass; solver_mass = NULL; }
+    if (solver_laplace) { delete solver_laplace; solver_laplace = NULL; }
+  }
+  
+  virtual void solve(const MTLVector& b, MTLVector& x) const;  
+  
+  const MatrixType& getM() const { return massMatrix->getBaseMatrix(); }
+  const MatrixType& getL() const { return laplaceMatrix->getBaseMatrix(); }
+  const MatrixType& getConDif() const { return conDifMatrix->getBaseMatrix(); }
+  const MatrixType& getMatV() const { return blockVelocityMatrix->getMatrix(); }
+  
+  const MatrixType& getMatDiv() const { return blockDivMatrix->getMatrix(); }
+  const MatrixType& getMatGrad() const { return blockGradMatrix->getMatrix(); }
+  
+protected: 
+  DOFMatrix* massMatrix;
+  DOFMatrix* laplaceMatrix;
+  DOFMatrix* conDifMatrix;
+  
+  mtl::irange vel_rows;
+  
+  Matrix<DOFMatrix*> massMatrix_;
+  SolverMatrix<Matrix<DOFMatrix*> > blockMassMatrix; 
+  
+  Matrix<DOFMatrix*> laplaceMatrix_;
+  SolverMatrix<Matrix<DOFMatrix*> > blockLaplaceMatrix; 
+  
+  Matrix<DOFMatrix*> velocityMatrix_;
+  SolverMatrix<Matrix<DOFMatrix*> > blockVelocityMatrix; 
+  
+  Matrix<DOFMatrix*> divMatrix_;
+  SolverMatrix<Matrix<DOFMatrix*> > blockDivMatrix; 
+  
+  Matrix<DOFMatrix*> gradMatrix_;
+  SolverMatrix<Matrix<DOFMatrix*> > blockGradMatrix; 
+   
+  mutable VectorType y01;
+  mutable VectorType y2;
+  
+  int pressureComponent;
+  std::string velocitySolutionMode;
+  std::string massSolutionMode;
+  std::string laplaceSolutionMode;
+    
+  LinearSolverInterface* solver_velocity;
+  LinearSolverInterface* solver_mass;
+  LinearSolverInterface* solver_laplace;
+  
+  RunnerBase< MatrixType, VectorType >* runner_velocity;
+  RunnerBase< MatrixType, VectorType >* runner_mass;
+  RunnerBase< MatrixType, VectorType >* runner_laplace;
+
+  std::string name;
+  
+  double *nu, *invTau, *nu1,*nu2,*rho1,*rho2;
+};
+
+} }
+
+#include "MTLPreconNavierStokes.hh"
+
+#endif // MTL_NS_PRECONDITIONER_H
+
diff --git a/extensions/preconditioner/MTLPreconNavierStokes.hh b/extensions/preconditioner/MTLPreconNavierStokes.hh
new file mode 100644
index 0000000000000000000000000000000000000000..c86b7afb1a19681a2bf92382ea808283c2ec462b
--- /dev/null
+++ b/extensions/preconditioner/MTLPreconNavierStokes.hh
@@ -0,0 +1,149 @@
+/******************************************************************************
+ *
+ * Extension of AMDiS - Adaptive multidimensional simulations
+ *
+ * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
+ * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
+ *
+ * Authors: Simon Praetorius et al.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *
+ * See also license.opensource.txt in the distribution.
+ * 
+ ******************************************************************************/
+
+namespace AMDiS { namespace extensions { 
+  
+void MTLPreconNavierStokes::init(const BlockMatrix& A_, const MatrixType& fullMatrix_)
+{
+  super::init(A_, fullMatrix_);
+  
+  // === extract velocity rows === 
+  BlockMapper mapper(A_);
+  mapper.setRow(Global::getGeo(WORLD));
+  vel_rows.set(0, mapper.row(0));
+  
+  // === create submatrices === 
+  Matrix<DOFMatrix*>* mat = A_.getOriginalMat();
+  for (int i = 0; i < Global::getGeo(WORLD); i++) {
+    for (int j = 0; j < Global::getGeo(WORLD); j++) {
+      velocityMatrix_[i][j] = (*mat)[i][j];
+    }
+  }
+  blockVelocityMatrix.setMatrix(velocityMatrix_);
+  runner_velocity.init(blockVelocityMatrix, getMatV()); // TODO: eventuell auf neues Erzeugen verzichten!
+  
+  for (int j = 0; j < Global::getGeo(WORLD); j++)
+    divMatrix_[0][j] = (*mat)[pressureComponent][j];
+  blockDivMatrix.setMatrix(divMatrix_);
+  
+  for (int i = 0; i < Global::getGeo(WORLD); i++)
+    gradMatrix_[i][0] = (*mat)[i][pressureComponent];
+  blockGradMatrix.setMatrix(gradMatrix_);
+
+  
+  const FiniteElemSpace *pressureFeSpace = componentSpaces[pressureComponent];
+  
+  // === Mass matrix solver ===    
+  massMatrix = new DOFMatrix(pressureFeSpace, pressureFeSpace);
+  {
+    Operator massOp(pressureFeSpace, pressureFeSpace);
+    if ((!phase) || (*nu == 0.0))
+      addZOT(massOp, 1.0);
+    else
+      addZOT(massOp, valueOf(phase));
+    massMatrix->assembleOperator(massOp);
+  }
+  massMatrix_(0,0) = massMatrix;
+  blockMassMatrix.setMatrix(massMatrix_);
+  runner_mass.init(blockMassMatrix, getM());
+  
+
+  // === Laplace matrix solver ===
+  laplaceMatrix = new DOFMatrix(pressureFeSpace, pressureFeSpace);
+  {
+    Operator laplaceOp(pressureFeSpace, pressureFeSpace);
+    if ((!phase) || (*nu == 0.0))
+      addSOT(laplaceOp, 1.0);
+    else
+      addSOT(laplaceOp, valueOf(phase));
+    laplaceMatrix.assembleOperator(laplaceOp);
+  }
+  laplaceMatrix_(0,0) = laplaceMatrix;
+  blockLaplaceMatrix.setMatrix(laplaceMatrix_);
+  runner_laplace.init(blockLaplaceMatrix, getL());
+  
+  
+  // === Create convection-diffusion operator ===
+  conDifMatrix = new DOFMatrix(pressureFeSpace, pressureFeSpace);
+  {
+    Operator conDifOp(pressureFeSpace, pressureFeSpace);
+    
+    DOFVector<double> vp(pressureFeSpace, "vp");
+    
+    WorldVector<DOFVector<double>*> V;
+    for (int i = 0; i < V.getSize(); i++) {
+      V[i] = new DOFVector<double>(pressureFeSpace, "v_i");
+      V[i]->interpol(solution->getDOFVector(i));
+    }
+
+    if (!phase) { // no phase given
+      MSG("INIT WITHOUT PHASE!\n");
+      addZOT(conDifOp, *invTau);
+      addZOT(conDifOp, *nu);
+      addFOT(conDifOp, valueOf(V), GRD_PHI);
+    } else {
+      vp.interpol(phase);
+      
+      if (*nu > 0.0) {
+	addZOT(conDifOp, valueOf(vp) * (*invTau));
+	addSOT(conDifOp, valueOf(vp) * (*nu));
+	addFOT(conDifOp, valueOf(vp) * valueOf(V), GRD_PHI);
+      } else {
+	addZOT(conDifOp, function_(wrap(new LinearInterpolation(*rho1,*rho2,*invTau)), valueOf(vp)) );
+	addSOT(conDifOp, function_(wrap(new LinearInterpolation(*nu1,*nu2)), valueOf(vp)) );
+	addFOT(conDifOp, valueOf(V) * function_(wrap(new LinearInterpolation(*rho1,*rho2)), valueOf(vp)), GRD_PHI );
+      }
+    }
+    conDifMatrix->assembleOperator(conDifOp);
+    
+    for (int i = 0; i < V.getSize(); i++)
+      delete V[i];
+  }
+
+  // temporary variables
+  y01.change_dim(num_rows(getMatV()));
+  y2.change_dim(num_rows(getM()));
+}
+
+
+void MTLPreconNavierStokes::solve(const VectorType& b, VectorType& x) const
+{ FUNCNAME("MTLPreconNavierStokes::solve()");
+
+  x.change_dim(num_rows(b));
+  
+  const VectorType b01(b[vel_rows]);
+  const VectorType b2(b[rows[pressureComponent]]);
+    
+  VectorType x01(x[vel_rows]);
+  VectorType x2(x[rows[pressureComponent]]);
+  
+  runner_velocity->solve(getMatV(), y01, b01);	// -> y01
+  y2 = b2 - getMatDiv() * y01;			// -> y2
+  runner_laplace->solve(getL(), x2, y2);		// -> x2
+  
+  // project out constant Null-space
+  double vecSum = sum(x2) / size(x2);
+  x2 -= vecSum;					// -> x2 -= sum(x2)/size(x2)
+    
+  y2 = getMatConDif() * x2;			// -> y2
+  runner_mass->solve(getM(), x2, y2);		// => x2
+  
+  y01 = b01 - getMatGrad() * x2;		// -> y01
+  runner_velocity->solve(getMatV(), x01, y01);	// => x01
+}
+
+} }
diff --git a/extensions/preconditioner/MTLPreconPfc.h b/extensions/preconditioner/MTLPreconPfc.h
index 4294bbb93156cc3ce724c40bda7a92e7fdf7958e..21c16a66dd7b42207405b9f86299d78a8ba07d77 100644
--- a/extensions/preconditioner/MTLPreconPfc.h
+++ b/extensions/preconditioner/MTLPreconPfc.h
@@ -18,7 +18,7 @@
 #define MTL_PFC_PRECONDITIONER_H
 
 #include "AMDiS.h"
-#include "BlockPreconditioner.h"
+#include "solver/BlockPreconditioner.h"
 
 #include <boost/numeric/mtl/interface/umfpack_solve.hpp>
 
@@ -27,39 +27,45 @@ namespace AMDiS { namespace extensions {
 using namespace std; 
 using namespace AMDiS::MTLTypes;
 
-struct MTLPreconPfc : BlockPreconditioner
+template<typename MatrixType>
+struct MTLPreconPfcBase : BlockPreconditioner<MatrixType>
 {
-  typedef BlockPreconditioner super;
+  typedef BlockPreconditioner<MatrixType>                           super;
+  typedef ITL_BasePreconditioner<MatrixType, MTLTypes::MTLVector>   precon_base;
+  typedef MTLPreconPfcBase<MatrixType>                              self;
  
-  class Creator : public PreconditionCreator
+  class Creator : public CreatorInterfaceName<precon_base>
   {
   public:
     virtual ~Creator() {}
     
-    BasePreconditioner* create() { 
-      return new MTLPreconPfc(this->name);
+    precon_base* create() { 
+      return new self(this->name);
     }
   };  
   
-  MTLPreconPfc(std::string name)
-  : BlockPreconditioner(),
-    name(name), 
-    tau(NULL),
-    PId(NULL), PDiagM(NULL), PDiagMpL(NULL), PDiagMpL2(NULL),
-    solverM(NULL), solverMpL(NULL), solverMpL2(NULL)
+  MTLPreconPfcBase(std::string name)
+    : super(),
+      name(name), 
+      tau(NULL),
+      PId(NULL), PDiagM(NULL), PDiagMpL(NULL), PDiagMpL2(NULL),
+      solverM(NULL), solverMpL(NULL), solverMpL2(NULL)
   { }
   
-  virtual ~MTLPreconPfc()
+  virtual ~MTLPreconPfcBase()
   {
     exit();
   }
   
-  void setData(double* tau_)
+  template<typename Data>
+  void setData(Data* data)
   {
-    tau = tau_;
+    tau = data->tau;
+    matM = &data->getM();
+    matL = &data->getL();
   }
   
-  virtual void init(const typename super::BlockMatrix& A, const MTLTypes::MTLMatrix& fullMatrix);
+  virtual void init(const SolverMatrix<Matrix<DOFMatrix*> >& A, const MatrixType& fullMatrix);
   
   virtual void exit()
   {    
@@ -132,11 +138,14 @@ struct MTLPreconPfc : BlockPreconditioner
   }
   
   
-  const MTLMatrix& getM() const { return A->getSubMatrix(2,2); }
-  const MTLMatrix& getL() const { return A->getSubMatrix(2,1); }
+  const MTLMatrix& getM() const { return *matM; }
+  const MTLMatrix& getL() const { return *matL; }
   double getTau() const { return *tau; }
   
 protected: 
+  MTLMatrix* matM;
+  MTLMatrix* matL;
+  
   MTLMatrix MpL;
   MTLMatrix MpL2;
    
@@ -144,20 +153,22 @@ protected:
   mutable MTLVector y1;
   mutable MTLVector tmp;
   
-  itl::pc::identity<MTLTypes::MTLMatrix, double> *PId;
-  itl::pc::diagonal<MTLTypes::MTLMatrix, double> *PDiagM;
-  itl::pc::diagonal<MTLTypes::MTLMatrix, double> *PDiagMpL;
-  itl::pc::diagonal<MTLTypes::MTLMatrix, double> *PDiagMpL2;
+  itl::pc::identity<MTLMatrix, double> *PId;
+  itl::pc::diagonal<MTLMatrix, double> *PDiagM;
+  itl::pc::diagonal<MTLMatrix, double> *PDiagMpL;
+  itl::pc::diagonal<MTLMatrix, double> *PDiagMpL2;
 
-  mtl::matrix::umfpack::solver<MTLTypes::MTLMatrix> *solverM;
-  mtl::matrix::umfpack::solver<MTLTypes::MTLMatrix> *solverMpL;
-  mtl::matrix::umfpack::solver<MTLTypes::MTLMatrix> *solverMpL2;
+  mtl::matrix::umfpack::solver<MTLMatrix> *solverM;
+  mtl::matrix::umfpack::solver<MTLMatrix> *solverMpL;
+  mtl::matrix::umfpack::solver<MTLMatrix> *solverMpL2;
 
   std::string name;
   
   double* tau;
 };
 
+typedef MTLPreconPfcBase<MTLTypes::MTLMatrix> MTLPreconPfc;
+
 } }
 
 #include "MTLPreconPfc.hh"
diff --git a/extensions/preconditioner/MTLPreconPfc.hh b/extensions/preconditioner/MTLPreconPfc.hh
index 28ddde0e21a41ab3404a53f62eca20ac4995e3b9..d10df58f22208f586f24d0398fa0ae7085876148 100644
--- a/extensions/preconditioner/MTLPreconPfc.hh
+++ b/extensions/preconditioner/MTLPreconPfc.hh
@@ -17,7 +17,8 @@
 
 namespace AMDiS { namespace extensions { 
   
-void MTLPreconPfc::init(const BlockMatrix& A_, const MTLMatrix& fullMatrix_)
+template<typename MatrixType>
+void MTLPreconPfcBase<MatrixType>::init(const SolverMatrix<Matrix<DOFMatrix*> >& A_, const MatrixType& fullMatrix_)
 {
   assert(tau != NULL);  
   super::init(A_, fullMatrix_);
@@ -66,18 +67,19 @@ void MTLPreconPfc::init(const BlockMatrix& A_, const MTLMatrix& fullMatrix_)
 }
 
 
-void MTLPreconPfc::solve(const MTLVector& b, MTLVector& x) const
+template<typename MatrixType>
+void MTLPreconPfcBase<MatrixType>::solve(const MTLVector& b, MTLVector& x) const
 { FUNCNAME("MTLPreconPfc::solve()");
 
   x.change_dim(num_rows(b));
   
-  const MTLVector b0(b[rows[0]]);
-  const MTLVector b1(b[rows[1]]);
-  const MTLVector b2(b[rows[2]]);
+  MTLVector x0(x[super::getRowRange(0)]);
+  MTLVector x1(x[super::getRowRange(1)]);
+  MTLVector x2(x[super::getRowRange(2)]);
   
-  MTLVector x0(x[rows[0]]);
-  MTLVector x1(x[rows[1]]);
-  MTLVector x2(x[rows[2]]);
+  const MTLVector b0(b[super::getRowRange(0)]);
+  const MTLVector b1(b[super::getRowRange(1)]);
+  const MTLVector b2(b[super::getRowRange(2)]); 
   
   double delta = std::sqrt(getTau());
   
diff --git a/extensions/preconditioner/PetscPreconCahnHilliard.cc b/extensions/preconditioner/PetscPreconCahnHilliard.cc
index 684cf2f31ad3f0df631e8c027d6b1b3605ca9100..263472997393af910aa4a3a4b2efc6b897986e34 100644
--- a/extensions/preconditioner/PetscPreconCahnHilliard.cc
+++ b/extensions/preconditioner/PetscPreconCahnHilliard.cc
@@ -57,28 +57,26 @@ namespace AMDiS {
   }
   
 
-  void PetscPreconCahnHilliard::init(const SolverMatrix<Matrix<DOFMatrix*> >& A, const PetscMatrixNested& src)
-  {
-    super::init(A, src);
-    
-    PCSetType(getPc(), PCSHELL);
-    PCShellSetApply(getPc(), pcChShell);
-    PCShellSetContext(getPc(), &data);
+  void PetscPreconCahnHilliard::init(PC pc, const SolverMatrix<Matrix<DOFMatrix*> >&, const MatrixType& A)
+  {    
+    PCSetType(pc, PCSHELL);
+    PCShellSetApply(pc, pcChShell);
+    PCShellSetContext(pc, &data);
     
-    MatNestGetSubMat(src.matrix, 1, 0, &data.matM);
+    MatNestGetSubMat(A.matrix, 1, 0, &data.matM);
     MatDuplicate(data.matM, MAT_COPY_VALUES, &data.matMinusDeltaK);
     MatScale(data.matMinusDeltaK, -1.0);
     
-    MatNestGetSubMat(src.matrix, 0, 0, &data.matM);
+    MatNestGetSubMat(A.matrix, 0, 0, &data.matM);
     
     MatDuplicate(data.matM, MAT_COPY_VALUES, &MpK);
     MatAXPY(MpK, -(*eps)/sqrt(*delta), data.matMinusDeltaK, SAME_NONZERO_PATTERN);
     
-    createSubSolver(data.kspM, data.matM, "mass_");
-    createSubSolver(data.kspMpK, MpK, "MpK_");
+    Runner::createSubSolver(data.kspM, data.matM, "mass_");
+    Runner::createSubSolver(data.kspMpK, MpK, "MpK_");
 
-    setSolver(data.kspM, "mass_", KSPCG, PCJACOBI, 0.0, 1e-14, 15);
-    setSolver(data.kspMpK, "MpK_", KSPRICHARDSON, PCHYPRE, 0.0, 1e-14, 15);
+    Runner::setSolver(data.kspM, "mass_", KSPCG, PCJACOBI, 0.0, 1e-14, 15);
+    Runner::setSolver(data.kspMpK, "MpK_", KSPRICHARDSON, PCHYPRE, 0.0, 1e-14, 15);
     
     // === Setup preconditioner data ===    
     data.delta = *delta;
@@ -93,7 +91,5 @@ namespace AMDiS {
     
     KSPDestroy(&data.kspM);
     KSPDestroy(&data.kspMpK);
-    
-    super::exit();
   }
 }
diff --git a/extensions/preconditioner/PetscPreconCahnHilliard.h b/extensions/preconditioner/PetscPreconCahnHilliard.h
index efb208b57e7cd508504ccf28fd295ee83e62d42b..d9d9eb4d05d98587bd94992a8ce8c9d84d3e444e 100644
--- a/extensions/preconditioner/PetscPreconCahnHilliard.h
+++ b/extensions/preconditioner/PetscPreconCahnHilliard.h
@@ -31,18 +31,27 @@ namespace AMDiS {
     double delta, eps;
   };
 
-  class PetscPreconCahnHilliard : public PetscRunner<PetscMatrixNested, PetscVectorNested>
+  class PetscPreconCahnHilliard : public PetscPreconditionerNested
   {
   public:
-    typedef PetscPreconCahnHilliard                            self;
-    typedef PetscRunner<PetscMatrixNested, PetscVectorNested>  super;
+    typedef PetscMatrixNested    MatrixType;
+    typedef PetscVectorNested    VectorType;
     
-    PetscPreconCahnHilliard(LinearSolverInterface* oem_)
-      : super(oem_),
+    typedef PetscPreconditionerNested            super;
+    typedef PetscPreconCahnHilliard              self;
+    typedef PetscRunner<MatrixType, VectorType>  Runner;
+    
+    struct Creator : CreatorInterfaceName<super>
+    {
+      virtual ~Creator() {}
+      super* create() { return new self(); }
+    };
+    
+    PetscPreconCahnHilliard()
+      : super("ch_", "ch"),
 	MpK(PETSC_NULL),
 	eps(NULL),
-	delta(NULL) 
-    { }
+	delta(NULL) { }
 
     void setData(double *epsPtr, double *deltaPtr)
     {
@@ -50,7 +59,7 @@ namespace AMDiS {
       delta = deltaPtr;
     }
 
-    void init(const SolverMatrix<Matrix<DOFMatrix*> >& A, const PetscMatrixNested& fullMatrix);
+    void init(PC pc, const SolverMatrix<Matrix<DOFMatrix*> >& A, const MatrixType& fullMatrix);
     void exit();
 
   private:
diff --git a/extensions/preconditioner/PetscPreconPfc.cc b/extensions/preconditioner/PetscPreconPfc.cc
index 91a56e9cc31132a05e7dcab57cc29144d6b964ac..22b06545a28dd439c6913f46ba26aca621133423 100644
--- a/extensions/preconditioner/PetscPreconPfc.cc
+++ b/extensions/preconditioner/PetscPreconPfc.cc
@@ -14,8 +14,9 @@
  * See also license.opensource.txt in the distribution.
  * 
  ******************************************************************************/
+
+
 #include "PetscPreconPfc.h"
-// #include "TimeTracer.h"
 
 namespace AMDiS {
 
@@ -71,21 +72,21 @@ namespace AMDiS {
   }
   
 
-  void PetscPreconPfc::init(const SolverMatrix<Matrix<DOFMatrix*> >& A, const PetscMatrixNested& src)
-  {
+  void PetscPreconPfc::init(PC pc, const SolverMatrix<Matrix<DOFMatrix*> >&, const MatrixType& A)
+  { FUNCNAME("PetscPreconPfc::init()");
+    
     assert(tau != NULL);
-    super::init(A, src);
     
     // init shell preconditioner
-    PCSetType(getPc(), PCSHELL);
-    PCShellSetApply(getPc(), pcPfcShell);
-    PCShellSetContext(getPc(), &data);
+    PCSetType(pc, PCSHELL);
+    PCShellSetApply(pc, pcPfcShell);
+    PCShellSetContext(pc, &data);
     
   
     double delta = sqrt(*tau);
     
-    MatNestGetSubMat(src.matrix, 2, 2, &data.matM);
-    MatNestGetSubMat(src.matrix, 2, 1, &data.matK);
+    MatNestGetSubMat(A.matrix, 2, 2, &data.matM);
+    MatNestGetSubMat(A.matrix, 2, 1, &data.matK);
     
     MatDuplicate(data.matM, MAT_COPY_VALUES, &MpK);
     MatAXPY(MpK, delta, data.matK, SAME_NONZERO_PATTERN);
@@ -94,9 +95,9 @@ namespace AMDiS {
     MatAXPY(MpK2, sqrt(delta), data.matK, SAME_NONZERO_PATTERN);
     
     // init sub-solvers
-    createSubSolver(data.kspM, data.matM, "mass_");
-    createSubSolver(data.kspMpK, MpK, "MpK_");
-    createSubSolver(data.kspMpK2, MpK2, "MpK2_");
+    Runner::createSubSolver(data.kspM, data.matM, "mass_");
+    Runner::createSubSolver(data.kspMpK, MpK, "MpK_");
+    Runner::createSubSolver(data.kspMpK2, MpK2, "MpK2_");
     
     data.delta = delta;
     data.tau = *tau;
@@ -118,12 +119,12 @@ namespace AMDiS {
     bool useAMG = false;
     Parameters::get("precon_pfc_MpL2->use AMG", useAMG);
 
-    setSolver(data.kspM, "M_", KSPCG, PCJACOBI, rtolM, tolM, nIterM);
-    setSolver(data.kspMpK, "MpK_", KSPCG, PCJACOBI, rtolMpL, tolMpL, nIterMpL);
+    Runner::setSolver(data.kspM, "M_", KSPCG, PCJACOBI, rtolM, tolM, nIterM);
+    Runner::setSolver(data.kspMpK, "MpK_", KSPCG, PCJACOBI, rtolMpL, tolMpL, nIterMpL);
     if (!useAMG) {
-      setSolver(data.kspMpK2, "MpK2_", KSPCG, PCJACOBI, rtolMpL2, tolMpL2, nIterMpL2);
+      Runner::setSolver(data.kspMpK2, "MpK2_", KSPCG, PCJACOBI, rtolMpL2, tolMpL2, nIterMpL2);
     } else {
-      setSolver(data.kspMpK2, "MpK2_", KSPRICHARDSON, PCHYPRE, rtolMpL2, tolMpL2, nIterMpL2);
+      Runner::setSolver(data.kspMpK2, "MpK2_", KSPRICHARDSON, PCHYPRE, rtolMpL2, tolMpL2, nIterMpL2);
     }
   }
 
@@ -136,7 +137,5 @@ namespace AMDiS {
     KSPDestroy(&data.kspM);
     KSPDestroy(&data.kspMpK);
     KSPDestroy(&data.kspMpK2);
-    
-    super::exit();
   }
 }
diff --git a/extensions/preconditioner/PetscPreconPfc.h b/extensions/preconditioner/PetscPreconPfc.h
index 1a6a7c8978b018aa590210ea7b3065bb9aeeeadb..a61ba554b2011950d58ab2b0ddbd7242bea04f91 100644
--- a/extensions/preconditioner/PetscPreconPfc.h
+++ b/extensions/preconditioner/PetscPreconPfc.h
@@ -30,15 +30,25 @@ namespace AMDiS {
     double delta, tau;
   };
 
-  class PetscPreconPfc : public PetscRunner<PetscMatrixNested, PetscVectorNested>
+  class PetscPreconPfc : public PetscPreconditionerNested
   {
   public:
-    typedef PetscPreconPfc                                     self;
-    typedef PetscRunner<PetscMatrixNested, PetscVectorNested>  super;
+    typedef PetscMatrixNested    MatrixType;
+    typedef PetscVectorNested    VectorType;
     
+    typedef PetscPreconditionerNested            super;
+    typedef PetscPreconPfc                       self;
+    typedef PetscRunner<MatrixType, VectorType>  Runner;
     
-    PetscPreconPfc(LinearSolverInterface* oem_)
-      : super(oem_),
+    struct Creator : CreatorInterfaceName<super>
+    {
+      virtual ~Creator() {}
+      super* create() { return new self(); }
+    };
+
+  public:
+    PetscPreconPfc()
+      : super("pfc_", "pfc"),
 	tau(NULL)
     { }
 
@@ -47,8 +57,8 @@ namespace AMDiS {
       tau = tauPtr;
     }
 
-    void init(const SolverMatrix<Matrix<DOFMatrix*> >& A, const PetscMatrixNested& fullMatrix);
-    void exit();
+    void init(PC pc, const SolverMatrix<Matrix<DOFMatrix*> >& A, const MatrixType& fullMatrix) override;
+    void exit() override;
 
   private:
     Mat MpK;
diff --git a/extensions/preconditioner/PetscPreconPfcDiag.cc b/extensions/preconditioner/PetscPreconPfcDiag.cc
index 36632edd6cff301b9aa1dea9e7c9186fe24c8e8a..2afb0ae30da6e1595bde9b95ebbe4265951053ca 100644
--- a/extensions/preconditioner/PetscPreconPfcDiag.cc
+++ b/extensions/preconditioner/PetscPreconPfcDiag.cc
@@ -23,7 +23,8 @@ namespace AMDiS {
   
   /// solve Pfc Preconditioner
   PetscErrorCode pcPfcDiagShell(PC pc, Vec b, Vec x) // solve Px=b
-  {      
+  { FUNCNAME("pcPfcShell()");
+      
     void *ctx;
     PCShellGetContext(pc, &ctx);
     PfcDiagData* data = static_cast<PfcDiagData*>(ctx);
@@ -69,21 +70,19 @@ namespace AMDiS {
   }
   
 
-  void PetscPreconPfcDiag::init(const SolverMatrix<Matrix<DOFMatrix*> >& A, const PetscMatrixNested& src)
+  void PetscPreconPfcDiag::init(PC pc, const SolverMatrix<Matrix<DOFMatrix*> >&, const MatrixType& A)
   {
     assert(tau != NULL);
-    super::init(A, src);
     
     // init shell preconditioner
-    PCSetType(getPc(), PCSHELL);
-    PCShellSetApply(getPc(), pcPfcDiagShell);
-    PCShellSetContext(getPc(), &data);
-    
+    PCSetType(pc, PCSHELL);
+    PCShellSetApply(pc, pcPfcDiagShell);
+    PCShellSetContext(pc, &data);
   
     double delta = sqrt(*tau);
     
-    MatNestGetSubMat(src.matrix, 2, 2, &data.matM);
-    MatNestGetSubMat(src.matrix, 2, 1, &data.matK);
+    MatNestGetSubMat(A.matrix, 2, 2, &data.matM);
+    MatNestGetSubMat(A.matrix, 2, 1, &data.matK);
     
     MatDuplicate(data.matM, MAT_COPY_VALUES, &MpK);
     MatAXPY(MpK, delta, data.matK, SAME_NONZERO_PATTERN);
@@ -100,17 +99,17 @@ namespace AMDiS {
     
     MatGetDiagonal(data.matM, x);
     VecReciprocal(x);
-    MatDiagonalScale(DK, x, PETSC_NULL); 				// DK := M_D^(-1)*K
+    MatDiagonalScale(DK, x, PETSC_NULL); 					// DK := M_D^(-1)*K
     MatMatMult(data.matK, DK, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &matS); 	// S := K*DK
     MatAYPX(matS, delta, data.matM, DIFFERENT_NONZERO_PATTERN); 			// S = delta*S + M
-    MatAXPY(matS, (-2.0*delta), data.matK, DIFFERENT_NONZERO_PATTERN);	// S = S - 2*delta*K
+    MatAXPY(matS, (-2.0*delta), data.matK, DIFFERENT_NONZERO_PATTERN);		// S = S - 2*delta*K
     VecDestroy(&x);
     MatDestroy(&DK);
     
     // init sub-solvers
-    createSubSolver(data.kspM, data.matM, "mass_");
-    createSubSolver(data.kspMpK, MpK, "MpK_");
-    createSubSolver(data.kspS, matS, "MpK2_");
+    Runner::createSubSolver(data.kspM, data.matM, "mass_");
+    Runner::createSubSolver(data.kspMpK, MpK, "MpK_");
+    Runner::createSubSolver(data.kspS, matS, "MpK2_");
     
     data.delta = delta;
     data.tau = *tau;
@@ -131,25 +130,25 @@ namespace AMDiS {
     bool useAMG = false;
     Parameters::get("precon_pfc_MpL2->use AMG", useAMG);
 
-    setSolver(data.kspM, "M_", KSPCG, PCJACOBI, rtolM, tolM, nIterM);
-    setSolver(data.kspMpK, "MpK_", KSPCG, PCJACOBI, rtolMpL, tolMpL, nIterMpL);
+    Runner::setSolver(data.kspM, "M_", KSPCG, PCJACOBI, rtolM, tolM, nIterM);
+    Runner::setSolver(data.kspMpK, "MpK_", KSPCG, PCJACOBI, rtolMpL, tolMpL, nIterMpL);
     if (!useAMG) {
-      setSolver(data.kspS, "MpK2_", KSPCG, PCJACOBI, rtolMpL2, tolMpL2, nIterMpL2);
+      Runner::setSolver(data.kspS, "MpK2_", KSPCG, PCJACOBI, rtolMpL2, tolMpL2, nIterMpL2);
     } else {
-      setSolver(data.kspS, "MpK2_", KSPRICHARDSON, PCHYPRE, rtolMpL2, tolMpL2, nIterMpL2);
+      Runner::setSolver(data.kspS, "MpK2_", KSPRICHARDSON, PCHYPRE, rtolMpL2, tolMpL2, nIterMpL2);
     }
   }
 
 
   void PetscPreconPfcDiag::exit()
-  {    
+  {
+    FUNCNAME("PetscPreconPfcDiag::exit()");
+    
     MatDestroy(&MpK);
     MatDestroy(&matS);
     
     KSPDestroy(&data.kspM);
     KSPDestroy(&data.kspMpK);
     KSPDestroy(&data.kspS);
-    
-    super::exit();
   }
 }
diff --git a/extensions/preconditioner/PetscPreconPfcDiag.h b/extensions/preconditioner/PetscPreconPfcDiag.h
index 553548dab77ba45d06defa14147bd88806e81dd5..bf363bf1a408efd2f57ee6d8c4c0c7b06e8ff1de 100644
--- a/extensions/preconditioner/PetscPreconPfcDiag.h
+++ b/extensions/preconditioner/PetscPreconPfcDiag.h
@@ -30,14 +30,25 @@ namespace AMDiS {
     double delta, tau;
   };
 
-  class PetscPreconPfcDiag : public PetscRunner<PetscMatrixNested, PetscVectorNested>
+  class PetscPreconPfcDiag : public PetscPreconditionerNested
   {
   public:
-    typedef PetscPreconPfcDiag                                 self;
-    typedef PetscRunner<PetscMatrixNested, PetscVectorNested>  super;
+    typedef PetscMatrixNested    MatrixType;
+    typedef PetscVectorNested    VectorType;
     
-    PetscPreconPfcDiag(LinearSolverInterface* oem_)
-      : super(oem_),
+    typedef PetscPreconditionerNested            super;
+    typedef PetscPreconPfcDiag                   self;
+    typedef PetscRunner<MatrixType, VectorType>  Runner;
+    
+    struct Creator : CreatorInterfaceName<super>
+    {
+      virtual ~Creator() {}
+      super* create() { return new self(); }
+    };
+
+  public:
+    PetscPreconPfcDiag()
+      : super("pfc_", "pfc_diag"),
 	tau(NULL)
     { }
 
@@ -46,7 +57,7 @@ namespace AMDiS {
       tau = tauPtr;
     }
 
-    void init(const SolverMatrix<Matrix<DOFMatrix*> >& A, const PetscMatrixNested& fullMatrix);
+    void init(PC pc, const SolverMatrix<Matrix<DOFMatrix*> >& A, const MatrixType& fullMatrix);
     void exit();
 
   private:
diff --git a/extensions/preconditioner/PetscSolverNavierStokes2.cc b/extensions/preconditioner/PetscSolverNavierStokes2.cc
index 5792dd75b2eed2687b18c90cc7596cb3824cdc55..3e6e9209712682b176eebe473a9fec8d6995f146 100644
--- a/extensions/preconditioner/PetscSolverNavierStokes2.cc
+++ b/extensions/preconditioner/PetscSolverNavierStokes2.cc
@@ -133,7 +133,11 @@ namespace AMDiS { namespace Parallel {
   {
     // Create FGMRES based outer solver
     KSPCreate(domainComm, &ksp);
+#if (PETSC_VERSION_MINOR >= 5)
+    KSPSetOperators(ksp, getMatInterior(), getMatInterior());
+#else
     KSPSetOperators(ksp, getMatInterior(), getMatInterior(), SAME_NONZERO_PATTERN);
+#endif
     if (getInfo() >= 10)
       KSPMonitorSet(ksp, KSPMonitorDefault, PETSC_NULL, PETSC_NULL);
     else if (getInfo() >= 20)
diff --git a/extensions/preconditioner/PetscSolverNavierStokes2.h b/extensions/preconditioner/PetscSolverNavierStokes2.h
index 9fa2d05cccc93bc9af504a92a512ccf47b676f23..091ff96d0ebba01678942dfa7cccca797857d67a 100644
--- a/extensions/preconditioner/PetscSolverNavierStokes2.h
+++ b/extensions/preconditioner/PetscSolverNavierStokes2.h
@@ -105,7 +105,7 @@ namespace AMDiS { namespace Parallel {
       virtual ~Creator() {}
 
       /// Returns a new PetscSolver object.
-      LinearSolverInterface* create() 
+      LinearSolver* create() 
       { 
 	return new PetscSolverNavierStokes2(this->name); 
       }
diff --git a/extensions/preconditioner/PetscSolverPfc.cc b/extensions/preconditioner/PetscSolverPfc.cc
index 7f618bc40bc886925ff4e1356f03cde73875be3d..6101c175092439fb047b295f3bf985e080366717 100644
--- a/extensions/preconditioner/PetscSolverPfc.cc
+++ b/extensions/preconditioner/PetscSolverPfc.cc
@@ -166,6 +166,7 @@ namespace AMDiS { namespace Parallel {
     int nIterM=5, nIterMpL=20, nIterMpL2=10;
     double tolM=PETSC_DEFAULT, tolMpL=PETSC_DEFAULT, tolMpL2=PETSC_DEFAULT;
     double rtolM=PETSC_DEFAULT, rtolMpL=PETSC_DEFAULT, rtolMpL2=PETSC_DEFAULT;
+    bool directM = false, directMpL = false, directMpL2 = false;
     Parameters::get("precon_pfc_M->max iteration", nIterM);
     Parameters::get("precon_pfc_MpL->max iteration", nIterMpL);
     Parameters::get("precon_pfc_MpL2->max iteration", nIterMpL2);
@@ -176,16 +177,29 @@ namespace AMDiS { namespace Parallel {
     Parameters::get("precon_pfc_MpL->relative tolerance", rtolMpL);
     Parameters::get("precon_pfc_MpL2->relative tolerance", rtolMpL2);
     
+    Parameters::get("precon_pfc_M->use direct solver", directM);
+    Parameters::get("precon_pfc_MpL->use direct solver", directMpL);
+    Parameters::get("precon_pfc_MpL2->use direct solver", directMpL2);
+    
     bool useAMG = false;
     Parameters::get("precon_pfc_MpL2->use AMG", useAMG);
 
-    petsc_helper::setSolver(data.kspM, "M_", KSPCG, PCJACOBI, rtolM, tolM, nIterM);
-    petsc_helper::setSolver(data.kspMpK, "MpK_", KSPCG, PCJACOBI, rtolMpL, tolMpL, nIterMpL);
-    if (!useAMG) {
-      petsc_helper::setSolver(data.kspMpK2, "MpK2_", KSPCG, PCJACOBI, rtolMpL2, tolMpL2, nIterMpL2);
-    } else {
-      petsc_helper::setSolver(data.kspMpK2, "MpK2_", KSPRICHARDSON, PCHYPRE, rtolMpL2, tolMpL2, nIterMpL2);
-    }
+    if (directM)
+      petsc_helper::setSolverWithLu(data.kspM, "M_", KSPRICHARDSON, PCLU, MATSOLVERMUMPS , 0.0, 1e-14, 1);
+    else
+      petsc_helper::setSolver(data.kspM, "M_", KSPCG, PCBJACOBI, rtolM, tolM, nIterM);
+    
+    if (directMpL)
+      petsc_helper::setSolverWithLu(data.kspMpK, "MpL_", KSPRICHARDSON, PCLU, MATSOLVERMUMPS , 0.0, 1e-14, 1);
+    else
+      petsc_helper::setSolver(data.kspMpK, "MpL_", KSPCG, PCBJACOBI, rtolMpL, tolMpL, nIterMpL);
+    
+    if (directMpL2)
+      petsc_helper::setSolverWithLu(data.kspMpK2, "MpL2_", KSPRICHARDSON, PCLU, MATSOLVERMUMPS , 0.0, 1e-14, 1);
+    else if (useAMG)
+      petsc_helper::setSolver(data.kspMpK2, "MpL2_", KSPRICHARDSON, PCHYPRE, rtolMpL2, tolMpL2, nIterMpL2);
+    else
+      petsc_helper::setSolver(data.kspMpK2, "MpL2_", KSPCG, PCBJACOBI, rtolMpL2, tolMpL2, nIterMpL2);
   }
 
 
diff --git a/extensions/preconditioner/PetscSolverPfc.h b/extensions/preconditioner/PetscSolverPfc.h
index 0fb7674cbd08fb37e2626082cb51627d5bb265ca..b358410f3fc98d465fbdfea4ae874c300853ccf9 100644
--- a/extensions/preconditioner/PetscSolverPfc.h
+++ b/extensions/preconditioner/PetscSolverPfc.h
@@ -31,27 +31,24 @@ namespace AMDiS { namespace Parallel {
   class PetscSolverPfc : public PetscSolverGlobalBlockMatrix
   {
   public:
+    typedef PetscSolverPfc                self;
+    typedef PetscSolverGlobalBlockMatrix  super;
+  
     /// Creator class
-    class Creator : public LinearSolverCreator
+    struct Creator : public LinearSolverCreator
     {
-    public:
       virtual ~Creator() {}
-
-      /// Returns a new PetscSolver object.
-      LinearSolverInterface* create() 
-      { 
-	return new PetscSolverPfc(this->name); 
-      }
+      LinearSolverInterface* create() { return new self(this->name); }
     };
     
     PetscSolverPfc(std::string name)
-    : PetscSolverGlobalBlockMatrix(name),
-      solverM(NULL),
-      solverK(NULL),
-      solverMpK(NULL),
-      solverMpK2(NULL),
-      useOldInitialGuess(false),
-      tau(NULL)
+      : super(name),
+	solverM(NULL),
+	solverK(NULL),
+	solverMpK(NULL),
+	solverMpK2(NULL),
+	useOldInitialGuess(false),
+	tau(NULL)
     { 	
       Parameters::get(initFileStr + "->use old initial guess", useOldInitialGuess);
     }
diff --git a/extensions/preconditioner/PetscSolverPfc_diag.h b/extensions/preconditioner/PetscSolverPfc_diag.h
index 5bba67897fe2c0e196efb852ff085ac5652ec7ea..449af4dba4cf4acf388be698245367ded837b47c 100644
--- a/extensions/preconditioner/PetscSolverPfc_diag.h
+++ b/extensions/preconditioner/PetscSolverPfc_diag.h
@@ -31,27 +31,24 @@ namespace AMDiS { namespace Parallel {
   class PetscSolverPfcDiag : public PetscSolverGlobalBlockMatrix
   {
   public:
+    typedef PetscSolverPfcDiag            self;
+    typedef PetscSolverGlobalBlockMatrix  super;
+  
     /// Creator class
-    class Creator : public LinearSolverCreator
+    struct Creator : public LinearSolverCreator
     {
-    public:
       virtual ~Creator() {}
-
-      /// Returns a new PetscSolver object.
-      LinearSolverInterface* create() 
-      { 
-	return new PetscSolverPfcDiag(this->name); 
-      }
+      LinearSolverInterface* create() { return new self(this->name); }
     };
     
     PetscSolverPfcDiag(std::string name)
-    : PetscSolverGlobalBlockMatrix(name),
-      solverM(NULL),
-      solverK(NULL),
-      solverMpK(NULL),
-      solverS(NULL),
-      useOldInitialGuess(false),
-      tau(NULL)
+      : super(name),
+	solverM(NULL),
+	solverK(NULL),
+	solverMpK(NULL),
+	solverS(NULL),
+	useOldInitialGuess(false),
+	tau(NULL)
     { 	
       Parameters::get(initFileStr + "->use old initial guess", useOldInitialGuess);
     }
diff --git a/extensions/preconditioner/PhaseFieldCrystal_.cc b/extensions/preconditioner/PhaseFieldCrystal_.cc
deleted file mode 100644
index 8928d4c129a9d096960cd538a5a94fd5b53005b9..0000000000000000000000000000000000000000
--- a/extensions/preconditioner/PhaseFieldCrystal_.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-#include "PhaseFieldCrystal_.h"
-
-namespace AMDiS { namespace base_problems {
-  
-using namespace std;
-
-PhaseFieldCrystal_::PhaseFieldCrystal_(const std::string &name_, bool createProblem) :
-  super(name_, createProblem),
-  useMobility(false),
-  tempParameter(-0.6),
-  r(-0.4),		// temperature deviation
-  rho0(1.0),		// liquid density
-  density(-0.3),	// mean density
-  two(2.0),
-  minus2(-2.0)
-{  
-  Parameters::get(name + "->r",r);
-  Parameters::get(name + "->rho0", rho0);
-  Parameters::get(name + "->density", density);
-  Parameters::get(name + "->use mobility", useMobility);
-  tempParameter= -(1.0+r);
-}
-
-
-void PhaseFieldCrystal_::fillOperators()
-{
-  
-  int degree = prob->getFeSpace(0)->getBasisFcts()->getDegree();
-  
-  // phi*rho
-  Operator *opMnew = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
-  opMnew->addTerm(new Simple_ZOT);
-  Operator *opMold = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
-  opMold->addTerm(new VecAtQP_ZOT(prob->getSolution()->getDOFVector(1), NULL));
-
-  // -nabla*(phi*grad(rho))
-  Operator *opL = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
-  opL->addTerm(new Simple_SOT);
-  
-  Operator *opLM = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
-  double M0 = 1.0;
-  Parameters::get(name + "->M0", M0);
-  if (useMobility) // non-constant mobility
-    opLM->addTerm(new VecAtQP_SOT(
-      prob->getSolution()->getDOFVector(1),
-      new MobilityPfc(density, M0, degree)));
-  else // constant mobility
-    opLM->addTerm(new Simple_SOT(M0));
-  
-  // -(1+r)*phi*rho
-  Operator *opMTemp = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
-  opMTemp->addZeroOrderTerm(new Simple_ZOT());
-  // -2*rho_old^3
-  Operator *opMPowExpl = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
-  opMPowExpl->addZeroOrderTerm(new VecAtQP_ZOT(prob->getSolution()->getDOFVector(1),new AMDiS::Pow<3>(-2.0, 3*degree)));
-  // -3*rho_old^2
-  Operator *opMPowImpl = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
-  opMPowImpl->addZeroOrderTerm(new VecAtQP_ZOT(prob->getSolution()->getDOFVector(1),new AMDiS::Pow<2>(-3.0, 2*degree)));
-  
-  
-  // dt(rho) = laplace(mu) - u*grad(rho)
-  // -----------------------------------
-  prob->addMatrixOperator(opMnew, 1, 1);
-  prob->addMatrixOperator(opLM, 1, 0, getTau(), getTau()); // -laplace(mu)
-  // . . . vectorOperators . . . . . . . . . . . . . . .
-  prob->addVectorOperator(opMold, 1);
-  
-  // mu-2*nu-laplace(nu)-(1+r)*rho = (rho_old^3) + ExtPot - eps^2/(rho_old+0.9)
-  // ----------------------------------------------------------------------
-  prob->addMatrixOperator(opMTemp, 0, 1, getTempParameter(), getTempParameter()); // -phi*(1+r)*rho
-  prob->addMatrixOperator(opMPowImpl, 0, 1); // -3*rho*rho_old^2
-  prob->addMatrixOperator(opL, 0, 1, &two, &two); // -2*phi*laplace(rho) * psi
-  prob->addMatrixOperator(opMnew, 0, 0); // phi*mu * psi
-  prob->addMatrixOperator(opL, 0, 2); // phi*grad(nu) * grad(psi)
-  // . . . vectorOperators . . . . . . . . . . . . . . .
-  prob->addVectorOperator(opMPowExpl, 0); // -2*phi^old*rho_old^3
-  
-  // 0 = nu-laplace(rho)
-  // -------------------
-  prob->addMatrixOperator(opL, 2, 1); // -laplace(rho)
-  prob->addMatrixOperator(opMnew, 2, 2); // nu
-}
-
-
-void PhaseFieldCrystal_::fillBoundaryConditions()
-{}
-
-} }
diff --git a/extensions/preconditioner/PhaseFieldCrystal_.h b/extensions/preconditioner/PhaseFieldCrystal_.h
deleted file mode 100644
index 58fe938fdd9a6f20034228e232c8e6d5457c9b90..0000000000000000000000000000000000000000
--- a/extensions/preconditioner/PhaseFieldCrystal_.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/** \file PhaseFieldCrystal_.h */
-
-#ifndef PHASE_FIELD_CRYSTAL_PRECON_H_
-#define PHASE_FIELD_CRYSTAL_PRECON_H_
-
-#include "AMDiS.h"
-#include "BaseProblem.h"
-#include "ExtendedProblemStat.h"
-
-namespace AMDiS { namespace base_problems {
-
-/** Phase-field Crystal problem
- */
-class PhaseFieldCrystal_ : public BaseProblem<extensions::ExtendedProblemStat>
-{
-public: // typedefs
-
-  typedef BaseProblem<extensions::ExtendedProblemStat> super;
-
-public:
- 
-  PhaseFieldCrystal_(const std::string &name_, bool createProblem = true);
-  ~PhaseFieldCrystal_() {}
-
-  double *getTempParameter() { return &tempParameter; }
-
-  virtual void fillOperators();
-  virtual void fillBoundaryConditions();
-
-protected:
-
-  bool useMobility;
-
-  double tempParameter;
-  double r;
-  double rho0;
-  double density;
-  double two;
-  double minus2;
-};
-
-
-/** \ingroup MainInstat
- * \brief
- * Abstract function to calculate the pure PFC-Energy
- */
-class Energy : public BinaryAbstractFunction<double,double,double>
-{
-  public:
-    Energy() : BinaryAbstractFunction<double,double,double>(4) { }
-
-    double operator()(const double &rho, const double &mu) const {
-      return -0.25*sqr(sqr(rho)) + 0.5*rho*mu; }
-};
-
-
-class MobilityPfc : public AbstractFunction<double,double>
-{
-  public:
-    MobilityPfc(double density_ = -0.3, double factor_ = 1.0, int degree=1) : 
-      AbstractFunction<double,double>(degree+1),
-      density(density_),
-      factor(factor_),
-      delta(1.e-6) { }
-
-    double operator()(const double &rho) const 
-    {
-      double mobility= std::abs(rho + 1.5)*factor;
-      return std::max(mobility, 0.0);
-    }
-  
-  protected:
-    double density;
-    double factor;
-    double delta;
-};
-
-} }
-
-#endif // PHASE_FIELD_CRYSTAL_PRECON_H_