From 35be339357d12502991f3368e4839758fdbc6c1c Mon Sep 17 00:00:00 2001
From: Andreas Naumann <andreas.naumann@tu-dresden.de>
Date: Sun, 15 May 2011 15:43:00 +0000
Subject: [PATCH] pmtl implemententation. test works

---
 AMDiS/AMDiSConfig.cmake.in          |   3 +
 AMDiS/AMDiSUse.cmake                |  16 +-
 AMDiS/CMakeLists.txt                | 109 ++++++----
 AMDiS/src/AMDiS.h                   |   2 +
 AMDiS/src/AMDiS_fwd.h               |   3 +-
 AMDiS/src/BasePreconditioner.h      |  46 ++++
 AMDiS/src/Collection.h              |  41 ++++
 AMDiS/src/CreatorMap.cc             |   5 +-
 AMDiS/src/Global.h                  |   4 +-
 AMDiS/src/ITL_OEMSolver.h           |  71 ++-----
 AMDiS/src/ITL_OEMSolver.hh          | 107 ++++++++++
 AMDiS/src/ITL_Preconditioner.h      |  73 +++----
 AMDiS/src/ITL_Solver.h              |   4 +-
 AMDiS/src/MTL4Solver.h              |  79 +++++++
 AMDiS/src/MTL4Types.h               |  12 ++
 AMDiS/src/Mapper.h                  |  78 +++++++
 AMDiS/src/MatrixStreams.h           | 141 ++++++++++++
 AMDiS/src/OEMSolver.h               | 170 ++++++++-------
 AMDiS/src/ProblemStat.cc            |   4 +-
 AMDiS/src/SolverMatrix.cc           |  15 ++
 AMDiS/src/SolverMatrix.h            |  46 ++--
 AMDiS/src/UmfPackSolver.h           | 112 +++++-----
 AMDiS/src/parallel/Mtl4Solver.cc    | 133 ++++++++++++
 AMDiS/src/parallel/Mtl4Solver.h     |  35 +--
 AMDiS/src/parallel/PITL_Solver.h    | 318 ++++++++++++++++++++++++++++
 AMDiS/src/parallel/ParallelMapper.h |  42 ++++
 26 files changed, 1351 insertions(+), 318 deletions(-)
 create mode 100644 AMDiS/src/BasePreconditioner.h
 create mode 100644 AMDiS/src/Collection.h
 create mode 100644 AMDiS/src/ITL_OEMSolver.hh
 create mode 100644 AMDiS/src/MTL4Solver.h
 create mode 100644 AMDiS/src/MTL4Types.h
 create mode 100644 AMDiS/src/Mapper.h
 create mode 100644 AMDiS/src/MatrixStreams.h
 create mode 100644 AMDiS/src/SolverMatrix.cc
 create mode 100644 AMDiS/src/parallel/Mtl4Solver.cc
 create mode 100644 AMDiS/src/parallel/PITL_Solver.h
 create mode 100644 AMDiS/src/parallel/ParallelMapper.h

diff --git a/AMDiS/AMDiSConfig.cmake.in b/AMDiS/AMDiSConfig.cmake.in
index 878394e9..113c0b97 100644
--- a/AMDiS/AMDiSConfig.cmake.in
+++ b/AMDiS/AMDiSConfig.cmake.in
@@ -61,6 +61,9 @@ set(AMDiS_NEED_UMFPACK @ENABLE_UMFPACK@)
 set(AMDiS_NEED_MKL @ENABLE_MKL@)
 set(AMDIS_USE_FILE ${AMDIS_DIR}/AMDiSUse.cmake)
 set(AMDiS_COMPILEFLAGS "@COMPILEFLAGS@")
+set(AMDIS_VERSION @CurrentRevision@)
+set(AMDIS_MAJOR_VERSION @AMDIS_MAJOR@)
+set(AMDIS_MINOR_VERSION @AMDIS_MINOR@)
 
 if(AMDiS_NEED_UMFPACK)
 	#look for umfpack, we need the headers only
diff --git a/AMDiS/AMDiSUse.cmake b/AMDiS/AMDiSUse.cmake
index f1b3c473..d5d664b7 100644
--- a/AMDiS/AMDiSUse.cmake
+++ b/AMDiS/AMDiSUse.cmake
@@ -12,13 +12,19 @@ if(AMDiS_HAS_PARALLEL_DOMAIN)
 	    list(APPEND AMDiS_COMPILEFLAGS ${MPI_COMPILE_FLAGS})
 	    list(APPEND AMDIS_INCLUDE_DIRS ${MPI_INCLUDE_PATH})
 	  endif(MPI_FOUND)
-	  set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${AMDIS_DIR})
-	  set(PETSC_EXECUTABLE_RUNS ON)
-	  find_package(PETSc REQUIRED)
-	  if(PETSC_FOUND)
+	  if(AMDiS_HAS_PARALLEL_DOMAIN STREQUAL "PETSC")
+	    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${AMDIS_DIR})
+	    set(PETSC_EXECUTABLE_RUNS ON)
+	    find_package(PETSc REQUIRED)
+	    if(PETSC_FOUND)
 	    list(APPEND AMDIS_LIBRARIES ${PETSC_LIBRARY_SYS} ${PETSC_LIBRARIES})
 	    list(APPEND AMDIS_INCLUDE_DIRS ${PETSC_INCLUDES})
-	  endif(PETSC_FOUND)
+	    endif(PETSc_FOUND)
+	  elseif(AMDiS_HAS_PARALLEL_DOMAIN STREQUAL "PMTL")
+	    find_package(MTL REQUIRED)
+	    list(APPEND AMDIS_LIBRARIES ${MTL_LIBRARIES})
+#	    set(AMDiS_COMPILEFLAGS "${AMDIS_COMPILEFLAGS} -DMTL_HAS_MPI -DHAVE_PARALLEL_MTL4")
+	  endif()
 	endif(NOT AMDiS_NEED_PARMETIS)
 endif(AMDiS_HAS_PARALLEL_DOMAIN)
 #thats bad because it affects each target
diff --git a/AMDiS/CMakeLists.txt b/AMDiS/CMakeLists.txt
index df04e933..bbf3e5f1 100644
--- a/AMDiS/CMakeLists.txt
+++ b/AMDiS/CMakeLists.txt
@@ -1,17 +1,31 @@
 project(AMDiS)
 
 cmake_minimum_required(VERSION 2.6)
-
-#needs: --enable-debug, enable-intel --enable-openmp --enable-parmetis --enable-parallel-domain --enable-umfpack --enable-mkl --enable-boost --enable-marmot
+#if revision is not set, let cmake look for the svn-version
+if( NOT CurrentRevision )
+	find_package(Subversion)
+	if(Subversion_FOUND)
+		Subversion_WC_INFO(${AMDiS_SOURCE_DIR} mtlSubinfo)
+		set(CurrentRevision "0.9${mtlSubinfo_WC_REVISION}")
+	#       message("current revision: ${mtlSubinfo_WC_REVISION}")
+	endif(Subversion_FOUND)
+endif( NOT CurrentRevision )
+#split the current revision in MAJOR.MINOR
+string(REGEX MATCH "([0-9]+).([0-9]+)" AMDIS_MAJOR "${CurrentRevision}" )
+set(AMDIS_MINOR ${CMAKE_MATCH_2})
+set(AMDIS_MAJOR ${CMAKE_MATCH_1})
+message("major: ${AMDIS_MAJOR}")
+message("minor: ${AMDIS_MINOR}")
 
 SET(LIB_DIR ${AMDiS_SOURCE_DIR}/lib)
 SET(SOURCE_DIR ${AMDiS_SOURCE_DIR}/src)
 
 #TODO: use the cmake build type
-SET(MTL_DIR ${LIB_DIR}/mtl4/ CACHE PATH "mtl4 directory")
+SET(MTL_INCLUDE_DIR ${LIB_DIR}/mtl4/ CACHE PATH "mtl4 directory")
 
 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -g -Wall -DDEBUG=0")
 set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -DDEBUG=1 -O0")
+set(COMPILEFLAGS "-DAMDIS_VERSION=${CurrentRevision}")
 
 #define the build type, empty can be everything and nothing
 if(CMAKE_BUILD_TYPE STREQUAL "")
@@ -19,13 +33,12 @@ if(CMAKE_BUILD_TYPE STREQUAL "")
 endif()
 
 #option(ENABLE_INTEL "use intel compiler" false)
-option(ENABLE_PARALLEL_DOMAIN "use parallel domain decomposition" false)
+SET(ENABLE_PARALLEL_DOMAIN "OFF" CACHE STRING "use parallel domain decomposition. please set to one of: PMTL, PETSC, OFF" )
 option(USE_PETSC_DEV false)
 #parmetis is not optional
 set(ENABLE_PARMETIS false)
 option(ENABLE_ZOLTAN false)
 option(ENABLE_UMFPACK "use umfpack solver" false)
-option(ENABLE_TESTS "compile the tests" false)
 
 if(ENABLE_INTEL)
 	Message("please set the icc manually")
@@ -37,14 +50,16 @@ endif(ENABLE_INTEL)
 
 find_package(Boost 1.42 REQUIRED)
 if(Boost_FOUND)
-  include_directories(${Boost_INCLUDE_DIR})
+#  include_directories(${Boost_INCLUDE_DIR})
+  list(APPEND AMDiS_INCLUDE_DIRS ${Boost_INCLUDE_DIR})
   message("boost lib-dirs: ${Boost_LIBRARY_DIRS}")
   message("use the boost dir: ${Boost_INCLUDE_DIR}")
   if(WIN32)
 	message("the windows find_boost does not set the boost library paths, please set it")
 	SET(Boost_LIBRARY_DIRS CACHE PATH "The directory containing the boost libraries")
-  endif(WIN32)		
-  link_directories(${Boost_LIBRARY_DIRS})
+  endif(WIN32)
+  list(APPEND AMDiS_LINK_DIRS ${Boost_LIBRARY_DIRS})
+#  link_directories(${Boost_LIBRARY_DIRS})
 endif(Boost_FOUND)
 
 SET(AMDIS_SRC ${SOURCE_DIR}/AdaptBase.cc
@@ -120,6 +135,7 @@ SET(AMDIS_SRC ${SOURCE_DIR}/AdaptBase.cc
 	      ${SOURCE_DIR}/SecondOrderTerm.cc
 	      ${SOURCE_DIR}/Serializer.cc
 	      ${SOURCE_DIR}/StandardProblemIteration.cc
+	      ${SOURCE_DIR}/SolverMatrix.cc
 	      ${SOURCE_DIR}/SubAssembler.cc
 	      ${SOURCE_DIR}/SubElInfo.cc
 	      ${SOURCE_DIR}/SubQuadrature.cc
@@ -154,10 +170,7 @@ SET(AMDIS_SRC ${SOURCE_DIR}/AdaptBase.cc
 if(ENABLE_PARALLEL_DOMAIN)
 	find_package(MPI REQUIRED)
 	if(MPI_FOUND)
-	  #INCLUDE (CMakeForceCompiler)	
-	  #CMAKE_FORCE_C_COMPILER(mpicc "MPI C compiler")
-	  #CMAKE_FORCE_CXX_COMPILER(mpiCC "MPI C++ compiler")
-	  list(APPEND AMDiS_COMPILEFLAGS ${MPI_COMPILE_FLAGS})
+	  list(APPEND COMPILEFLAGS "${MPI_COMPILE_FLAGS}")
 	  include_directories(${MPI_INCLUDE_PATH})
 	endif(MPI_FOUND)
  
@@ -165,7 +178,10 @@ if(ENABLE_PARALLEL_DOMAIN)
 			make
 			WORKING_DIRECTORY ${LIB_DIR}/ParMetis-3.1
 			)
-	include_directories( ${LIB_DIR}/ParMetis-3.1)
+#include_directories( ${LIB_DIR}/ParMetis-3.1)
+	list(APPEND AMDiS_INCLUDE_DIRS ${LIB_DIR}/ParMetis-3.1)
+	list(APPEND AMDiS_LIBS ${LIB_DIR}/ParMetis-3.1/libparmetis.a ${LIB_DIR}/ParMetis-3.1/libmetis.a)
+#	list(APPEND AMDiS_LINK_DIRS ${LIB_DIR}/ParMetis-3.1/)
         INSTALL(FILES ${LIB_DIR}/ParMetis-3.1/parmetis.h
 		${LIB_DIR}/ParMetis-3.1/libparmetis.a
 		${LIB_DIR}/ParMetis-3.1/libmetis.a
@@ -180,14 +196,12 @@ if(ENABLE_PARALLEL_DOMAIN)
 	  else()
 		message( FATAL_ERROR "could not find zoltan.")
 	  endif( ZOLTAN_HEADER_FILE )
-	  set(COMPILEFLAGS "${COMPILEFLAGS} -DHAVE_ZOLTAN")
+	  list(APPEND COMPILEFLAGS "-DHAVE_ZOLTAN")
 	endif(ENABLE_ZOLTAN)
 
-	set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};/usr/share/cmake-2.8/Modules/;${CMAKE_SOURCE_DIR}/")
-	set(PETSC_EXECUTABLE_RUNS ON)
-	find_package(PETSc REQUIRED)
-	include_directories(${PETSC_DIR}/include ${PETSC_DIR}/${PETSC_ARCH}/include)
+	list(APPEND COMPILEFLAGS "-DHAVE_PARALLEL_DOMAIN_AMDIS=1")
 	SET(PARALLEL_DOMAIN_AMDIS_SRC
+               	${SOURCE_DIR}/parallel/ParMetisPartitioner.cc
 		${SOURCE_DIR}/parallel/CheckerPartitioner.cc
 		${SOURCE_DIR}/parallel/ElementObjectData.cc
 		${SOURCE_DIR}/parallel/MeshDistributor.cc 
@@ -197,22 +211,41 @@ if(ENABLE_PARALLEL_DOMAIN)
 		${SOURCE_DIR}/parallel/ParallelDebug.cc
 		${SOURCE_DIR}/parallel/ParallelProblemStatBase.cc
                 ${SOURCE_DIR}/parallel/ParMetisPartitioner.cc
-		${SOURCE_DIR}/parallel/PetscProblemStat.cc
-		${SOURCE_DIR}/parallel/PetscSolver.cc
-		${SOURCE_DIR}/parallel/PetscSolverFeti.cc
-		${SOURCE_DIR}/parallel/PetscSolverGlobalMatrix.cc
-		${SOURCE_DIR}/parallel/PetscSolverSchur.cc
 		${SOURCE_DIR}/parallel/StdMpi.cc
 		${SOURCE_DIR}/parallel/ZoltanPartitioner.cc)
-	SET(COMPILEFLAGS "${COMPILEFLAGS} -DHAVE_PARALLEL_DOMAIN_AMDIS=1")
+		
+	if(ENABLE_PARALLEL_DOMAIN STREQUAL "PETSC")
+		set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};/usr/share/cmake-2.8/Modules/;${CMAKE_SOURCE_DIR}/")
+		set(PETSC_EXECUTABLE_RUNS ON)
+		find_package(PETSc REQUIRED)
+		include_directories(${PETSC_DIR}/include ${PETSC_DIR}/${PETSC_ARCH}/include)
+		list(APPEND AMDiS_INCLUDE_DIRS ${PETSC_DIR}/include ${PETSC_DIR}/${PETSC_ARCH}/include)
+		list(APPEND PARALLEL_DOMAIN_AMDIS_SRC ${SOURCE_DIR}/parallel/PetscSolver.cc
+			${SOURCE_DIR}/parallel/PetscProblemStat.cc
+			${SOURCE_DIR}/parallel/PetscSolverFeti.cc
+			${SOURCE_DIR}/parallel/PetscSolverGlobalMatrix.cc
+			${SOURCE_DIR}/parallel/PetscSolverSchur.cc)
+	elseif(ENABLE_PARALLEL_DOMAIN STREQUAL "PMTL")
+		set(MTL_INCLUDE_DIR "")
+		find_package(MTL REQUIRED)
+		list(APPEND COMPILEFLAGS "-DMTL_HAS_MPI" "-DHAVE_PARALLEL_MTL4")
+		list(APPEND PARALLEL_DOMAIN_AMDIS_SRC ${SOURCE_DIR}/parallel/Mtl4Solver.cc)
+		list(APPEND AMDiS_LIBS ${MTL_LIBRARIES})
+#message("using the parallel mtl4 version")
+
+	else()
+		message(SEND_ERROR "please set the domain-decomposition version correctly")
+	endif()
+
 	INSTALL(FILES ResolveCompilerPaths.cmake FindPackageMultipass.cmake FindPETSc.cmake
 		DESTINATION share/amdis/)
 	if( USE_PETSC_DEV )
-	  SET(COMPILEFLAGS "${COMPILEFLAGS} -DHAVE_PETSC_DEV")
+	  list(APPEND COMPILEFLAGS "-DHAVE_PETSC_DEV")
 	endif( USE_PETSC_DEV)
 endif(ENABLE_PARALLEL_DOMAIN)
 
 if(ENABLE_UMFPACK)
+
 #	include_directories(${LIB_DIR}/UFconfig ${LIB_DIR}/AMD/Include ${LIB_DIR}/UMFPACK/Include)
 #        FILE(GLOB UMFPACK_HEADERS "${LIB_DIR}/UMFPACK/Include/*.h")
 #	INSTALL(FILES ${UMFPACK_HEADERS} 
@@ -281,7 +314,7 @@ if(ENABLE_UMFPACK)
 	
 		#add the compileflags and directories
 		include_directories(${UMFPACK_PATH} ${UFCONFIG_PATH} ${AMD_PATH})
-		SET(COMPILEFLAGS "${COMPILEFLAGS} -DHAVE_UMFPACK=1 -DMTL_HAS_UMFPACK")
+		list(APPEND COMPILEFLAGS "-DHAVE_UMFPACK=1" "-DMTL_HAS_UMFPACK")
 	else()
 		message(FATAL_ERROR "Could not find the umfpack-headers. Please install umfpack")
 	endif()
@@ -304,20 +337,25 @@ file(GLOB REINIT_SRC ${REINIT_SOURCE_DIR}/*.cc)
 include_directories(${REINIT_SOURCE_DIR})
 
 #mtl4 includes
-include_directories(${MTL_DIR})
-include_directories(${SOURCE_DIR})
+list(APPEND AMDiS_INCLUDE_DIRS ${MTL_INCLUDE_DIR})
+#include_directories(${MTL_INCLUDE_DIR})
+list(APPEND AMDiS_INCLUDE_DIRS ${SOURCE_DIR})
+#include_directories(${SOURCE_DIR})
+include_directories(${AMDiS_INCLUDE_DIRS})
 
 add_library(amdis SHARED ${AMDIS_SRC} ${PARALLEL_DOMAIN_AMDIS_SRC})
 add_library(compositeFEM SHARED ${COMPOSITE_FEM_SRC})
 add_library(reinit STATIC ${REINIT_SRC})
 target_link_libraries(compositeFEM amdis)
+list(APPEND AMDiS_LIBS amdis ${Boost_LIBRARIES})
 
 if(WIN32)
-	SET(COMPILEFLAGS "${COMPILEFLAGS} -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS")
+	list(APPEND COMPILEFLAGS "-D_SCL_SECURE_NO_WARNINGS" "-D_CRT_SECURE_NO_WARNINGS")
 endif(WIN32)
 message("compileflags: ${COMPILEFLAGS}")
 #SET_TARGET_PROPERTIES(amdis PROPERTIES COMPILE_FLAGS "${COMPILEFLAGS}")
 add_definitions(${COMPILEFLAGS})
+
 if(ENABLE_MARMOT)
 	Message("please set marmotcc manually")
 endif(ENABLE_MARMOT)
@@ -391,15 +429,6 @@ endforeach(mtl4_file)
 list(REMOVE_DUPLICATES deb_add_dirs)
 
 #PACKAGES
-#let cmake look for the svn-version
-if( NOT CurrentRevision )
-	find_package(Subversion)
-	if(Subversion_FOUND)
-		Subversion_WC_INFO(${AMDiS_SOURCE_DIR} mtlSubinfo)
-		set(CurrentRevision "0.9.${mtlSubinfo_WC_REVISION}")
-	#       message("current revision: ${mtlSubinfo_WC_REVISION}")
-	endif(Subversion_FOUND)
-endif( NOT CurrentRevision )
 set(CPACK_PACKAGE_NAME "AMDiS")
 set(CPACK_PACKAGE_CONTACT "Andreas.Naumann@tu-dresden.de")
 set(CPACK_PACKAGE_VERSION "${CurrentRevision}")
@@ -418,7 +447,3 @@ set(CPACK_DEBIAN_PACKAGE_DEPENDS "libboost-dev (>= 1.42), libboost-iostreams-dev
 set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${AMDiS_BINARY_DIR}/preinst" "${AMDiS_BINARY_DIR}/postrm")
 
 include(CPack)
-if(ENABLE_TESTS)
-ENABLE_TESTING()
-add_subdirectory(test)
-endif(ENABLE_TESTS)
diff --git a/AMDiS/src/AMDiS.h b/AMDiS/src/AMDiS.h
index 6b052c5e..a3392147 100644
--- a/AMDiS/src/AMDiS.h
+++ b/AMDiS/src/AMDiS.h
@@ -23,6 +23,8 @@
 #ifndef AMDIS_H
 #define AMDIS_H
 
+#include "stdint.h"
+#include "MTL4Types.h"
 #include "AbstractFunction.h"
 #include "AdaptInfo.h"
 #include "AdaptInstationary.h"
diff --git a/AMDiS/src/AMDiS_fwd.h b/AMDiS/src/AMDiS_fwd.h
index 266bf613..a1070295 100644
--- a/AMDiS/src/AMDiS_fwd.h
+++ b/AMDiS/src/AMDiS_fwd.h
@@ -53,7 +53,6 @@ namespace AMDiS {
   class Flag;
   class IdentityPreconditioner; 
   class InteriorBoundary;
-  class ITL_BasePreconditioner;
   class LeafDataPeriodic;
   class LevelAdmin;
   class Line;
@@ -120,7 +119,7 @@ namespace AMDiS {
   template<typename T>                                 class DimVec;
   template<typename T>                                 class DimMat;
   template<typename ITLSolver>                         class ITL_OEMSolver;
-  template<typename T>                                 class ITL_Preconditioner;
+  template<typename T, typename Vec, typename Mat >    class ITL_Preconditioner;
   template<typename T>                                 class Matrix;
   template<typename T>                                 class MatrixOfFixVecs;
   template<typename T>                                 class MatVecMultiplier;
diff --git a/AMDiS/src/BasePreconditioner.h b/AMDiS/src/BasePreconditioner.h
new file mode 100644
index 00000000..0161895c
--- /dev/null
+++ b/AMDiS/src/BasePreconditioner.h
@@ -0,0 +1,46 @@
+#ifndef BASEPRECONDITIONER_H
+#define BASEPRECONDITIONER_H
+
+#include <stdexcept>
+#include "CreatorInterface.h"
+#include "ITL_Preconditioner.h"
+#include "Collection.h"
+
+namespace AMDiS {
+
+  template< typename Vector >
+  struct CreatorInterface< ITL_BasePreconditioner< Vector > > {
+    typedef typename AMDiS::Collection< Vector >::PreconditionMatrix PreconditionMatrix;
+    virtual ITL_BasePreconditioner< Vector >* create(const PreconditionMatrix& )=0 /*{ return NULL; }*/ ;
+  };
+
+  template< typename Vector >
+  class NullCreator< ITL_BasePreconditioner< Vector > > : 
+    public CreatorInterface< ITL_BasePreconditioner< Vector > >
+  {
+    typedef typename AMDiS::Collection< Vector >::PreconditionMatrix PreconditionMatrix;
+    typedef ITL_BasePreconditioner< Vector > BaseClass;
+    /// Creates no object.
+    BaseClass* create() 
+    {
+      TEST_EXIT(false)("should never class this function");
+      return NULL; 
+    }
+
+    BaseClass* create(const PreconditionMatrix& ) {
+      TEST_EXIT(false)("this is the wrong null creator\n");
+      return NULL;
+    }
+    ///
+    virtual bool isNullCreator() 
+    { 
+      return true; 
+    }
+  };
+
+  typedef CreatorInterface< ITL_BasePreconditioner< MTLTypes::MTLVector > > PreconditionCreator;
+  typedef ITL_BasePreconditioner< MTLTypes::MTLVector > BasePreconditioner;
+
+}
+
+#endif
diff --git a/AMDiS/src/Collection.h b/AMDiS/src/Collection.h
new file mode 100644
index 00000000..4e2c5c1b
--- /dev/null
+++ b/AMDiS/src/Collection.h
@@ -0,0 +1,41 @@
+// ============================================================================
+// ==                                                                        ==
+// == AMDiS - Adaptive multidimensional simulations                          ==
+// ==                                                                        ==
+// ============================================================================
+// ==                                                                        ==
+// ==  TU Dresden                                                            ==
+// ==                                                                        ==
+// ==  Institut für Wissenschaftliches Rechnen                               ==
+// ==  Zellescher Weg 12-14                                                  ==
+// ==  01069 Dresden                                                         ==
+// ==  germany                                                               ==
+// ==                                                                        ==
+// ============================================================================
+// ==                                                                        ==
+// ==  https://gforge.zih.tu-dresden.de/projects/amdis/                      ==
+// ==                                                                        ==
+// ============================================================================
+
+#ifndef AMDIS_COLLECTION_H
+#define AMDIS_COLLECTION_H
+
+#include "MTL4Types.h"
+
+namespace AMDiS {
+  template< typename T >
+  struct Collection {};
+
+  using namespace MTLTypes;
+  template< >
+    struct Collection< MTLMatrix > {
+      typedef mtl::matrix::inserter< MTLMatrix > Inserter;
+    };
+
+  template< >
+    struct Collection< MTLVector > {
+      typedef mtl::vector::inserter< MTLVector > Inserter;
+      typedef MTLMatrix PreconditionMatrix;
+    };
+}
+#endif
diff --git a/AMDiS/src/CreatorMap.cc b/AMDiS/src/CreatorMap.cc
index f9e43459..70091af4 100644
--- a/AMDiS/src/CreatorMap.cc
+++ b/AMDiS/src/CreatorMap.cc
@@ -11,6 +11,7 @@
 
 
 #include "CreatorMap.h"
+#include "MTL4Types.h"
 #include "OEMSolver.h"
 #include "ITL_Solver.h"
 #include "ITL_Preconditioner.h"
@@ -74,9 +75,9 @@ namespace AMDiS {
 
 
   template<>
-  void CreatorMap<ITL_BasePreconditioner>::addDefaultCreators()
+  void CreatorMap<BasePreconditioner>::addDefaultCreators()
   {
-    CreatorInterface<ITL_BasePreconditioner> *creator;
+    PreconditionCreator *creator;
 
     creator =  new DiagonalPreconditioner::Creator;
     addCreator("diag", creator);
diff --git a/AMDiS/src/Global.h b/AMDiS/src/Global.h
index 63e4d733..8e1bd8a2 100644
--- a/AMDiS/src/Global.h
+++ b/AMDiS/src/Global.h
@@ -37,7 +37,9 @@
 #endif
 
 /** \brief current AMDiS version */
-#define AMDIS_VERSION  "AMDiS: Version 0.100"
+#ifndef AMDIS_VERSION
+#define AMDIS_VERSION  "AMDiS: Version 0.9.1"
+#endif
 
 #include <string>
 #include <vector>
diff --git a/AMDiS/src/ITL_OEMSolver.h b/AMDiS/src/ITL_OEMSolver.h
index 7af26e23..6889a75e 100644
--- a/AMDiS/src/ITL_OEMSolver.h
+++ b/AMDiS/src/ITL_OEMSolver.h
@@ -24,55 +24,36 @@
 #ifndef AMDIS_ITL_OEM_SOLVER_H
 #define AMDIS_ITL_OEM_SOLVER_H
 
-#include <iostream>
-#include "OEMSolver.h"
-#include "ITL_Preconditioner.h"
-#include "SolverMatrix.h"
-#include "DOFVector.h"
-#include "SystemVector.h"
-#include "DOFMatrix.h"
-#include "Parameters.h"
+#include "MTL4Solver.h"
+#include "ITL_OEMSolver.hh"
+#include "MTL4Types.h"
 
 #include <boost/numeric/itl/itl.hpp>
 #include <boost/numeric/mtl/mtl.hpp>
 
 namespace AMDiS {
 
-  
   /**
    * \ingroup Solver
    * 
    *\brief
-   * Template for using solvers from ITL in AMDiS. 
+   * Template for using solvers from ITL in AMDiS.
+   * Uses a previous definition of MTLMatrix and MTLVector.
+   * Additional template generalization of ITL_OEMSolver destroys class hierarchy 
    */
+
   template <typename ITLSolver>
-  class ITL_OEMSolver : public OEMSolver
-  {
-    typedef ITL_Preconditioner<itl::pc::identity<DOFMatrix> > id_t;
+  class ITL_OEMSolver : public MTL4Solver< MTLTypes::MTLMatrix, MTLTypes::MTLVector, ITL_OEMSolver_runner< ITLSolver > >  {
 
-  public:
+    protected:
+    public:
     /// The constructor reads needed parameters and sets solvers \ref name.
-    ITL_OEMSolver(std::string name) : OEMSolver(name)  {}
+    ITL_OEMSolver(std::string name) : 
+	    MTL4Solver< MTLTypes::MTLMatrix, MTLTypes::MTLVector, ITL_OEMSolver_runner< ITLSolver > >(name)  {}
+
   
     ~ITL_OEMSolver() {}
 
-
-    /// Solves the system iteratively
-    // This function is virtual because derived class calls solver with parameter
-    virtual int solveSystem(const DOFMatrix::base_matrix_type&      A,
-			    mtl::dense_vector<value_type>&          x,
-			    const mtl::dense_vector<value_type>&    b)
-    {
-      itl::cyclic_iteration<value_type> iter(b, this->max_iter, this->relative, 
-					     this->tolerance, this->print_cycle);
-
-      error = ITLSolver()(A, x, b, *this->leftPrecon, *this->rightPrecon, iter);
-      iterations = iter.iterations();
-      residual = iter.resid();
-      return error;
-    }
-
-
     /// Creator class used in the OEMSolverMap.
     class Creator : public OEMSolverCreator
     {
@@ -88,7 +69,6 @@ namespace AMDiS {
   
   };
 
-
   /**
    * \ingroup Solver
    * 
@@ -97,34 +77,19 @@ namespace AMDiS {
    */
   template <typename ITLSolver>
   class ITL_OEMSolver_para
-      : public OEMSolver // ITL_OEMSolver<ITLSolver>
+      : public MTL4Solver< MTLMatrix, MTLVector, ITL_OEMSolver_para_runner< ITLSolver > > // ITL_OEMSolver<ITLSolver>
   {
-      typedef DOFMatrix::value_type value_type;
   public:
       /// The constructor reads needed parameters and sets solvers \ref name.
       ITL_OEMSolver_para(std::string name) 
-	  : OEMSolver(name), ell(OEMSolver::max_iter) 
+	  : MTL4Solver< MTLMatrix, MTLVector, ITL_OEMSolver_para_runner< ITLSolver > >(name) 
       {
-	Parameters::get(name + "->ell", ell);
+
       }
       
       ~ITL_OEMSolver_para() {}
 
       /// Set parameter of iterative solver
-    void setEll(int p) { ell= p; }
-
-    /// Solves the system iteratively
-    int solveSystem(const DOFMatrix::base_matrix_type&      A,
-		    mtl::dense_vector<value_type>&          x,
-		    const mtl::dense_vector<value_type>&    b)
-    {
-	itl::cyclic_iteration<value_type> iter(b, this->max_iter, this->relative, 
-					       this->tolerance, this->print_cycle);
-	error = ITLSolver()(A, x, b, *this->leftPrecon, *this->rightPrecon, iter, ell);
-	iterations = iter.iterations();
-	residual = iter.resid();
-	return error;
-    }
 
     class Creator : public OEMSolverCreator
     {
@@ -139,11 +104,7 @@ namespace AMDiS {
     }; 
       
   private:
-    /// parameter for bicgstab_ell iterative solver    
-    int ell;
   };
-
-
 } // namespace AMDiS
 
 #endif // AMDIS_ITL_OEM_SOLVER_H
diff --git a/AMDiS/src/ITL_OEMSolver.hh b/AMDiS/src/ITL_OEMSolver.hh
new file mode 100644
index 00000000..248584d3
--- /dev/null
+++ b/AMDiS/src/ITL_OEMSolver.hh
@@ -0,0 +1,107 @@
+#include "ITL_Preconditioner.h"
+
+namespace AMDiS {
+  template< typename Vector >
+  struct PreconPair { 
+    /// Pointer to the left preconditioner
+    ITL_BasePreconditioner< Vector >* l;
+
+    /// Pointer to the right preconditioner
+    ITL_BasePreconditioner< Vector >* r;
+    PreconPair():
+	    l(NULL), r(NULL)
+	  {}
+
+  };
+
+  struct BaseITL_runner { 
+    OEMSolver& oem;
+    BaseITL_runner(OEMSolver* oemPtr):
+	    oem(*oemPtr)
+    {
+      TEST_EXIT(oemPtr != NULL)("need a real oemsolver\n");
+    }
+
+    template< typename Vector , typename Matrix >
+      void setPrecon(PreconPair< Vector >& pair, const Matrix& matrix)
+      {
+	/// Creator for the left preconditioner
+	CreatorInterface< ITL_BasePreconditioner< Vector > >* leftCreator(NULL);
+
+	/// Creator for the right preconditioner
+	CreatorInterface< ITL_BasePreconditioner< Vector > >* rightCreator(NULL);
+
+	std::string preconType("no");
+	Parameters::get(oem.getName() + "->left precon", preconType);
+
+	leftCreator = CreatorMap<ITL_BasePreconditioner< Vector > >::getCreator(preconType);
+	TEST_EXIT(leftCreator != NULL)
+		("there is no creator for the given left preconditioner");
+
+	preconType = "no";
+	Parameters::get(oem.getName() + "->right precon", preconType);
+	rightCreator = CreatorMap<ITL_BasePreconditioner< Vector > >::getCreator(preconType);
+	TEST_EXIT(rightCreator != NULL)
+		("there is no creator for the given right preconditioner");
+
+	pair.l = leftCreator->create(matrix);
+	pair.r = rightCreator->create(matrix);
+      }
+  };
+
+  template< typename ITLSolver >
+  struct ITL_OEMSolver_para_runner : BaseITL_runner {
+    ITL_OEMSolver_para_runner(OEMSolver* oem_):
+	      BaseITL_runner(oem_),
+	      ell(1)
+    {
+      ell=oem.getMaxIterations();
+      Parameters::get(oem.getName() + "->ell", ell);
+    }
+
+    template< typename Matrix, typename Vector>
+    int solve(const Matrix& A, Vector& x, Vector& b) 
+    {
+      itl::cyclic_iteration<typename Matrix::value_type> iter(b, oem.getMaxIterations(), oem.getRelative(), 
+					     oem.getTolerance(), oem.getPrint_cycle());
+
+      static PreconPair< Vector > preconPair;
+      if (preconPair.l == NULL || preconPair.r == NULL || !oem.getMultipleRhs())
+	     BaseITL_runner::setPrecon(preconPair, A); 
+
+      int error = ITLSolver()(A, x, b, *(preconPair.l), *(preconPair.r), iter, ell);
+      oem.setIterations(iter.iterations());
+      oem.setResidual(iter.resid());
+      oem.setErrorCode(error);
+      return error;
+    }
+    private:
+    int ell;
+  };
+
+  template< typename ITLSolver >
+  struct ITL_OEMSolver_runner : BaseITL_runner {
+   
+   
+    ITL_OEMSolver_runner(OEMSolver* oem):
+	    BaseITL_runner(oem)
+    {}
+
+    template< typename Matrix, typename Vector>
+    int solve(const Matrix& A, Vector& x, Vector& b) 
+    {
+      itl::cyclic_iteration<typename Matrix::value_type> iter(b, oem.getMaxIterations(), oem.getRelative(), 
+					     oem.getTolerance(), oem.getPrint_cycle());
+
+      static PreconPair< Vector > preconPair;
+      if (preconPair.l == NULL || preconPair.r == NULL || !oem.getMultipleRhs())
+	     BaseITL_runner::setPrecon(preconPair, A); 
+
+      int error = ITLSolver()(A, x, b, *(preconPair.l), *(preconPair.r), iter);
+      oem.setErrorCode(error);
+      oem.setIterations(iter.iterations());
+      oem.setResidual(iter.resid());
+      return error;
+    }
+  };
+}
diff --git a/AMDiS/src/ITL_Preconditioner.h b/AMDiS/src/ITL_Preconditioner.h
index d62f87f5..39a30f8d 100644
--- a/AMDiS/src/ITL_Preconditioner.h
+++ b/AMDiS/src/ITL_Preconditioner.h
@@ -23,6 +23,7 @@
 #ifndef AMDIS_ITL_PRECONDITIONER_H
 #define AMDIS_ITL_PRECONDITIONER_H
 
+#include "MTL4Types.h"
 #include "DOFMatrix.h"
 #include "CreatorInterface.h"
 
@@ -42,58 +43,56 @@ namespace AMDiS {
    * 
    * \brief Common base class for wrappers to use ITL preconditioners in AMDiS.
    */
+  template< class Vec >
   class ITL_BasePreconditioner 
   {
   public:
-      typedef DOFMatrix::value_type value_type;
-
       virtual ~ITL_BasePreconditioner() {}
 
-      virtual mtl::dense_vector<value_type>
-      member_solve(const mtl::dense_vector<value_type>& vin) const = 0;
+      virtual Vec member_solve(const Vec& vin) const =0 ;
 
-      virtual mtl::dense_vector<value_type>
-      member_adjoint_solve(const mtl::dense_vector<value_type>& vin) const = 0;
+      virtual Vec member_adjoint_solve(const Vec& vin) const =0 ;
   };
 
-    inline mtl::dense_vector<DOFMatrix::value_type>
-    solve(const ITL_BasePreconditioner& P, const mtl::dense_vector<DOFMatrix::value_type>& vin)
-    {
-	return P.member_solve(vin);
-    }
+  template< typename Vec >
+  inline Vec
+  solve(const ITL_BasePreconditioner< Vec >& P, const Vec& vin)
+  {
+    return P.member_solve(vin);
+  }
 
-    inline mtl::dense_vector<DOFMatrix::value_type>
-    adjoint_solve(const ITL_BasePreconditioner& P, const mtl::dense_vector<DOFMatrix::value_type>& vin)
-    {
-	return P.member_adjoint_solve(vin);
-    }
+  template< typename Vec >
+  inline Vec
+  adjoint_solve(const ITL_BasePreconditioner< Vec >& P, const Vec& vin)
+  {
+    return P.member_adjoint_solve(vin);
+  }
 
   /**
    * \ingroup Solver
    * 
    * \brief Wrapper for using ITL preconditioners in AMDiS.
    */
-  template <typename Preconditioner>
-  class ITL_Preconditioner : public ITL_BasePreconditioner
+  template <typename Preconditioner, typename MTLVector, typename MTLMatrix >
+  class ITL_Preconditioner : public ITL_BasePreconditioner< MTLVector >
   {
-    typedef DOFMatrix::value_type value_type;
   public:
-    ITL_Preconditioner(const DOFMatrix::base_matrix_type& A) : precon(A) {}
+    ITL_Preconditioner(const MTLMatrix& A) : precon(A) {}
    
-    mtl::dense_vector<value_type>
-    member_solve(const mtl::dense_vector<value_type>& vin) const
+    MTLVector
+    member_solve(const MTLVector& vin) const
     {
       return solve(precon, vin);
     }
 
-    mtl::dense_vector<value_type>
-    member_adjoint_solve(const mtl::dense_vector<value_type>& vin) const
+    MTLVector
+    member_adjoint_solve(const MTLVector& vin) const
     {
       return adjoint_solve(precon, vin);
     }
 
     /// Creator class used in the OEMSolverMap.
-    class Creator : public CreatorInterface<ITL_BasePreconditioner>
+    class Creator : public CreatorInterface< ITL_BasePreconditioner< MTLVector > >
     {
     public:
       virtual ~Creator() {}
@@ -101,12 +100,8 @@ namespace AMDiS {
       /** \brief
        * Creates an ITL preconditioner
        */
-      ITL_BasePreconditioner *create(const DOFMatrix::base_matrix_type& A) { 
-	return new ITL_Preconditioner<Preconditioner>(A);
-      }
-
-      ITL_BasePreconditioner *create() {
-	ERROR_EXIT("Must not be called! Only defined to avoid abstract function."); return 0;
+      ITL_BasePreconditioner< MTLVector >* create(const MTLMatrix& A) { 
+	return new ITL_Preconditioner<Preconditioner, MTLVector, MTLMatrix>(A);
       }
     };
 
@@ -126,12 +121,12 @@ namespace AMDiS {
    * Diagonal preconditioner. 
    */
   class DiagonalPreconditioner 
-    : public ITL_Preconditioner<itl::pc::diagonal<DOFMatrix::base_matrix_type> >
+    : public ITL_Preconditioner<itl::pc::diagonal<DOFMatrix::base_matrix_type>, MTLTypes::MTLVector, MTLTypes::MTLMatrix >
   {
-    typedef ITL_Preconditioner<itl::pc::diagonal<DOFMatrix::base_matrix_type> > base;
+    typedef ITL_Preconditioner<itl::pc::diagonal<DOFMatrix::base_matrix_type>, MTLTypes::MTLVector, MTLTypes::MTLMatrix > base;
 
   public:
-    DiagonalPreconditioner(const DOFMatrix::base_matrix_type& A) : base(A) {}
+    DiagonalPreconditioner(const MTLTypes::MTLMatrix& A) : base(A) {}
   };
 
   /**
@@ -141,12 +136,12 @@ namespace AMDiS {
    * Identity preconditioner. Behaves like no preconditioning.
    */
   class IdentityPreconditioner 
-    : public ITL_Preconditioner<itl::pc::identity<DOFMatrix::base_matrix_type> >
+    : public ITL_Preconditioner<itl::pc::identity<DOFMatrix::base_matrix_type>, MTLTypes::MTLVector, MTLTypes::MTLMatrix >
   {
-    typedef ITL_Preconditioner<itl::pc::identity<DOFMatrix::base_matrix_type> > base;
+    typedef ITL_Preconditioner<itl::pc::identity<DOFMatrix::base_matrix_type>, MTLTypes::MTLVector, MTLTypes::MTLMatrix > base;
 
   public:
-      IdentityPreconditioner(const DOFMatrix::base_matrix_type& A) : base(A) {}
+      IdentityPreconditioner(const MTLTypes::MTLMatrix& A) : base(A) {}
   };
 
 
@@ -165,11 +160,11 @@ namespace AMDiS {
    * described in chapter 10.3 (algorithm 10.4).
    */
   class ILUPreconditioner 
-      : public ITL_Preconditioner< itl::pc::ilu_0<DOFMatrix::base_matrix_type> >
+      : public ITL_Preconditioner< itl::pc::ilu_0<DOFMatrix::base_matrix_type>, MTLTypes::MTLVector, MTLTypes::MTLMatrix >
   {};
 
   class ICPreconditioner 
-      : public ITL_Preconditioner< itl::pc::ic_0<DOFMatrix::base_matrix_type> >
+      : public ITL_Preconditioner< itl::pc::ic_0<DOFMatrix::base_matrix_type>, MTLTypes::MTLVector, MTLTypes::MTLMatrix >
   {};
 
 
diff --git a/AMDiS/src/ITL_Solver.h b/AMDiS/src/ITL_Solver.h
index 787903da..9b283fbb 100644
--- a/AMDiS/src/ITL_Solver.h
+++ b/AMDiS/src/ITL_Solver.h
@@ -16,9 +16,7 @@
 //
 // See also license.opensource.txt in the distribution.
 
-
-
-/** \file ITL_Preconditioner.h */
+/** \file ITL_Solver.h */
 
 #ifndef AMDIS_ITL_SOLVER_H
 #define AMDIS_ITL_SOLVER_H
diff --git a/AMDiS/src/MTL4Solver.h b/AMDiS/src/MTL4Solver.h
new file mode 100644
index 00000000..b6ba1907
--- /dev/null
+++ b/AMDiS/src/MTL4Solver.h
@@ -0,0 +1,79 @@
+// ============================================================================
+// ==                                                                        ==
+// == AMDiS - Adaptive multidimensional simulations                          ==
+// ==                                                                        ==
+// ============================================================================
+// ==                                                                        ==
+// ==  TU Dresden                                                            ==
+// ==                                                                        ==
+// ==  Institut für Wissenschaftliches Rechnen                               ==
+// ==  Zellescher Weg 12-14                                                  ==
+// ==  01069 Dresden                                                         ==
+// ==  germany                                                               ==
+// ==                                                                        ==
+// ============================================================================
+// ==                                                                        ==
+// ==  https://gforge.zih.tu-dresden.de/projects/amdis/                      ==
+// ==                                                                        ==
+// ============================================================================
+
+#ifndef MTL4SOLVER_H
+#define MTL4SOLVER_H
+
+#include "OEMSolver.h"
+#include "MatrixStreams.h"
+#include <iostream>
+
+namespace AMDiS {
+  template< typename MTLMatrix, typename MTLVector, typename Worker >
+  class MTL4Solver : public OEMSolver {
+
+    protected:
+
+      Worker worker;
+
+      template< typename Matrix, typename Vector, typename Mapper >
+      int solve(const Matrix& A, Vector& x, Vector& b, Mapper& mapper) 
+      {
+	 MTLMatrix matrix(mapper.nRow(), mapper.nCol());
+	 set_to_zero(matrix);
+	 MatMap< const Matrix, Mapper > matMap(A,mapper);
+	 matrix << matMap;
+
+         MTLVector mtl_x(mapper.nRow());
+	 set_to_zero(mtl_x);
+	 VecMap< Vector, Mapper > xVecMap(x, mapper);
+	 mtl_x << xVecMap;
+
+	 MTLVector mtl_b(mapper.nRow());
+	 set_to_zero(mtl_b);
+	 VecMap< Vector, Mapper> bVecMap(b, mapper);
+	 mtl_b << bVecMap;
+
+	 error = worker.solve(matrix, mtl_x, mtl_b);
+
+	 mtl_x >> xVecMap;
+	 return error;
+      }
+
+    public:
+      MTL4Solver(std::string n):
+	OEMSolver(n),
+        worker(this)
+      {
+	FUNCNAME("MTL4Solver()");
+
+      }
+
+      virtual int solveSystem(const SolverMatrix<Matrix<DOFMatrix*> >& A,
+			    SystemVector& x, 
+			    SystemVector& b,
+			    VectorialMapper& m)
+      {
+	return solve(A,x,b,m);
+      }
+
+      
+  };
+}
+#endif
diff --git a/AMDiS/src/MTL4Types.h b/AMDiS/src/MTL4Types.h
new file mode 100644
index 00000000..be018fd1
--- /dev/null
+++ b/AMDiS/src/MTL4Types.h
@@ -0,0 +1,12 @@
+#ifndef MTL4TYPES_H
+#define MTL4TYPES_H
+#include <boost/numeric/mtl/mtl.hpp>
+namespace AMDiS {
+  namespace MTLTypes {
+  typedef double value_type;
+  typedef mtl::matrix::compressed2D< value_type > MTLMatrix;
+  typedef mtl::vector::dense_vector< value_type > MTLVector;
+  }
+}
+#endif
+
diff --git a/AMDiS/src/Mapper.h b/AMDiS/src/Mapper.h
new file mode 100644
index 00000000..e16230ce
--- /dev/null
+++ b/AMDiS/src/Mapper.h
@@ -0,0 +1,78 @@
+#ifndef MAPPER_H
+#define MAPPER_H
+
+#include "SolverMatrix.h"
+#include <vector>
+namespace AMDiS {
+/*  struct ScalarMapper {
+    ScalarMapper(int nrow, int ncol):
+      nrow(nrow), ncol(ncol) {}
+    inline int row(int r) { return r; }
+    inline int col(int c) { return c; }
+    inline int nRow() { return nrow; }
+    inline int nCol() { return ncol; }
+  protected:
+    int nrow;
+    int ncol;
+  };
+*/
+  struct VectorialMapper 
+  {
+
+    VectorialMapper(const SolverMatrix<Matrix<DOFMatrix* > >& sm ) :
+      nComp(sm.getOriginalMat()->getSize()), 
+      rowOffset(0), colOffset(0), nrow(0), ncol(0), sizes(nComp)
+    {
+      const Matrix<DOFMatrix* >& orMat(*sm.getOriginalMat());
+      const int ns = orMat.getSize();
+      for (int i= 0; i < ns; i++) {
+	sizes[i] = orMat[i][i]->getFeSpace()->getAdmin()->getUsedSize();
+	nrow += sizes[i];
+      }
+      ncol = nrow;
+    }
+
+    VectorialMapper(unsigned int nComp, int nDOFperComp) :
+      nComp(nComp), rowOffset(0), colOffset(0), 
+      nrow(nComp*nDOFperComp), ncol(nrow),sizes(nComp)
+    {
+       for (unsigned int i(0); i < nComp; ++i)
+         sizes[i] = nDOFperComp;
+    }
+      
+    inline void setRow( unsigned int r) { 
+	    assert( r <= sizes.size() );
+	    rowOffset = sum( r); 
+    }
+
+    inline void setCol( unsigned int c) { colOffset = sum( c); }
+
+    inline int row(int r) const { return r + rowOffset; }
+
+    inline int col(int c) const { return c + colOffset; }
+
+    inline int nCol() const { return ncol; }
+
+    inline int nRow() const { return nrow; }
+
+  protected:
+
+    ///compute the sum of sizes from [0, end)
+    inline unsigned int sum(unsigned int end) const 
+    {
+      unsigned int ret(0);
+      for (unsigned int i(0); i < end; ++i)
+	ret += sizes[i];
+      return ret;
+    }
+
+    int nComp;
+    int rowOffset;
+    int colOffset;
+    int nrow;
+    int ncol;
+    std::vector< unsigned int > sizes;
+  };
+}
+
+#endif
diff --git a/AMDiS/src/MatrixStreams.h b/AMDiS/src/MatrixStreams.h
new file mode 100644
index 00000000..98ccbcab
--- /dev/null
+++ b/AMDiS/src/MatrixStreams.h
@@ -0,0 +1,141 @@
+// ============================================================================
+// ==                                                                        ==
+// == AMDiS - Adaptive multidimensional simulations                          ==
+// ==                                                                        ==
+// ============================================================================
+// ==                                                                        ==
+// ==  TU Dresden                                                            ==
+// ==                                                                        ==
+// ==  Institut für Wissenschaftliches Rechnen                               ==
+// ==  Zellescher Weg 12-14                                                  ==
+// ==  01069 Dresden                                                         ==
+// ==  germany                                                               ==
+// ==                                                                        ==
+// ============================================================================
+// ==                                                                        ==
+// ==  https://gforge.zih.tu-dresden.de/projects/amdis/                      ==
+// ==                                                                        ==
+// ============================================================================
+
+/** \file MatrixStreams.h */
+
+#ifndef MATRIXSTREAMS_H
+#define MATRIXSTREAMS_H
+
+#include "DOFMatrix.h"
+#include "SolverMatrix.h"
+#include "SystemVector.h"
+#include "Collection.h"
+
+using namespace mtl::operations;
+namespace AMDiS {
+  template< typename VecT, typename CurMap>
+  struct VecMap {
+    VecT& vec;
+    CurMap& mapper;
+    VecMap(VecT& vec, CurMap& mapper):
+      vec(vec),mapper(mapper) {}
+  };
+
+  template< typename MatT, typename CurMap>
+  struct MatMap {
+    MatT& mat;
+    CurMap& mapper;
+    MatMap(MatT& mat, CurMap& m):
+      mat(mat), mapper(m) {}
+  };
+
+  template< typename MTLMatrix, typename Mapper >
+  void operator<<(MTLMatrix& matrix, MatMap<const SolverMatrix<Matrix<DOFMatrix* > >, Mapper >& Asolver)
+  {
+    const Matrix< DOFMatrix* >& A = *(Asolver.mat.getOriginalMat());
+    int ns = A.getSize();
+
+    Mapper& mapper(Asolver.mapper);
+    set_to_zero(matrix);
+
+    int nnz = 0;
+    for (int rb = 0; rb < ns; ++rb)
+      for (int cb = 0; cb < ns; ++cb)
+        if (A[rb][cb])
+	  nnz += A[rb][cb]->getBaseMatrix().nnz();	  
+      
+    {
+      typedef mtl::matrix::mapped_inserter< typename Collection< MTLMatrix >::Inserter, Mapper > Inserter;
+      Inserter ins(matrix, mapper, int(1.2 * nnz / matrix.dim1()));
+      for (int rb = 0; rb < ns; ++rb) {
+        mapper.setRow(rb);
+        for (int cb = 0; cb < ns; ++cb) {
+	  mapper.setCol(cb);
+          if (A[rb][cb])
+	    ins << A[rb][cb]->getBaseMatrix();
+        }
+      }
+    }
+  }
+
+  template< typename Vector, typename CurMap >
+  void operator<<(Vector& dest, VecMap<DOFVector<double >, CurMap >& rhs)
+  {
+    DOFVector<double>::Iterator it_x(&rhs.vec, USED_DOFS);
+    int counter(0);
+    typedef typename Collection< Vector >::Inserter Inserter ;
+
+    Inserter swapIns(dest);
+    mtl::vector::mapped_inserter< Inserter, CurMap > ins(swapIns, rhs.mapper);
+
+    for (it_x.reset(); !it_x.end(); ++it_x) {
+      ins[counter] << *it_x;
+      counter++;
+    }
+  }
+
+  template< typename Vector, typename CurMap >
+  inline void operator>>(const Vector& dest, VecMap<DOFVector< double >, CurMap >& rhs)
+  {
+    DOFVector<double>::Iterator it_x(&rhs.vec, USED_DOFS);
+    int counter(0);
+    {
+      mtl::vector::extracter< Vector > extracter(dest);
+      for (it_x.reset(); !it_x.end(); ++it_x) {
+	extracter[rhs.mapper.row(counter)] >> *it_x ;
+	counter++;
+      }
+    }
+  }
+
+  template< typename Vector, typename CurMap >
+  void operator<<(Vector& dest, VecMap<SystemVector, CurMap>& rhs)
+  {
+    int ns = rhs.vec.getSize();  // Number of systems.
+
+      // Copy vectors
+    typedef typename Collection< Vector >::Inserter Inserter;
+    Inserter swapInserter(dest);
+    mtl::vector::mapped_inserter< Inserter, CurMap > ins(swapInserter, rhs.mapper);
+    for (int i = 0; i < ns; i++) {
+      DOFVector<double>::Iterator it_source(rhs.vec.getDOFVector(i), USED_DOFS);
+      int counter(0);
+      rhs.mapper.setRow(i);
+      for (it_source.reset(); !it_source.end(); ++it_source) {
+        ins[counter] << *it_source;
+        counter++;
+      }
+    }
+  }
+
+  template< typename Vector, typename CurMap >
+  void operator>>(const Vector& dest, VecMap<SystemVector, CurMap>& rhs) 
+  {
+    int ns = rhs.vec.getSize();  // Number of systems.
+
+      // Copy vectors
+    for (int i = 0; i < ns; i++) {
+      DOFVector< double >& dofvec(*(rhs.vec.getDOFVector(i)));
+      rhs.mapper.setRow(i);
+      VecMap< DOFVector< double >, CurMap > swap(dofvec, rhs.mapper);
+      dest >> swap;
+    }
+  }
+}
+#endif
diff --git a/AMDiS/src/OEMSolver.h b/AMDiS/src/OEMSolver.h
index 6c126a0f..ef7fb895 100644
--- a/AMDiS/src/OEMSolver.h
+++ b/AMDiS/src/OEMSolver.h
@@ -39,7 +39,13 @@
 #include "DOFVector.h"
 #include "SystemVector.h"
 #include "DOFMatrix.h"
-#include "ITL_Preconditioner.h"
+#include "BasePreconditioner.h"
+#include "Mapper.h"
+
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+#include "parallel/ParallelMapper.h"
+#endif
+//#include "ITL_Preconditioner.h"
 
 namespace AMDiS {
 
@@ -67,9 +73,9 @@ namespace AMDiS {
 	print_cycle(100),
 	iterations(-1),
 	error(-1),
-	multipleRhs(false),
+	multipleRhs(false)/*,
 	leftPrecon(NULL),
-	rightPrecon(NULL)
+	rightPrecon(NULL)*/
     {}
 
     ///
@@ -87,75 +93,22 @@ namespace AMDiS {
       Parameters::get(name + "->info", info);
     }
 
-    /** Set left Preconditioner
-     *
-     *  It is assumed that the solver owns the preconditioner from this call.
-     *  That means that the preconditioner is deleted by the solver when not needed.
-     */
-    void setLeftPrecon(ITL_BasePreconditioner* p) 
-    {
-      if (leftPrecon)
-        delete leftPrecon;
-      leftPrecon = p;
-    }
-
-    /** Set right Preconditioner
-     *
-     *  It is assumed that the solver owns the preconditioner from this call.
-     *  That means that the preconditioner is deleted by the solver when not needed.
-     */
-    void setRightPrecon(ITL_BasePreconditioner* p) 
-    {
-      if (rightPrecon)
-        delete rightPrecon;
-      rightPrecon = p;
-    }
-
-    /// Linear System to be solved in the derived class
-    virtual int solveSystem(const DOFMatrix::base_matrix_type& A,
-			    mtl::dense_vector<value_type>& x,
-			    const mtl::dense_vector<value_type>& b) = 0;
-    
-
-    /// Solve a linear system for a scalar problem.
-    int solveSystem(const SolverMatrix<DOFMatrix>& A,
-		    DOFVector<double>& x, 
-		    DOFVector<double>& b) 
-    {
-      mtl::dense_vector<value_type> xx(x.getUsedSize()), bb(b.getUsedSize());
-
-      // Copy rhs vector
-      int counter = 0;
-      DOFVector<double>::Iterator it_b(&b, USED_DOFS);
-      DOFVector<double>::Iterator it_x(&x, USED_DOFS);
-
-      for (it_b.reset(), it_x.reset(); !it_b.end(); ++it_b, ++it_x) {	
-	bb[counter] = *it_b;
-	xx[counter] = *it_x;
-	counter++;
-      }
-
-      int r = solveSystem(A.getMatrix(), xx, bb);
-
-      // Copy solution vector to DOFVector
-      counter = 0;
-      for (it_x.reset(); !it_x.end(); ++it_x)
-	*it_x = xx[counter++];
-
-      return r;
-    }
 
     /// Solve a linear system for a vectorial problem.
     virtual int solveSystem(const SolverMatrix<Matrix<DOFMatrix*> >& A,
 			    SystemVector& x, 
-			    SystemVector& b) 
+			    SystemVector& b,
+			    VectorialMapper&) = 0;
+#if 0
     {
       int ns = x.getSize(),  // Number of systems.
 	size = x.getUsedSize(); // Size of all DOFVectors
 
       // Copy vectors
       mtl::dense_vector<value_type>   xx(size), bb(size);
-      for (int i = 0, counter = 0; i < ns; i++) {
+      xx << x;
+      bb << b
+/*      for (int i = 0, counter = 0; i < ns; i++) {
 	DOFVector<double>::Iterator it_b(b.getDOFVector(i), USED_DOFS);	  
 	DOFVector<double>::Iterator it_x(x.getDOFVector(i), USED_DOFS);
 	
@@ -165,9 +118,11 @@ namespace AMDiS {
 	  counter++;
 	}
       }
-      
+     */
       // Solver on DOFVector for single system
-      int r = solveSystem(A.getMatrix(), xx, bb);
+      DOFMatrix::base_matrix_type baseA;
+      baseA << A;
+      int r = solveSystem(baseA, xx, bb);
       
       for (int i = 0, counter = 0; i < ns; i++) {
 	DOFVector<double>::Iterator it(x.getDOFVector(i), USED_DOFS);	  
@@ -177,6 +132,27 @@ namespace AMDiS {
       
       return r;
     }
+#endif
+
+    inline int solveSystem(const SolverMatrix< Matrix< DOFMatrix* > >& A,
+		    SystemVector& x,
+		    SystemVector& b) 
+    {
+	    VectorialMapper mapper(A);
+	    return solveSystem(A, x, b, mapper);
+    }
+
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+    virtual int solveSystem(const SolverMatrix<Matrix<DOFMatrix*> >& A,
+			    SystemVector& x, 
+			    SystemVector& b,
+			    ParallelMapper&) 
+    { 
+      FUNCNAME("OEMSolver::solveSystem()");
+      TEST_EXIT(false)("This linear solver is not suitable for domaindecomposition problems\n");
+      return -1;
+    }
+#endif
 
     /** \name getting methods
      * \{ 
@@ -200,12 +176,49 @@ namespace AMDiS {
       return max_iter;
     }
 
+    /// Returns number of iterations in last run of an iterative solver
+    inline int getIterations() 
+    {
+      return iterations;
+    }
+
+    /// Returns error code in last run of an iterative solver
+    inline int getErrorCode() 
+    {
+      return error;
+    }
+
+    /// Returns info
+    inline int getInfo()
+    {
+      return info;
+    }
+
+    /// Returns \ref print_cycle
+    inline int getPrint_cycle() const
+    {
+      return print_cycle;
+    }
+
     /// Returns \ref residual
     inline double getResidual() const
     {
       return residual;
     }
 
+    /// Returns \ref relative
+    inline double getRelative() const
+    {
+      return relative;
+    }
+
+    /// Returns \ref multipleRhs
+    inline bool getMultipleRhs() const
+    {
+      return multipleRhs;
+    }
+
+
     /** \} */ 
 
     /** \name setting methods
@@ -218,6 +231,11 @@ namespace AMDiS {
       tolerance = tol;
     }
 
+    inline void setResidual(double r)
+    {
+      residual = r;
+    }
+
     /// Sets \ref relative
     inline void setRelative(double rel) 
     {
@@ -230,25 +248,24 @@ namespace AMDiS {
       max_iter = i;
     }
 
-    /// Returns number of iterations in last run of an iterative solver
-    inline int getIterations() 
+    inline void setIterations(int i)
     {
-      return iterations;
+      iterations=i;
     }
 
-    /// Returns error code in last run of an iterative solver
-    inline int getErrorCode() 
+    /// set the \ref error
+    inline void setErrorCode(int code)
     {
-      return error;
+      error=code;
     }
-
+  
     /// Sets \ref info
     inline void setInfo(int i) 
     {
       info = i;
     }
 
-    void setMultipleRhs(bool b)
+    inline void setMultipleRhs(bool b)
     {
       multipleRhs = b;
     }
@@ -289,12 +306,13 @@ namespace AMDiS {
      * as they can do the factorization of the matrix only once.
      */
     bool multipleRhs;
-
+#if 0
     /// Left preconditioner (ignored by some iterative solvers and by UmfPack)
-    ITL_BasePreconditioner *leftPrecon;
+    PreconCreator *leftPrecon;
 
     /// Right preconditioner (ignored by some iterative solvers and by UmfPack)
-    ITL_BasePreconditioner *rightPrecon;
+    PreconCreator *rightPrecon;
+#endif
   };
 
   /** 
@@ -323,6 +341,6 @@ namespace AMDiS {
   };
 }
 
-#include "ITL_Solver.h"
+//#include "ITL_Solver.h"
 
 #endif // AMDIS_OEM_SOLVER_H
diff --git a/AMDiS/src/ProblemStat.cc b/AMDiS/src/ProblemStat.cc
index c2e65056..711f6a39 100644
--- a/AMDiS/src/ProblemStat.cc
+++ b/AMDiS/src/ProblemStat.cc
@@ -1290,7 +1290,7 @@ namespace AMDiS {
 
   void ProblemStatSeq::createPrecon()
   {
-    string preconType("no");
+    /*string preconType("no");
     Parameters::get(name + "->solver->left precon", preconType);
 
     CreatorInterface<ITL_BasePreconditioner> *preconCreator = 
@@ -1302,7 +1302,7 @@ namespace AMDiS {
     Parameters::get(name + "->solver->right precon", preconType);
 
     preconCreator = CreatorMap<ITL_BasePreconditioner>::getCreator(preconType);
-    solver->setRightPrecon(preconCreator->create(solverMatrix.getMatrix()));
+    solver->setRightPrecon(preconCreator->create(solverMatrix.getMatrix()));*/
   }
 
 
diff --git a/AMDiS/src/SolverMatrix.cc b/AMDiS/src/SolverMatrix.cc
new file mode 100644
index 00000000..c7a1c0b2
--- /dev/null
+++ b/AMDiS/src/SolverMatrix.cc
@@ -0,0 +1,15 @@
+#include "SolverMatrix.h"
+#include "Mapper.h"
+#include "MatrixStreams.h"
+
+namespace AMDiS {
+  void SolverMatrix< Matrix<DOFMatrix*> >::buildMatrix() const
+  {
+    VectorialMapper mapper(*this);
+    matrix.change_dim(mapper.nRow(), mapper.nCol());
+    set_to_zero(matrix);
+    MatMap< const SolverMatrix< Matrix<DOFMatrix*> >, VectorialMapper > matMap(*this,mapper);
+    matrix << matMap;
+
+  }
+}
diff --git a/AMDiS/src/SolverMatrix.h b/AMDiS/src/SolverMatrix.h
index 1fe1ae32..9a9e8bde 100644
--- a/AMDiS/src/SolverMatrix.h
+++ b/AMDiS/src/SolverMatrix.h
@@ -40,8 +40,11 @@ namespace AMDiS {
   template <>
   class SolverMatrix<DOFMatrix>
   {
-    public : 
-      SolverMatrix() : matrix(0) {}
+    public :
+
+      SolverMatrix() : 
+	matrix(0)
+      {}
 
       void setMatrix(const DOFMatrix& A)
       {
@@ -62,36 +65,22 @@ namespace AMDiS {
   template <>
   class SolverMatrix<Matrix<DOFMatrix*> >
   {
-  public : 
+    void buildMatrix() const;
+  public :
+    SolverMatrix<Matrix<DOFMatrix* > >():
+      originalMat(NULL)
+    {}
+
     void setMatrix(const Matrix<DOFMatrix*>& A)
     {
-      int ns = A.getSize();
-      std::vector<int> block_starts(ns + 1);
-
-      block_starts[0] = 0;
-      for (int i= 0; i < ns; i++)
-	block_starts[i + 1] = block_starts[i] + A[i][i]->getFeSpace()->getAdmin()->getUsedSize();
-      
-      matrix.change_dim(block_starts[ns], block_starts[ns]);
-      set_to_zero(matrix);
-      
-      int nnz = 0;
-      for (int rb = 0; rb < ns; ++rb)
-	for (int cb = 0; cb < ns; ++cb)
-	  if (A[rb][cb])
-	    nnz += A[rb][cb]->getBaseMatrix().nnz();	  
-      
-      DOFMatrix::inserter_type  ins(matrix, int(1.2 * nnz / matrix.dim1()));
-      for (int rb = 0; rb < ns; ++rb)
-	for (int cb = 0; cb < ns; ++cb)
-	  if (A[rb][cb])
-	    ins[block_starts[rb]][block_starts[cb]] << A[rb][cb]->getBaseMatrix();
-
       originalMat = &A;
+      matrix.change_dim(0,0);
     }
-    
+
     const DOFMatrix::base_matrix_type& getMatrix() const 
     { 
+      if( num_rows(matrix) == 0)
+        buildMatrix();
       return matrix; 
     }
 
@@ -101,12 +90,11 @@ namespace AMDiS {
     }
     
   private:      
-    DOFMatrix::base_matrix_type matrix;
+    mutable DOFMatrix::base_matrix_type matrix;
     
     const Matrix<DOFMatrix*>* originalMat;
-    
-  };
 
+  };
 
 
 } // namespace AMDiS
diff --git a/AMDiS/src/UmfPackSolver.h b/AMDiS/src/UmfPackSolver.h
index 520388b4..a07f1b79 100644
--- a/AMDiS/src/UmfPackSolver.h
+++ b/AMDiS/src/UmfPackSolver.h
@@ -28,7 +28,7 @@
 #include <iostream>
 #include <boost/numeric/mtl/operation/two_norm.hpp>
 #include <boost/numeric/mtl/interface/umfpack_solve.hpp>
-#include "OEMSolver.h"
+#include "MTL4Solver.h"
 
 namespace AMDiS {
 
@@ -41,81 +41,97 @@ namespace AMDiS {
    *
    * This is a direct solver for large sparse matrices.
    */
-
-  class UmfPackSolver : public OEMSolver
+  template< typename Matrix >
+  struct Umfpack_runner 
   {
-  public:
-    /// Creator class used in the OEMSolverMap.
-    class Creator : public OEMSolverCreator
-    {
-    public:
-      virtual ~Creator() {}
-      
-      /// Returns a new UmfPackSolver object.
-      OEMSolver* create() 
-      { 
-	return new UmfPackSolver(this->name); 
-      }
-    };
-
-    /// Constructor
-    UmfPackSolver(std::string name) 
-      : OEMSolver(name), 
-	solver(0),
-	store_symbolic(0),
-	symmetric_strategy(0)
+    typedef Matrix matrix_type ;
+    OEMSolver& oem;
+    Umfpack_runner(OEMSolver* oem_):
+      oem(*oem_),
+      solver(NULL),
+      store_symbolic(0),
+      symmetric_strategy(0)
     {
-      Parameters::get(name + "->store symbolic", store_symbolic);
-      Parameters::get(name + "->symmetric strategy", symmetric_strategy);
-    }
-    
-    /// Destructor
-    ~UmfPackSolver() 
-    { 
-      if (solver) 
-	delete solver;
+      TEST_EXIT_DBG(oem_ != NULL)("Need real OEMSolver\n"); 
+      Parameters::get(oem.getName() + "->store symbolic", store_symbolic);
+      Parameters::get(oem.getName() + "->symmetric strategy", symmetric_strategy);
     }
 
-    /// Solves the system directly
-    int solveSystem(const DOFMatrix::base_matrix_type& A,
-		    mtl::dense_vector<value_type>& x,
-		    const mtl::dense_vector<value_type>& b)
-    {
+    template< typename Vector> 
+    int solve(const Matrix& A, Vector& x, Vector& b) 
+    { 
       if (!solver) {
 	if (!symmetric_strategy)
 	  solver = new mtl::matrix::umfpack::solver<matrix_type>(A);
 	else
 	  solver = new mtl::matrix::umfpack::solver<matrix_type>(A, UMFPACK_STRATEGY_SYMMETRIC);
       } else {
-	if (!multipleRhs) {
+	if (!oem.getMultipleRhs()) {
+
  	  if (store_symbolic)
  	    solver->update_numeric();
  	  else
 	    solver->update();
 	}
-     }
-     
+      }
+
       int code = (*solver)(x, b);
-      if (info > 0) {
-        mtl::dense_vector<value_type> r(b); 
+      if( oem.getInfo() > 0) {
+        mtl::dense_vector<typename matrix_type::value_type> r(b); 
         r -= A * x; 
-        residual = two_norm(r);
+        double residual = two_norm(r);
+        oem.setResidual(residual);
+        oem.setErrorCode(code);
         std::cout << "UmfPackSolver: ||b-Ax|| = " << residual << "\n";
-	if (residual > tolerance) {
-          WARNING("Tolerance tol=%e could not be reached!\n",tolerance);
+	if (residual > oem.getTolerance()) {
+          WARNING("Tolerance tol=%e could not be reached!\n", oem.getTolerance());
 	}
       }
       return code;
+
     }
 
-    
-  private:
+    ~Umfpack_runner() 
+    {
+      if(!solver)
+	delete solver;
+    }
+
+    private:
     mtl::matrix::umfpack::solver<matrix_type> *solver;
 
     int store_symbolic;
-
     int symmetric_strategy;
   };
+
+  using namespace MTLTypes;
+  class UmfPackSolver : public MTL4Solver<MTLMatrix, MTLVector, Umfpack_runner< MTLMatrix > >
+  {
+    protected:
+
+  public:
+    /// Creator class used in the OEMSolverMap.
+    class Creator : public OEMSolverCreator
+    {
+    public:
+      virtual ~Creator() {}
+      
+      /// Returns a new UmfPackSolver object.
+      OEMSolver* create() 
+      { 
+	return new UmfPackSolver(this->name); 
+      }
+    };
+
+    /// Constructor
+    UmfPackSolver(std::string name) 
+      : MTL4Solver< MTLMatrix, MTLVector, Umfpack_runner< MTLMatrix > >(name)
+    {
+    }
+    
+    
+  private:
+  };
   
 }
 
diff --git a/AMDiS/src/parallel/Mtl4Solver.cc b/AMDiS/src/parallel/Mtl4Solver.cc
new file mode 100644
index 00000000..b7b20d05
--- /dev/null
+++ b/AMDiS/src/parallel/Mtl4Solver.cc
@@ -0,0 +1,133 @@
+#include "parallel/Mtl4Solver.h"
+#include "parallel/PITL_Solver.h"
+#include "parallel/ParallelMapper.h"
+
+namespace AMDiS {
+  namespace Parallel {
+
+    void Mtl4Solver::addPMTLSolvers()
+    {
+      OEMSolverCreator *creator;
+
+      creator = new CGSolver::Creator;
+      CreatorMap< OEMSolver >::addCreator("pcg", creator);
+
+      creator = new CGSSolver::Creator;
+      CreatorMap< OEMSolver >::addCreator("pcgs", creator);
+
+      creator = new BiCGSolver::Creator;
+      CreatorMap< OEMSolver >::addCreator("pbicg", creator);
+
+      creator = new BiCGStabSolver::Creator;
+      CreatorMap< OEMSolver >::addCreator("pbicgstab", creator);
+
+      creator = new BiCGStab2Solver::Creator;
+      CreatorMap< OEMSolver >::addCreator("pbicgstab2", creator);
+
+      creator = new BiCGStabEllSolver::Creator;
+      CreatorMap< OEMSolver >::addCreator("pbicgstab_ell", creator);
+
+      creator = new QMRSolver::Creator;
+      CreatorMap< OEMSolver >::addCreator("pqmr", creator);
+
+      creator = new TFQMRSolver::Creator;
+      CreatorMap< OEMSolver >::addCreator("ptfqmr", creator);
+
+      creator = new GMResSolver::Creator;
+      CreatorMap< OEMSolver >::addCreator("pgmres", creator);
+
+      creator = new IDRsSolver::Creator;
+      CreatorMap< OEMSolver >::addCreator("pidr_s", creator);
+
+      creator = new MinResSolver::Creator;
+      CreatorMap< OEMSolver >::addCreator("pminres", creator);
+    }
+
+/*    void Mtl4Solver::addPMTLPrecons() 
+    {
+       ParallelPreconditionCreator *creator;
+
+       creator =  new DiagonalPreconditioner::Creator;
+       CreatorMap<ParallelPreconditioner >::addCreator("pdiag", creator);
+
+       creator = new ILUPreconditioner::Creator;
+       CreatorMap<ParallelPreconditioner >::addCreator("pilu", creator);
+
+       creator = new ICPreconditioner::Creator;
+       CreatorMap<ParallelPreconditioner >::addCreator("pic", creator);
+
+       creator =  new IdentityPreconditioner::Creator;
+       CreatorMap<ParallelPreconditioner >::addCreator("pno", creator);
+
+    }*/
+  
+    void Mtl4Solver::createSolver()
+    {
+      FUNCNAME("Parallel::Mtl4Solver::createSolver()");
+
+      // === create solver ===
+      std::string solverType("0");
+      Parameters::get(name + "->solver", solverType);
+      solverType = "p" + solverType;
+      OEMSolverCreator *solverCreator = 
+	dynamic_cast<OEMSolverCreator*>(CreatorMap<OEMSolver>::getCreator(solverType));
+      TEST_EXIT(solverCreator)("no solver type\n");
+      solverCreator->setName(name + "->solver");
+      solver = solverCreator->create();
+      solver->initParameters();
+    }
+
+    //TODO: replace the name in the map
+    void Mtl4Solver::createPrecon()
+    {
+      /*std::string preconType("no");
+      GET_PARAMETER(0, name + "->solver->left precon", &preconType);
+      preconType = "p" + preconType ;
+
+      CreatorInterface<BasePreconditioner> *preconCreator = 
+	CreatorMap<BasePreconditioner>::getCreator(preconType);
+
+  //    solver->setLeftPrecon(preconCreator->create(solverMatrix.getMatrix()));
+      solver->setLeftPrecon(preconCreator);
+
+      preconType= "no";
+      GET_PARAMETER(0, name + "->solver->right precon", &preconType);
+      preconType = "p" + preconType;
+
+      preconCreator = CreatorMap<BasePreconditioner>::getCreator(preconType);
+  //    solver->setRightPrecon(preconCreator->create(solverMatrix.getMatrix()));
+      solver->setRightPrecon(preconCreator);*/
+    }
+    
+    void Mtl4Solver::solve(AdaptInfo* adaptInfo, bool fixedMatrix)
+    {
+/*      FUNCNAME("Mtl4Solver::solve()");
+      std::string solverName("");
+      GET_PARAMETER(0, name+"->solver", &solverName);
+      TEST_EXIT(solverName != "")("need solver name");
+      OEMSolver* solver = getPMTLSolver(solverName);
+
+      delete solver;
+      */
+      ParallelMapper pmapper(*meshDistributor, nComponents);
+      solver->solveSystem(solverMatrix, *solution, *rhs, pmapper);
+    }
+  }
+
+  template< > 
+  void CreatorMap< Parallel::ParallelPreconditioner >::addDefaultCreators() {
+    Parallel::ParallelPreconditionCreator *creator;
+
+     creator =  new Parallel::DiagonalPreconditioner::Creator;
+     addCreator("diag", creator);
+
+     creator = new Parallel::ILUPreconditioner::Creator;
+     addCreator("ilu", creator);
+
+     creator = new Parallel::ICPreconditioner::Creator;
+     addCreator("ic", creator);
+
+     creator =  new Parallel::IdentityPreconditioner::Creator;
+     addCreator("no", creator);
+  }
+}
diff --git a/AMDiS/src/parallel/Mtl4Solver.h b/AMDiS/src/parallel/Mtl4Solver.h
index e3043edc..30c9d383 100644
--- a/AMDiS/src/parallel/Mtl4Solver.h
+++ b/AMDiS/src/parallel/Mtl4Solver.h
@@ -27,26 +27,33 @@
 
 namespace AMDiS {
 
-  class Mtl4Solver : public ParallelProblemStatBase
-  {
-  public:
-    Mtl4Solver(std::string nameStr,
-	       ProblemIterationInterface *problemIteration = NULL)
-      : ParallelProblemStatBase(nameStr, problemIteration)
-    {}
+  namespace Parallel {
+    class Mtl4Solver : public ParallelProblemStatBase
+    {
+      void addPMTLSolvers();
+      //void addPMTLPrecons();
+    public:
+      Mtl4Solver(std::string nameStr,
+             ProblemIterationInterface *problemIteration = NULL)
+        : ParallelProblemStatBase(nameStr, problemIteration)
+      {
+	addPMTLSolvers();
+	//addPMTLPrecons();
+      }
 
     
-    ~Mtl4Solver()
-    {}
+      ~Mtl4Solver()
+      {}
 
 
-    void solve(AdaptInfo *adaptInfo, bool fixedMatrix = false)
-    {
-      ERROR_EXIT("TO BE IMPLEMENTED!\n");
-    }
+      void solve(AdaptInfo *adaptInfo, bool fixedMatrix = false);
+      void createPrecon();
+      void createSolver();
+    };
   }
 
-  typedef Mtl4Solver ParallelProblemStat;
+  typedef Parallel::Mtl4Solver ParallelProblemStat;
+  typedef ParallelProblemStat  ProblemStat;
 }
 
 #endif
diff --git a/AMDiS/src/parallel/PITL_Solver.h b/AMDiS/src/parallel/PITL_Solver.h
new file mode 100644
index 00000000..2754dd0e
--- /dev/null
+++ b/AMDiS/src/parallel/PITL_Solver.h
@@ -0,0 +1,318 @@
+// ============================================================================
+// ==                                                                        ==
+// == AMDiS - Adaptive multidimensional simulations                          ==
+// ==                                                                        ==
+// ============================================================================
+// ==                                                                        ==
+// ==  TU Dresden                                                            ==
+// ==                                                                        ==
+// ==  Institut für Wissenschaftliches Rechnen                               ==
+// ==  Zellescher Weg 12-14                                                  ==
+// ==  01069 Dresden                                                         ==
+// ==  germany                                                               ==
+// ==                                                                        ==
+// ============================================================================
+// ==                                                                        ==
+// ==  https://gforge.zih.tu-dresden.de/projects/amdis/                      ==
+// ==                                                                        ==
+// ============================================================================
+
+/** \file PITL_Solver.h */
+
+#ifndef AMDIS_PITL_SOLVER_H
+#define AMDIS_PITL_SOLVER_H
+
+#include "ITL_Solver.h"
+
+namespace AMDiS {
+  namespace Parallel {
+    typedef mtl::matrix::distributed< MTLTypes::MTLMatrix > MTLMatrix;
+    typedef mtl::vector::distributed< MTLTypes::MTLVector > MTLVector;
+    typedef CreatorInterface< ITL_BasePreconditioner< MTLVector > > ParallelPreconditionCreator;
+    typedef ITL_BasePreconditioner< MTLVector > ParallelPreconditioner;
+
+    template< typename ITLSolver >
+    class PITL_Solver : public AMDiS::MTL4Solver< MTLMatrix, MTLVector, ITL_OEMSolver_runner< ITLSolver > > {
+      public:
+	PITL_Solver(std::string name):
+	  AMDiS::MTL4Solver< MTLMatrix, MTLVector, ITL_OEMSolver_runner< ITLSolver > >(name) {}
+
+	int solveSystem(const SolverMatrix<Matrix<DOFMatrix*> >& A,
+			    SystemVector& x, 
+			    SystemVector& b,
+			    ParallelMapper& m) 
+	{
+	  return AMDiS::MTL4Solver< MTLMatrix, MTLVector, ITL_OEMSolver_runner< ITLSolver > >::solve(A,x,b,m);
+	}
+
+
+	/// Creator class used in the OEMSolverMap.
+    	class Creator : public OEMSolverCreator
+        {
+	  public:
+	    virtual ~Creator() {}
+	    
+            /// Returns a new CGSolver object.
+	    OEMSolver* create() 
+            { 
+	      return new PITL_Solver<ITLSolver>(this->name); 
+            }
+	};
+    };
+
+    template< typename ITLSolver >
+    class PITL_Solver_para : public AMDiS::MTL4Solver< MTLMatrix, MTLVector, ITL_OEMSolver_para_runner< ITLSolver > > {
+      public:
+	PITL_Solver_para(std::string name):
+	  AMDiS::MTL4Solver< MTLMatrix, MTLVector, ITL_OEMSolver_para_runner< ITLSolver > >(name) {}
+
+	/// Creator class used in the OEMSolverMap.
+    	class Creator : public OEMSolverCreator
+        {
+	  public:
+	    virtual ~Creator() {}
+	    
+            /// Returns a new CGSolver object.
+	    OEMSolver* create() 
+            { 
+	      return new PITL_Solver_para<ITLSolver>(this->name); 
+            }
+	};
+    };
+
+    /**
+     * \ingroup Solver
+     * 
+     * \brief
+     * Solves a linear system by the conjugate gradient method (CG) and can be used for
+     * symmetric positive definite system matrices.
+     * Right preconditioner is ignored.
+     */
+    class CGSolver : public PITL_Solver<cg_solver_type>
+    {
+    public:
+      /// The constructor reads required parameters and sets solvers \ref name.
+      CGSolver(std::string name) : PITL_Solver<cg_solver_type>(name) {}
+    };
+
+
+    /**
+     * \ingroup Solver
+     * 
+     * \brief
+     * Solves a linear system by the squared conjugate gradient method (CGS).
+     * Right preconditioner is ignored.
+     */
+    class CGSSolver : public PITL_Solver<cgs_solver_type>
+    {
+    public:
+      /// The constructor reads required parameters and sets solvers \ref name.
+      CGSSolver(std::string name) : PITL_Solver<cgs_solver_type>(name) {}
+    };
+
+
+     /**  
+     * \ingroup Solver
+     *
+     * \brief
+     * Solves a linear system by a stabilized BiCG method and can be used for 
+     * system matrices.
+     */
+    class BiCGSolver : public PITL_Solver<bicg_solver_type>
+    {
+    public:
+      /// The constructor reads required parameters and sets solvers \ref name.
+      BiCGSolver(std::string name) : PITL_Solver<bicg_solver_type>(name) {}
+    };
+
+    /**  
+     * \ingroup Solver
+     *
+     * \brief
+     * Solves a linear system by a stabilized BiCG method and can be used for 
+     * system matrices.
+     */
+    class BiCGStabSolver : public PITL_Solver<bicgstab_type>
+    {
+    public:
+      /// The constructor reads required parameters and sets solvers \ref name.
+      BiCGStabSolver(std::string name) : PITL_Solver<bicgstab_type>(name) {}
+    };
+
+    /**  
+     * \ingroup Solver
+     *
+     * \brief
+     * Solves a linear system by a stabilized BiCG method and can be used for 
+     * system matrices.
+     */
+    class BiCGStab2Solver : public PITL_Solver<bicgstab2_type>
+    {
+    public:
+      /// The constructor reads required parameters and sets solvers \ref name.
+      BiCGStab2Solver(std::string name) : PITL_Solver<bicgstab2_type>(name) {}
+    };
+
+
+     /**
+     * \ingroup Solver
+     * 
+     * \brief
+     * Solves a linear system by the Quasi-Minimal Residual method (QMR).
+     */
+    class QMRSolver : public PITL_Solver<qmr_solver_type>
+    {
+    public:
+      /// The constructor reads required parameters and sets solvers \ref name.
+      QMRSolver(std::string name) : PITL_Solver<qmr_solver_type>(name) {}
+    };
+
+
+     /**
+     * \ingroup Solver
+     * 
+     * \brief
+     * Solves a linear system by the Transposed-Free Quasi-Minimal Residual method (TFQMR).
+     * Does not use preconditioning currently.
+     */
+    class TFQMRSolver : public PITL_Solver<tfqmr_solver_type>
+    {
+    public:
+      /// The constructor reads required parameters and sets solvers \ref name.
+      TFQMRSolver(std::string name) : PITL_Solver<tfqmr_solver_type>(name) {}
+    };
+
+
+    /**  
+     * \ingroup Solver
+     *
+     * \brief
+     * Solves a linear system by a stabilized BiCG(l) method and can be used for 
+     * system matrices.
+     */
+    class BiCGStabEllSolver : public PITL_Solver_para<bicgstab_ell_type>
+    {
+    public:
+      /// The constructor reads required parameters and sets solvers \ref name.
+      BiCGStabEllSolver(std::string name) : PITL_Solver_para<bicgstab_ell_type>(name) {}
+    };
+
+    /**  
+     * \ingroup Solver
+     *
+     * \brief
+     * Solves a linear system by the GMRES method.
+     * The parameter ell is the maximal number of orthogonalized vectors.
+     * The method is not preconditioned 
+     */
+    class GMResSolver : public PITL_Solver_para<gmres_type>
+    {
+    public:
+      /// The constructor reads required parameters and sets solvers \ref name.
+      GMResSolver(std::string name) : PITL_Solver_para<gmres_type>(name) {}
+    };
+
+
+    /**  
+     * \ingroup Solver
+     *
+     * \brief
+     * Solves a linear system by an Induced Dimension Reduction method and can be used for 
+     * system matrices.
+     * The parameter s can be specified as ell.
+     * Peter Sonneveld and Martin B. van Gijzen, IDR(s): a family of simple and fast algorithms for solving large nonsymmetric linear systems. 
+     * SIAM J. Sci. Comput. Vol. 31, No. 2, pp. 1035-1062 (2008). (copyright SIAM)
+     * 
+     */
+    class IDRsSolver : public PITL_Solver_para<idr_s_type>
+    {
+    public:
+      /// The constructor reads required parameters and sets solvers \ref name.
+      IDRsSolver(std::string name) : PITL_Solver_para<idr_s_type>(name) {}
+    };
+
+
+    /**
+     * \ingroup Solver
+     * 
+     * \brief
+     * Solves a linear system by the Minres method. Can be used for symmetric 
+     * indefinite systems.
+     */
+    class MinResSolver : public PITL_Solver<minres_solver_type>
+    {
+    public:
+      /// The constructor reads required parameters and sets solvers \ref name.
+      MinResSolver(std::string name) : PITL_Solver<minres_solver_type>(name) {}
+    };
+
+ /**
+   * \ingroup Solver
+   * 
+   * \brief
+   * Diagonal preconditioner. 
+   */
+  class DiagonalPreconditioner 
+    : public ITL_Preconditioner<itl::pc::diagonal<MTLMatrix >, MTLVector, MTLMatrix >
+  {
+    typedef ITL_Preconditioner<itl::pc::diagonal<MTLMatrix >, MTLVector, MTLMatrix > base;
+
+  public:
+    DiagonalPreconditioner(const MTLMatrix& A) : base(A) {}
+  };
+
+  /**
+   * \ingroup Solver
+   * 
+   * \brief
+   * Identity preconditioner. Behaves like no preconditioning.
+   */
+  class IdentityPreconditioner 
+    : public ITL_Preconditioner<itl::pc::identity<MTLMatrix >, MTLVector, MTLMatrix >
+  {
+    typedef ITL_Preconditioner<itl::pc::identity<MTLMatrix >, MTLVector, MTLMatrix > base;
+
+  public:
+      IdentityPreconditioner(const MTLMatrix& A) : base(A) {}
+  };
+
+
+  // ============================================================================
+  // ===== class ILUPreconditioner ==============================================
+  // ============================================================================
+
+  /**
+   * \ingroup Solver
+   * 
+   * \brief
+   * ILU (Incomplete LU factorization) preconditioner.
+   *
+   * The preconditioner is used from ITL. It corresponds for instance to "Iterative Methods for
+   * Sparce Linear Systems", second edition, Yousef Saad. The preconditioner is
+   * described in chapter 10.3 (algorithm 10.4).
+   */
+  class ILUPreconditioner 
+      : public ITL_Preconditioner< itl::pc::ilu_0<MTLMatrix >,MTLVector, MTLMatrix >
+  {};
+
+  class ICPreconditioner 
+      : public ITL_Preconditioner< itl::pc::ic_0<MTLMatrix >, MTLVector, MTLMatrix >
+  {};
+
+
+  }
+  template< >
+  struct Collection< Parallel::MTLMatrix > {
+    typedef mtl::matrix::inserter< Parallel::MTLMatrix , mtl::update_plus< Parallel::MTLMatrix::value_type > > Inserter;
+  };
+
+  template< >
+  struct Collection< Parallel::MTLVector > {
+    typedef mtl::vector::inserter< Parallel::MTLVector , mtl::update_plus< Parallel::MTLVector::value_type > > Inserter;
+    typedef Parallel::MTLMatrix PreconditionMatrix;
+  };
+
+} // namespace AMDiS
+
+#endif // AMDIS_PITL_SOLVER
+ 
diff --git a/AMDiS/src/parallel/ParallelMapper.h b/AMDiS/src/parallel/ParallelMapper.h
new file mode 100644
index 00000000..5b9c36e1
--- /dev/null
+++ b/AMDiS/src/parallel/ParallelMapper.h
@@ -0,0 +1,42 @@
+#ifndef PARALLEL_MAPPER_H
+#define PARALLEL_MAPPER_H
+
+#include "parallel/MeshDistributor.h"
+namespace AMDiS {
+	//todo: request from a problem -> distributor mapper?
+	template< typename size_type > 
+	class ParallelMapper_base {
+		MeshDistributor& md;
+		/// the current row in the problem system
+		size_type r;
+		/// the current column in the problem system
+		size_type c;
+		int nComponents;
+
+		public:
+
+		ParallelMapper_base(MeshDistributor& md, int nComponents):
+			md(md),r(0),c(0),nComponents(nComponents) 
+		{
+			TEST_EXIT_DBG(nComponents > 0)("the system must have at least one component");
+		}
+		size_type row(size_type r_) 
+		{
+			size_type ret = md.mapLocalToGlobal(r_)*nComponents+r;
+			return ret;
+		}
+		size_type col(size_type c_) 
+		{
+			size_type ret = md.mapLocalToGlobal(c_)*nComponents+c;
+			return ret ;
+		}
+
+		inline void setRow(size_type r_) { r = r_ ;}
+		inline void setCol(size_type c_) { c = c_; }
+		inline size_type nRow() { return md.getNumberOverallDofs() * nComponents; }
+		inline size_type nCol() { return md.getNumberOverallDofs() * nComponents; }
+	};
+
+	typedef ParallelMapper_base< unsigned int > ParallelMapper;
+}
+#endif
-- 
GitLab