diff --git a/cmake/modules/AmdisMacros.cmake b/cmake/modules/AmdisMacros.cmake
index 3ee268187aff02a90ce4e3ae91ba3fb0e56b64a6..0862c33eb4d36324aa3ec47feedf42145640ac77 100644
--- a/cmake/modules/AmdisMacros.cmake
+++ b/cmake/modules/AmdisMacros.cmake
@@ -1,21 +1,29 @@
-# File for module specific CMake tests.
-
 include(AMDiSCXXFeatures)
 
 # some additional packages and flags
-find_package(MTL REQUIRED
-             PATHS /usr/local/lib/mtl4 /opt/sources/mtl4 /opt/development/mtl4)
+find_package(MTL
+  PATHS ${MTL_DIR}
+  HINTS /usr/local/lib/mtl4 /opt/sources/mtl4 /opt/development/mtl4
+)
+
+if (MTL_FOUND)
+  set(CXX_ELEVEN_FEATURE_LIST "MOVE" "AUTO" "RANGEDFOR" "INITLIST" "STATICASSERT" "DEFAULTIMPL")
+  set(MTL_COMPILE_DEFINITIONS "")
+  foreach(feature ${CXX_ELEVEN_FEATURE_LIST})
+    list(APPEND MTL_COMPILE_DEFINITIONS "MTL_WITH_${feature}")
+  endforeach()
 
-set(CXX_ELEVEN_FEATURE_LIST "MOVE" "AUTO" "RANGEDFOR" "INITLIST" "STATICASSERT" "DEFAULTIMPL")
-set(MTL_COMPILE_DEFINITIONS "")
-foreach(feature ${CXX_ELEVEN_FEATURE_LIST})
-  list(APPEND MTL_COMPILE_DEFINITIONS "MTL_WITH_${feature}")
-endforeach()
+  find_package(SuiteSparse QUIET)
+  if (SuiteSparse_FOUND)
+    list(APPEND MTL_COMPILE_DEFINITIONS "MTL_HAS_UMFPACK")
+  endif (SuiteSparse_FOUND)
+endif (MTL_FOUND)
 
-if(HAVE_UMFPACK OR ENABLE_SUITESPARSE OR SuiteSparse_FOUND)
-  list(APPEND MTL_COMPILE_DEFINITIONS "MTL_HAS_UMFPACK")
-endif()
+set(HAVE_MTL MTL_FOUND)
 
-dune_register_package_flags(
-  COMPILE_DEFINITIONS ${MTL_COMPILE_DEFINITIONS}
-  INCLUDE_DIRS ${MTL_INCLUDE_DIRS})
+if (MTL_FOUND)
+  list(APPEND MTL_COMPILE_DEFINITIONS "ENABLE_MTL=1")
+  dune_register_package_flags(
+    COMPILE_DEFINITIONS ${MTL_COMPILE_DEFINITIONS}
+    INCLUDE_DIRS ${MTL_INCLUDE_DIRS})
+endif (MTL_FOUND)
\ No newline at end of file
diff --git a/config.h.cmake b/config.h.cmake
index e53392bc7ccd643d244e463b52e0df06dcb2fa1b..23a127dba08ec64ebac14df6d1a68429d9f5bbfe 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -1,4 +1,4 @@
-/* begin dune-amdis
+/* begin amdis
    put the definitions for config.h specific to
    your project here. Everything above will be
    overwritten
@@ -40,12 +40,13 @@
 /* Define to the revision of amdis */
 #define AMDIS_VERSION_REVISION @AMDIS_VERSION_REVISION@
 
+/* Define to ENABLE_UMFPACK if the MTL library is available */
+#cmakedefine HAVE_MTL ENABLE_MTL
 
 /* some detected compiler features may be used in AMDiS */
 #cmakedefine AMDIS_HAS_CXX_FOLD_EXPRESSIONS 1
-
 #cmakedefine AMDIS_HAS_CXX_CONSTEXPR_IF 1
 
-/* end dune-amdis
+/* end amdis
    Everything below here will be overwritten
 */
diff --git a/examples/convection_diffusion.cc b/examples/convection_diffusion.cc
index 40871822f4fe7a9483e404fe2ab8bb8f38dc6124..14bea3a42cbf8d4e46213281d25ec3d3236cbbb2 100644
--- a/examples/convection_diffusion.cc
+++ b/examples/convection_diffusion.cc
@@ -1,6 +1,6 @@
-// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
-// vi: set et ts=4 sw=2 sts=2:
-
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 #include <iostream>
 
 #include <amdis/AMDiS.hpp>
@@ -26,13 +26,13 @@ int main(int argc, char** argv)
 
   // -div(A*grad(u)) + div(b*u) + c*u = f
   auto opCD = convectionDiffusion(/*A=*/1.0, /*b=*/0.0, /*c=*/1.0, /*f=*/1.0);
-  prob.addMatrixOperator(opCD, _0, _0);
-  prob.addVectorOperator(opCD, _0);
+  prob.addMatrixOperator(opCD, 0, 0);
+  prob.addVectorOperator(opCD, 0);
 
   // set boundary condition
   auto predicate = [](auto const& x){ return x[0] < 1.e-8 || x[1] < 1.e-8; }; // define boundary
   auto dbcValues = [](auto const& x){ return 0.0; }; // set value
-  prob.addDirichletBC(predicate, _0, _0, dbcValues);
+  prob.addDirichletBC(predicate, 0, 0, dbcValues);
 
   AdaptInfo adaptInfo("adapt");
   prob.buildAfterCoarsen(adaptInfo, Flag(0));
diff --git a/examples/ellipt.cc b/examples/ellipt.cc
index 396737c3643a17662486482fe66a5fc45f540577..fc7830e8fee7e0b9b46ec87198a53e30593fb627 100644
--- a/examples/ellipt.cc
+++ b/examples/ellipt.cc
@@ -1,6 +1,6 @@
-// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
-// vi: set et ts=4 sw=2 sts=2:
-
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 #include <iostream>
 
 #include <fmt/core.h>
@@ -15,7 +15,7 @@ using namespace AMDiS;
 using namespace Dune::Indices;
 
 // 1 component with polynomial degree 1
-using Param   = YaspGridBasis<AMDIS_DIM, 1>;
+using Param   = YaspGridBasis<AMDIS_DIM, 2>;
 using ElliptProblem = ProblemStat<Param>;
 
 int main(int argc, char** argv)
diff --git a/examples/heat.cc b/examples/heat.cc
index d232264159f3ca35290fbaf364d9b3c06b032400..c2fa5e08d1c7d8afbd2fa611393bed74afa48822 100644
--- a/examples/heat.cc
+++ b/examples/heat.cc
@@ -1,6 +1,6 @@
-// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
-// vi: set et ts=4 sw=2 sts=2:
-
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 #include <iostream>
 
 #include <amdis/AMDiS.hpp>
diff --git a/examples/init/ellipt.dat.2d b/examples/init/ellipt.dat.2d
index f12565729e95e06f7902cf81744b29450c3445e1..0ef4d635178cbd825b31cbd818eab17a036d5c72 100644
--- a/examples/init/ellipt.dat.2d
+++ b/examples/init/ellipt.dat.2d
@@ -3,10 +3,10 @@ elliptMesh->global refinements: 0
 ellipt->mesh:                   elliptMesh
 
 ellipt->solver->name:           bicgstab
-ellipt->solver->max iteration:  1000
-ellipt->solver->relative tolerance: 1.e-8
-ellipt->solver->info:           10
-ellipt->solver->left precon:    diag
+ellipt->solver->max iteration:  10000
+ellipt->solver->relative tolerance: 1.e-10
+ellipt->solver->info:           1
+ellipt->solver->left precon:    ilu
 ellipt->solver->right precon:   no
 
 ellipt->output[0]->filename:    ellipt.2d
diff --git a/examples/navier_stokes.cc b/examples/navier_stokes.cc
index 4fcf941ba26aa0d16f10dc0ef26832dc01a881d7..762b369deba45fa66ffe002b519cb6bebf03a7ca 100644
--- a/examples/navier_stokes.cc
+++ b/examples/navier_stokes.cc
@@ -1,3 +1,7 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <iostream>
 #include <ctime>
 #include <cmath>
@@ -41,8 +45,8 @@ int main(int argc, char** argv)
   AdaptInfo adaptInfo("adapt");
 
   // tree-paths for components
-  auto _v = 0_c;
-  auto _p = 1_c;
+  auto _v = Dune::Indices::_0;
+  auto _p = Dune::Indices::_1;
 
   // <1/tau * u, v>
   auto opTime = makeOperator(tag::testvec_trialvec{}, density);
diff --git a/examples/stokes0.cc b/examples/stokes0.cc
index 7118684a3780769425f17ceac524c369e6335ecb..40a8c425474d611be7ca3d5845f55270f2055eab 100644
--- a/examples/stokes0.cc
+++ b/examples/stokes0.cc
@@ -1,3 +1,7 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <iostream>
 #include <ctime>
 #include <cmath>
@@ -30,8 +34,8 @@ int main(int argc, char** argv)
     Parameters::get("stokes->viscosity", viscosity);
 
     // tree-paths for components
-    auto _v = 0_c;
-    auto _p = 1_c;
+    auto _v = Dune::Indices::_0;
+    auto _p = Dune::Indices::_1;
 
     // <viscosity*grad(u_i), grad(v_i)>
     for (std::size_t i = 0; i < DOW; ++i) {
@@ -76,10 +80,12 @@ int main(int argc, char** argv)
     // assemble and solve system
     prob.buildAfterCoarsen(adaptInfo, Flag(0));
 
+#ifdef DEBUG_MTL
     // write matrix to file
     mtl::io::matrix_market_ostream out("matrix_stokes0.mtx");
-    out << prob.getSystemMatrix().getMatrix();
-    std::cout << prob.getSystemMatrix().getMatrix() << '\n';
+    out << prob.getSystemMatrix().matrix();
+    std::cout << prob.getSystemMatrix().matrix() << '\n';
+#endif
 
     prob.solve(adaptInfo);
 
diff --git a/examples/stokes1.cc b/examples/stokes1.cc
index e0effccebad0af27d55163287295bf5a13eaa598..bdb95a3b5c11de137c2ba754850a7c708ad38fc0 100644
--- a/examples/stokes1.cc
+++ b/examples/stokes1.cc
@@ -1,3 +1,7 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <iostream>
 #include <ctime>
 #include <cmath>
@@ -30,8 +34,8 @@ int main(int argc, char** argv)
     Parameters::get("stokes->viscosity", viscosity);
 
     // tree-paths for components
-    auto _v = 0_c;
-    auto _p = 1_c;
+    auto _v = Dune::Indices::_0;
+    auto _p = Dune::Indices::_1;
 
     // <viscosity*grad(u_i), grad(v_i)>
     for (std::size_t i = 0; i < DOW; ++i) {
@@ -77,10 +81,12 @@ int main(int argc, char** argv)
     // assemble and solve system
     prob.buildAfterCoarsen(adaptInfo, Flag(0));
 
+#ifdef DEBUG_MTL
     // write matrix to file
     mtl::io::matrix_market_ostream out("matrix_stokes1.mtx");
-    out << prob.getSystemMatrix().getMatrix();
-    std::cout << prob.getSystemMatrix().getMatrix() << '\n';
+    out << prob.getSystemMatrix().matrix();
+    std::cout << prob.getSystemMatrix().matrix() << '\n';
+#endif
 
     prob.solve(adaptInfo);
 
diff --git a/examples/stokes3.cc b/examples/stokes3.cc
index 54c75d0da556897759920a782f3cf0b029875902..44ccdd6a4db128ab582a7907dd4296ad7d7172c8 100644
--- a/examples/stokes3.cc
+++ b/examples/stokes3.cc
@@ -1,3 +1,7 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <iostream>
 #include <ctime>
 #include <cmath>
@@ -24,8 +28,8 @@ int main(int argc, char** argv)
   Parameters::get("stokes->viscosity", viscosity);
 
   // tree-paths for components
-  auto _v = 0_c;
-  auto _p = 1_c;
+  auto _v = Dune::Indices::_0;
+  auto _p = Dune::Indices::_1;
 
   auto opStokes = makeOperator(tag::stokes{}, viscosity);
   prob.addMatrixOperator(opStokes, treepath(), treepath());
diff --git a/examples/vecellipt.cc b/examples/vecellipt.cc
index e87f870d172ba675e8d7a49dbefce7e77d6cfe7a..a4dfb40735a29230dbad1e02bedb43c9e4cf8927 100644
--- a/examples/vecellipt.cc
+++ b/examples/vecellipt.cc
@@ -1,3 +1,7 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <iostream>
 
 #include <amdis/AMDiS.hpp>
@@ -38,13 +42,15 @@ int main(int argc, char** argv)
 
   prob.buildAfterCoarsen(adaptInfo, Flag(0));
 
+#ifdef DEBUG_MTL
   // write matrix to file
   if (Parameters::get<int>("elliptMesh->global refinements").value_or(0) < 4) {
     mtl::io::matrix_market_ostream out("matrix.mtx");
-    out << prob.getSystemMatrix().getMatrix();
+    out << prob.getSystemMatrix().matrix();
 
-    std::cout << prob.getSystemMatrix().getMatrix() << '\n';
+    std::cout << prob.getSystemMatrix().matrix() << '\n';
   }
+#endif
 
   prob.solve(adaptInfo);
   prob.writeFiles(adaptInfo, true);
diff --git a/src/amdis/Assembler.hpp b/src/amdis/Assembler.hpp
index ef99fb52f1cd519f54b83db8a0e34dfd3c7c219c..e487c99f6b2814ea3195cd9de0ca5da46fa843f1 100644
--- a/src/amdis/Assembler.hpp
+++ b/src/amdis/Assembler.hpp
@@ -3,14 +3,9 @@
 #include <memory>
 #include <tuple>
 
-#include <dune/common/fmatrix.hh>
-#include <dune/common/fvector.hh>
-
 #include <amdis/DirichletBC.hpp>
-#include <amdis/LinearAlgebra.hpp>
 #include <amdis/LocalAssemblerList.hpp>
 #include <amdis/common/Mpl.hpp>
-#include <amdis/common/TypeDefs.hpp>
 
 namespace AMDiS
 {
diff --git a/src/amdis/Assembler.inc.hpp b/src/amdis/Assembler.inc.hpp
index f073f40c9c90ddb077b4ad20bc14ac223cc126c3..2854493e03077196120f629a32ecb0fccbca0308 100644
--- a/src/amdis/Assembler.inc.hpp
+++ b/src/amdis/Assembler.inc.hpp
@@ -1,5 +1,7 @@
 #pragma once
 
+#include <dune/common/dynmatrix.hh>
+#include <dune/common/dynvector.hh>
 #include <dune/functions/functionspacebases/subspacebasis.hh>
 #include <amdis/utility/TreePath.hpp>
 #include <amdis/utility/Visitor.hpp>
@@ -24,14 +26,14 @@ void Assembler<Traits>::assemble(
   // 2. create a local matrix and vector
   std::size_t localSize = localView.maxSize();
 
-  Impl::ElementMatrix elementMatrix(localSize, localSize);
-  Impl::ElementVector elementVector(localSize);
+  Dune::DynamicMatrix<double> elementMatrix(localSize, localSize);
+  Dune::DynamicVector<double> elementVector(localSize);
 
   // 3. traverse grid and assemble operators on the elements
   for (auto const& element : elements(globalBasis_.gridView()))
   {
-    set_to_zero(elementMatrix);
-    set_to_zero(elementVector);
+    elementMatrix = 0;
+    elementVector = 0;
 
     localView.bind(element);
     auto geometry = element.geometry();
@@ -75,24 +77,9 @@ void Assembler<Traits>::assemble(
       });
     });
 
-    // add element-matrix to system-matrix
-    for (std::size_t i = 0; i < localView.size(); ++i) {
-      auto const row = localView.index(i);
-      for (std::size_t j = 0; j < localView.size(); ++j) {
-        if (std::abs(elementMatrix(i,j)) > threshold<double>) {
-          auto const col = localView.index(j);
-          matrix(row,col) += elementMatrix(i,j);
-        }
-      }
-    }
-
-    // add element-vector to system-vector
-    for (std::size_t i = 0; i < localView.size(); ++i) {
-      if (std::abs(elementVector[i]) > threshold<double>) {
-        auto const idx = localView.index(i);
-        rhs[idx] += elementVector[i];
-      }
-    }
+    // add element-matrix to system-matrix and element-vector to rhs
+    matrix.insert(localView, localView, elementMatrix);
+    rhs.insert(localView, elementVector);
 
     // unbind all operators
     forEachNode_(localView.tree(), [&,this](auto const& rowNode, auto&&) {
@@ -203,7 +190,7 @@ std::size_t Assembler<Traits>::finishMatrixVector(
     });
   });
 
-  return matrix.getNnz();
+  return matrix.nnz();
 }
 
 } // end namespace AMDiS
diff --git a/src/amdis/DirichletBC.hpp b/src/amdis/DirichletBC.hpp
index 34a281e1c992a40192133583403bac3484a1fa91..30960d343be66ef19a143304054ef5847f032d0c 100644
--- a/src/amdis/DirichletBC.hpp
+++ b/src/amdis/DirichletBC.hpp
@@ -11,12 +11,14 @@
 #include <amdis/Output.hpp>
 #include <amdis/common/Concepts.hpp>
 #include <amdis/common/ValueCategory.hpp>
-#include <amdis/linear_algebra/mtl/MTLDenseVector.hpp>
+#include <amdis/linear_algebra/HierarchicWrapper.hpp>
 #include <amdis/utility/RangeType.hpp>
 #include <amdis/utility/TreeData.hpp>
 
 namespace AMDiS
 {
+  struct BoundaryType { int b; };
+
   /// Implements a boundary condition of Dirichlet-type.
   /**
    * By calling the methods \ref init() and \ref finish before and after
@@ -82,13 +84,13 @@ namespace AMDiS
       using Dune::Functions::interpolate;
       Dune::Hybrid::ifElse(std::is_same<RangeType_t<typename RowBasis::LocalView::Tree>, Range>{},
         [&](auto id) {
-          auto rhsWrapper = wrapper(rhs.getVector());
+          auto rhsWrapper = hierarchicVectorWrapper(rhs.vector());
           interpolate(id(rowBasis), rhsWrapper, values_, dirichletNodes_);
         });
 
       Dune::Hybrid::ifElse(std::is_same<RangeType_t<typename ColBasis::LocalView::Tree>, Range>{},
         [&](auto id) {
-          auto solutionWrapper = wrapper(solution.getVector());
+          auto solutionWrapper = hierarchicVectorWrapper(solution.vector());
           interpolate(id(colBasis), solutionWrapper, values_, dirichletNodes_);
         });
 
diff --git a/src/amdis/DirichletBC.inc.hpp b/src/amdis/DirichletBC.inc.hpp
index 8f4fe3750c62984c61803f26431f50ebc0104730..c2536f44d9a2c2b181694a47395f5d1151e6aa88 100644
--- a/src/amdis/DirichletBC.inc.hpp
+++ b/src/amdis/DirichletBC.inc.hpp
@@ -3,9 +3,6 @@
 #include <dune/functions/functionspacebases/boundarydofs.hh>
 #include <dune/functions/functionspacebases/interpolate.hh>
 #include <dune/functions/functionspacebases/subspacebasis.hh>
-#include <amdis/LinearAlgebra.hpp>
-#include <amdis/linear_algebra/HierarchicWrapper.hpp>
-#include <amdis/linear_algebra/mtl/MTLDenseVector.hpp>
 
 namespace AMDiS
 {
diff --git a/src/amdis/FileWriter.hpp b/src/amdis/FileWriter.hpp
index 50a40c1d7d71969f84d9fe48f62b1a4b336e2a49..7e0686d3fef0c5a45713fc661cf81416406ab04d 100644
--- a/src/amdis/FileWriter.hpp
+++ b/src/amdis/FileWriter.hpp
@@ -43,14 +43,13 @@ namespace AMDiS
   constexpr std::size_t VTKFieldSize = Size<Range>;
 
 
-  template <class Traits, class TreePath>
+  template <class GlobalBasis, class RangeType, class TreePath>
   class FileWriter
       : public FileWriterInterface
   {
   private: // typedefs and static constants
-    using GlobalBasis = typename Traits::GlobalBasis;
     using GridView = typename GlobalBasis::GridView;
-    using Vector = DOFVectorConstView<Traits,TreePath>;
+    using Vector = DOFVectorConstView<GlobalBasis,RangeType,TreePath>;
     using Range = typename Vector::Range;
 
     /// Dimension of the mesh
@@ -123,12 +122,12 @@ namespace AMDiS
   };
 
 
-  template <class Traits, class TreePath>
-  std::shared_ptr<FileWriter<Traits,TreePath>> makeFileWriterPtr(
-      std::string baseName,
-      DOFVectorConstView<Traits,TreePath> const& dofvector)
+  template <class GlobalBasis, class Range, class TreePath>
+  std::shared_ptr<FileWriter<GlobalBasis,Range,TreePath>>
+  makeFileWriterPtr(std::string baseName,
+      DOFVectorConstView<GlobalBasis,Range,TreePath> const& dofvector)
   {
-    return std::make_shared<FileWriter<Traits,TreePath>>(baseName, dofvector);
+    return std::make_shared<FileWriter<GlobalBasis,Range,TreePath>>(baseName, dofvector);
   }
 
 } // end namespace AMDiS
diff --git a/src/amdis/GridFunctionOperator.hpp b/src/amdis/GridFunctionOperator.hpp
index 318506fa12473ce9c561258b8a9f781d4cbb2975..167892ffa6c2c05ef08667453d05cb9ed154e319 100644
--- a/src/amdis/GridFunctionOperator.hpp
+++ b/src/amdis/GridFunctionOperator.hpp
@@ -6,6 +6,7 @@
 #include <amdis/GridFunctions.hpp>
 #include <amdis/LocalOperator.hpp>
 #include <amdis/QuadratureFactory.hpp>
+#include <amdis/common/Transposed.hpp>
 #include <amdis/common/Utility.hpp>
 #include <amdis/utility/FiniteElementType.hpp>
 
@@ -172,7 +173,7 @@ namespace AMDiS
                           ColNode const& colNode,
                           ElementMatrix& elementMatrix)
     {
-      auto elementMatrixTransposed = trans(elementMatrix);
+      auto elementMatrixTransposed = transposed(elementMatrix);
       transposedOp_.getElementMatrix(
         context, colNode, rowNode, elementMatrixTransposed);
     }
diff --git a/src/amdis/LinearAlgebra.hpp b/src/amdis/LinearAlgebra.hpp
index 569c7457b973b15f23645ab52a57761317b6c9d5..d0ec769f15b0ce3d8c9b72a40afc026009218e0b 100644
--- a/src/amdis/LinearAlgebra.hpp
+++ b/src/amdis/LinearAlgebra.hpp
@@ -1,31 +1,16 @@
 #pragma once
 
-#include <amdis/linear_algebra/LinearSolverInterface.hpp>
+#include <amdis/linear_algebra/LinearSolver.hpp>
 #include <amdis/linear_algebra/SolverInfo.hpp>
 
-#if defined(AMDIS_BACKEND_ISTL)
-
-#include <amdis/linear_algebra/istl/SystemVector.hpp>
-#include <amdis/linear_algebra/istl/SystemMatrix.hpp>
-#include <amdis/linear_algebra/istl/LinearSolver.hpp>
-
-#elif defined(AMDIS_BACKEND_MTL)
-
-#include <amdis/linear_algebra/mtl/SystemVector.hpp>
-#include <amdis/linear_algebra/mtl/SystemMatrix.hpp>
-#include <amdis/linear_algebra/mtl/LinearSolver.hpp>
+#if HAVE_MTL
+#include <amdis/linear_algebra/mtl/DOFVector.hpp>
+#include <amdis/linear_algebra/mtl/DOFMatrix.hpp>
 #include <amdis/linear_algebra/mtl/ITL_Solver.hpp>
-#include <amdis/linear_algebra/mtl/BITL_Solver.hpp>
-
-#elif defined(AMDIS_BACKEND_PETSC)
-
-#include <amdis/linear_algebra/petsc/SystemVector.hpp>
-#include <amdis/linear_algebra/petsc/SystemMatrix.hpp>
-#include <amdis/linear_algebra/petsc/LinearSolver.hpp>
-
+#include <amdis/linear_algebra/mtl/ITL_Preconditioner.hpp>
 #else
-
-#error "Unknown linear algebra backend!. Set corresponding variable \
-        AMDIS_BACKEND_ISTL, AMDIS_BACKEND_MTL or AMDIS_BACKEND_PETSC."
-
+#include <amdis/linear_algebra/istl/DOFVector.hpp>
+#include <amdis/linear_algebra/istl/DOFMatrix.hpp>
+#include <amdis/linear_algebra/istl/ISTL_Solver.hpp>
+#include <amdis/linear_algebra/istl/ISTL_Preconditioner.hpp>
 #endif
\ No newline at end of file
diff --git a/src/amdis/LocalAssemblerBase.hpp b/src/amdis/LocalAssemblerBase.hpp
index f6320729f7ddfc14d37557fa8635e03908948379..2504c42c1edb863fa8992202e055829d2b0a6c73 100644
--- a/src/amdis/LocalAssemblerBase.hpp
+++ b/src/amdis/LocalAssemblerBase.hpp
@@ -2,9 +2,10 @@
 
 #include <type_traits>
 
+#include <dune/common/dynmatrix.hh>
+#include <dune/common/dynvector.hh>
+
 #include <amdis/ContextGeometry.hpp>
-// #include <amdis/common/ConceptsBase.hpp>
-#include <amdis/common/TypeDefs.hpp>
 
 namespace AMDiS
 {
@@ -22,10 +23,13 @@ namespace AMDiS
     static_assert( numNodes == 1 || numNodes == 2,
       "VectorAssembler gets 1 Node, MatrixAssembler gets 2 Nodes!");
 
+    using ElementMatrix = Dune::DynamicMatrix<double>; // TODO: choose correct value_type
+    using ElementVector = Dune::DynamicVector<double>;
+
     /// Either an ElementVector or an ElementMatrix (depending on the number of nodes)
     using ElementMatrixVector = std::conditional_t<
-      (sizeof...(Nodes)==1), Impl::ElementVector, std::conditional_t<
-      (sizeof...(Nodes)==2), Impl::ElementMatrix, void>>;
+      (sizeof...(Nodes)==1), ElementVector, std::conditional_t<
+      (sizeof...(Nodes)==2), ElementMatrix, void>>;
 
   public:
     /// Virtual destructor
diff --git a/src/amdis/ProblemInstat.hpp b/src/amdis/ProblemInstat.hpp
index 2a67680284ac7f7943224caaec4a2c9b13a12aae..a61b9b3b55b5e88736fb289a74e5b8b4817c6c83 100644
--- a/src/amdis/ProblemInstat.hpp
+++ b/src/amdis/ProblemInstat.hpp
@@ -60,6 +60,8 @@ namespace AMDiS
     /// Returns \ref oldSolution.
     std::unique_ptr<SystemVector> getOldSolutionVector() const
     {
+      test_exit_dbg(oldSolution,
+        "OldSolution need to be created. Call initialize with INIT_UH_OLD.");
       return *oldSolution;
     }
 
diff --git a/src/amdis/ProblemInstat.inc.hpp b/src/amdis/ProblemInstat.inc.hpp
index e6ee9c7fbad04dfd169026268226e5d647afe9fa..5e93f0e889caf94fec46c4bd1c18675e98b71f5b 100644
--- a/src/amdis/ProblemInstat.inc.hpp
+++ b/src/amdis/ProblemInstat.inc.hpp
@@ -45,7 +45,7 @@ void ProblemInstat<Traits>::createUhOld()
   if (oldSolution)
     warning("oldSolution already created\n");
   else // create oldSolution
-    oldSolution.reset(new SystemVector(problemStat.globalBasis(), name + "_uOld"));
+    oldSolution.reset(new SystemVector(problemStat.globalBasis()));
 }
 
 
@@ -53,7 +53,7 @@ template <class Traits>
 void ProblemInstat<Traits>::initTimestep(AdaptInfo&)
 {
   if (oldSolution)
-    oldSolution->copy(problemStat.getSolutionVector());
+    *oldSolution = problemStat.getSolutionVector();
 }
 
 } // end namespace AMDiS
diff --git a/src/amdis/ProblemStat.hpp b/src/amdis/ProblemStat.hpp
index 9e36f2ca8ddaa34689db11e5d47400ac691a8971..0a53c64db5594422c3182544185357dde60ab29a 100644
--- a/src/amdis/ProblemStat.hpp
+++ b/src/amdis/ProblemStat.hpp
@@ -27,7 +27,6 @@
 #include <amdis/StandardProblemIteration.hpp>
 
 #include <amdis/common/TupleUtility.hpp>
-#include <amdis/common/TypeDefs.hpp>
 #include <amdis/common/Utility.hpp>
 
 #include <amdis/GridFunctions.hpp>
@@ -68,7 +67,7 @@ namespace AMDiS
     static constexpr int dow = Grid::dimensionworld;
 
     using SystemMatrix = DOFMatrix<GlobalBasis, GlobalBasis, double>;
-    using SystemVector = DOFVector<Traits, double>;
+    using SystemVector = DOFVector<GlobalBasis, double>;
 
     using LinearSolverType = LinearSolverInterface<typename SystemMatrix::BaseMatrix, typename SystemVector::BaseVector>;
 
@@ -275,9 +274,9 @@ namespace AMDiS
 
     void createMatricesAndVectors()
     {
-      systemMatrix_ = std::make_shared<SystemMatrix>(*globalBasis_, *globalBasis_, "mat");
-      solution_ = std::make_shared<SystemVector>(*globalBasis_, "solution");
-      rhs_ = std::make_shared<SystemVector>(*globalBasis_, "rhs");
+      systemMatrix_ = std::make_shared<SystemMatrix>(*globalBasis_, *globalBasis_);
+      solution_ = std::make_shared<SystemVector>(*globalBasis_);
+      rhs_ = std::make_shared<SystemVector>(*globalBasis_);
 
       AMDiS::forEachNode_(localView_->tree(), [&,this](auto const& node, auto treePath)
       {
@@ -286,8 +285,6 @@ namespace AMDiS
         for (std::size_t j = 0; j < estimates_[i].size(); j++)
           estimates_[i][j] = 0.0; // TODO: Remove when estimate() is implemented
       });
-
-      rhs_ = std::make_shared<SystemVector>(*globalBasis_, "rhs");
     }
 
     void createSolver()
diff --git a/src/amdis/ProblemStat.inc.hpp b/src/amdis/ProblemStat.inc.hpp
index 92a7b2155a095f204eea5f93351a73925bec6fc7..833b31c882d8ba0e9d665f100a2d564af54da3a0 100644
--- a/src/amdis/ProblemStat.inc.hpp
+++ b/src/amdis/ProblemStat.inc.hpp
@@ -281,7 +281,7 @@ solve(AdaptInfo& adaptInfo, bool createMatrixData, bool storeMatrixData)
 
   solution_->compress();
 
-  linearSolver_->solve(systemMatrix_->getMatrix(), solution_->getVector(), rhs_->getVector(),
+  linearSolver_->solve(systemMatrix_->matrix(), solution_->vector(), rhs_->vector(),
                       solverInfo);
 
   if (solverInfo.getInfo() > 0) {
diff --git a/src/amdis/common/CMakeLists.txt b/src/amdis/common/CMakeLists.txt
index 03492346bd8b0e507998ca66b8be429a9b1f9a94..7b4b4ac25b8cc8d50d016821c0f0c2bfb9565e00 100644
--- a/src/amdis/common/CMakeLists.txt
+++ b/src/amdis/common/CMakeLists.txt
@@ -18,8 +18,8 @@ install(FILES
     ScalarTypes.hpp
     Size.hpp
     Tags.hpp
+    Transposed.hpp
     TupleUtility.hpp
-    TypeDefs.hpp
     Utility.hpp
     ValueCategory.hpp
 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/amdis/common)
diff --git a/src/amdis/common/Math.hpp b/src/amdis/common/Math.hpp
index 555d1585c0cbb0cb97bd83e727f7afa681845834..9897ad0c7898ec30295d730648b2ad83a7d420af 100644
--- a/src/amdis/common/Math.hpp
+++ b/src/amdis/common/Math.hpp
@@ -118,7 +118,7 @@ namespace AMDiS
   }
 
   template <class T>
-  constexpr T threshold = T(1.e-18L); //Math::sqr(std::numeric_limits<T>::epsilon());
+  constexpr T threshold = std::numeric_limits<T>::epsilon();
 
 
   /// Calculates factorial of i
diff --git a/src/amdis/common/Transposed.hpp b/src/amdis/common/Transposed.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4778e95f956c1ee1635e7d7ab18a5271a47faed5
--- /dev/null
+++ b/src/amdis/common/Transposed.hpp
@@ -0,0 +1,79 @@
+#pragma once
+
+#include <type_traits>
+
+namespace AMDiS
+{
+  /// \brief The transposed view onto a matrix
+  template <class Matrix>
+  class TransposedMatrix
+  {
+    using RawMatrix = std::decay_t<Matrix>;
+
+  public:
+    using size_type = typename RawMatrix::size_type;
+    using value_type = typename RawMatrix::value_type;
+
+  private:
+    struct ConstRowProxy
+    {
+      RawMatrix const* mat;
+      size_type row;
+
+      value_type const& operator[](size_type col) const
+      {
+        return (*mat)[col][row];
+      }
+    };
+
+    struct MutableRowProxy
+    {
+      RawMatrix* mat;
+      size_type row;
+
+      value_type& operator[](size_type col)
+      {
+        return (*mat)[col][row];
+      }
+    };
+
+  public:
+    template <class M>
+    TransposedMatrix(M&& matrix)
+      : matrix_(std::forward<M>(matrix))
+    {}
+
+    ConstRowProxy operator[](size_type row) const
+    {
+      return ConstRowProxy{&matrix_, row};
+    }
+
+    template <class M = Matrix,
+      std::enable_if_t<not std::is_const<M>::value, int> = 0>
+    MutableRowProxy operator[](size_type row)
+    {
+      return MutableRowProxy{&matrix_, row};
+    }
+
+    size_type N() const
+    {
+      return matrix_.M();
+    }
+
+    size_type M() const
+    {
+      return matrix_.N();
+    }
+
+  private:
+    Matrix& matrix_;
+  };
+
+  template <class Matrix>
+  auto transposed(Matrix&& matrix)
+  {
+    using M = std::remove_reference_t<Matrix>;
+    return TransposedMatrix<M>{std::forward<Matrix>(matrix)};
+  }
+
+} // end namespace AMDiS
diff --git a/src/amdis/common/TypeDefs.hpp b/src/amdis/common/TypeDefs.hpp
deleted file mode 100644
index 735d9cb6a50b7022c0ef0b414b8ed850a5f194ba..0000000000000000000000000000000000000000
--- a/src/amdis/common/TypeDefs.hpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-#include <type_traits>
-
-#include <amdis/linear_algebra/Mtl.hpp>
-
-namespace AMDiS
-{
-  namespace Impl
-  {
-    using ElementVector = mtl::dense_vector<double>;
-    using ElementMatrix = mtl::dense2D<double>;
-
-    using SystemVector = mtl::dense_vector<double>;
-    using SystemMatrix = mtl::compressed2D<double>;
-
-  } // end namespace Impl
-
-  struct BoundaryType { int b; };
-
-} // end namespace AMDiS
diff --git a/src/amdis/gridfunctions/DOFVectorView.hpp b/src/amdis/gridfunctions/DOFVectorView.hpp
index 0cfccfc24e91911cdb18f4ec96b69cda4d50ca34..86b52e7e7771030973eeae3b3a83932e9672cd47 100644
--- a/src/amdis/gridfunctions/DOFVectorView.hpp
+++ b/src/amdis/gridfunctions/DOFVectorView.hpp
@@ -20,13 +20,12 @@ namespace AMDiS
     * @{
     **/
 
-  template <class Traits, class TreePathType>
+  template <class GlobalBasisType, class RangeType, class TreePathType>
   class DOFVectorConstView
   {
   public:
-    using GlobalBasis = typename Traits::GlobalBasis;
+    using GlobalBasis = GlobalBasisType;
     using TreePath = TreePathType;
-    using Vector = DOFVector<Traits>;
 
     using Tree = typename GlobalBasis::LocalView::Tree;
     using SubTree = typename Dune::TypeTree::ChildForTreePath<Tree, TreePath>;
@@ -37,6 +36,8 @@ namespace AMDiS
 
     using Domain = typename EntitySet::GlobalCoordinate;
     using Range = RangeType_t<SubTree>;
+    static_assert(std::is_arithmetic<RangeType>::value, "");
+    // Don't know how to determine Range with non-trivial RangeType
 
     using RawSignature = typename Dune::Functions::SignatureTraits<Range(Domain)>::RawSignature;
     using DerivativeTraits = Dune::Functions::DefaultDerivativeTraits<RawSignature>;
@@ -201,11 +202,11 @@ namespace AMDiS
 
   public:
     /// Constructor. Stores a pointer to the dofVector and a copy of the treePath.
-    DOFVectorConstView(DOFVector<Traits> const& dofVector, TreePath const& treePath)
+    DOFVectorConstView(DOFVector<GlobalBasis,RangeType> const& dofVector, TreePath const& treePath)
       : dofVector_(&dofVector)
       , treePath_(treePath)
-      , entitySet_(dofVector.getFeSpace().gridView())
-      , nodeToRangeEntry_(Dune::Functions::makeDefaultNodeToRangeMap(dofVector.getFeSpace(), treePath))
+      , entitySet_(dofVector.basis().gridView())
+      , nodeToRangeEntry_(Dune::Functions::makeDefaultNodeToRangeMap(dofVector.basis(), treePath))
     {}
 
     /// Evaluate the view on this DOFVector in global coordinates
@@ -230,7 +231,7 @@ namespace AMDiS
     /// Return global basis
     GlobalBasis const& basis() const
     {
-      return dofVector_->getFeSpace();
+      return dofVector_->basis();
     }
 
     /// Return treePath associated with this view
@@ -240,13 +241,13 @@ namespace AMDiS
     }
 
     /// Return const coefficient vector
-    DOFVector<Traits> const& coefficients() const
+    DOFVector<GlobalBasis,RangeType> const& coefficients() const
     {
       return *dofVector_;
     }
 
   protected:
-    DOFVector<Traits> const* dofVector_;
+    DOFVector<GlobalBasis,RangeType> const* dofVector_;
     TreePath const treePath_;
 
     EntitySet entitySet_;
@@ -255,18 +256,18 @@ namespace AMDiS
 
 
   // A mutable version of DOFVectorView
-  template <class Traits, class TreePathType>
+  template <class GlobalBasisType, class RangeType, class TreePathType>
   class DOFVectorMutableView
-      : public DOFVectorConstView<Traits, TreePathType>
+      : public DOFVectorConstView<GlobalBasisType, RangeType, TreePathType>
   {
-    using Super = DOFVectorConstView<Traits, TreePathType>;
+    using Super = DOFVectorConstView<GlobalBasisType, RangeType, TreePathType>;
 
-    using GlobalBasis = typename Traits::GlobalBasis;
+    using GlobalBasis = GlobalBasisType;
     using TreePath = TreePathType;
 
   public:
     /// Constructor. Stores a pointer to the mutable `dofvector`.
-    DOFVectorMutableView(DOFVector<Traits>& dofVector, TreePath const& treePath)
+    DOFVectorMutableView(DOFVector<GlobalBasis,RangeType>& dofVector, TreePath const& treePath)
       : Super(dofVector, treePath)
       , mutableDofVector_(&dofVector)
     {}
@@ -281,11 +282,11 @@ namespace AMDiS
 
       auto&& gridFct = makeGridFunction(std::forward<Expr>(expr), basis.gridView());
 
-      DOFVector<Traits> tmp(basis, "tmp");
+      DOFVector<GlobalBasis,RangeType> tmp(*mutableDofVector_);
       Dune::Functions::interpolate(basis, treePath, tmp, std::forward<decltype(gridFct)>(gridFct));
 
       // move data from temporary vector into stored DOFVector
-      mutableDofVector_->getVector() = std::move(tmp.getVector());
+      mutableDofVector_->vector() = std::move(tmp.vector());
       return *this;
     }
 
@@ -297,13 +298,13 @@ namespace AMDiS
 
 
     /// Return the mutable DOFVector
-    DOFVector<Traits>& coefficients() { return *mutableDofVector_; }
+    DOFVector<GlobalBasis,RangeType>& coefficients() { return *mutableDofVector_; }
 
     /// Return the const DOFVector
     using Super::coefficients;
 
   protected:
-    DOFVector<Traits>* mutableDofVector_;
+    DOFVector<GlobalBasis,RangeType>* mutableDofVector_;
   };
 
   /** @} **/
@@ -311,34 +312,34 @@ namespace AMDiS
 
 #ifndef DOXYGEN
   // A Generator for a const \ref DOFVectorView.
-  template <class Traits, class TreePath>
-  auto makeDOFVectorView(DOFVector<Traits> const& dofVector, TreePath const& treePath)
+  template <class GlobalBasis, class RangeType, class TreePath>
+  auto makeDOFVectorView(DOFVector<GlobalBasis, RangeType> const& dofVector, TreePath const& treePath)
   {
-    return DOFVectorConstView<Traits, TreePath>{dofVector, treePath};
+    return DOFVectorConstView<GlobalBasis, RangeType, TreePath>{dofVector, treePath};
   }
 
   // A Generator for a mutable \ref DOFVectorView.
-  template <class Traits, class TreePath>
-  auto makeDOFVectorView(DOFVector<Traits>& dofVector, TreePath const& treePath)
+  template <class GlobalBasis, class RangeType, class TreePath>
+  auto makeDOFVectorView(DOFVector<GlobalBasis, RangeType>& dofVector, TreePath const& treePath)
   {
-    return DOFVectorMutableView<Traits, TreePath>{dofVector, treePath};
+    return DOFVectorMutableView<GlobalBasis, RangeType, TreePath>{dofVector, treePath};
   }
 
 
   // A Generator for a const \ref DOFVectorView.
-  template <class Traits>
-  auto makeDOFVectorView(DOFVector<Traits> const& dofVector)
+  template <class GlobalBasis, class RangeType>
+  auto makeDOFVectorView(DOFVector<GlobalBasis, RangeType> const& dofVector)
   {
     auto treePath = Dune::TypeTree::hybridTreePath();
-    return DOFVectorConstView<Traits, decltype(treePath)>{dofVector, treePath};
+    return DOFVectorConstView<GlobalBasis, RangeType, decltype(treePath)>{dofVector, treePath};
   }
 
   // A Generator for a mutable \ref DOFVectorView.
-  template <class Traits>
-  auto makeDOFVectorView(DOFVector<Traits>& dofVector)
+  template <class GlobalBasis, class RangeType>
+  auto makeDOFVectorView(DOFVector<GlobalBasis, RangeType>& dofVector)
   {
     auto treePath = Dune::TypeTree::hybridTreePath();
-    return DOFVectorMutableView<Traits, decltype(treePath)>{dofVector, treePath};
+    return DOFVectorMutableView<GlobalBasis, RangeType, decltype(treePath)>{dofVector, treePath};
   }
 #endif
 
diff --git a/src/amdis/gridfunctions/DOFVectorView.inc.hpp b/src/amdis/gridfunctions/DOFVectorView.inc.hpp
index a97dc1a47b1922b0db421f80b19468858a4f2076..139a1ab4c98883747d4882eee5bac08975a663ea 100644
--- a/src/amdis/gridfunctions/DOFVectorView.inc.hpp
+++ b/src/amdis/gridfunctions/DOFVectorView.inc.hpp
@@ -4,8 +4,8 @@
 
 namespace AMDiS {
 
-template <class Traits, class TreePath>
-typename DOFVectorConstView<Traits, TreePath>::Range DOFVectorConstView<Traits, TreePath>::
+template <class GB, class RT, class TP>
+typename DOFVectorConstView<GB,RT,TP>::Range DOFVectorConstView<GB,RT,TP>::
 LocalFunction::operator()(LocalDomain const& x) const
 {
   assert( bound_ );
@@ -48,8 +48,8 @@ LocalFunction::operator()(LocalDomain const& x) const
 }
 
 
-template <class Traits, class TreePath>
-typename DOFVectorConstView<Traits, TreePath>::DerivativeRange DOFVectorConstView<Traits, TreePath>::
+template <class GB, class RT, class TP>
+typename DOFVectorConstView<GB,RT,TP>::DerivativeRange DOFVectorConstView<GB,RT,TP>::
 GradientLocalFunction::operator()(LocalDomain const& x) const
 {
   assert( bound_ );
diff --git a/src/amdis/linear_algebra/CMakeLists.txt b/src/amdis/linear_algebra/CMakeLists.txt
index 200338d51155f07071e20d69efbbafe1ab409853..ff79554f15af37891a18244704545418050e4a33 100644
--- a/src/amdis/linear_algebra/CMakeLists.txt
+++ b/src/amdis/linear_algebra/CMakeLists.txt
@@ -1,10 +1,12 @@
 #install headers
 
 install(FILES
+    Common.hpp
+    DOFMatrixBase.hpp
+    DOFVectorBase.hpp
+    DOFVectorInterface.hpp
     HierarchicWrapper.hpp
-    LinearAlgebraBase.hpp
     LinearSolverInterface.hpp
-    Mtl.hpp
     PreconditionerInterface.hpp
     RunnerInterface.hpp
     SolverInfo.hpp
diff --git a/src/amdis/linear_algebra/Common.hpp b/src/amdis/linear_algebra/Common.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e7bf16d923776bf233d6114d4706986d9929d9b3
--- /dev/null
+++ b/src/amdis/linear_algebra/Common.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <cstddef>
+
+namespace AMDiS
+{
+  template <class T>
+  struct Triplet
+  {
+    std::size_t row, cols;
+    T value;
+  };
+
+} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/DOFMatrixBase.hpp b/src/amdis/linear_algebra/DOFMatrixBase.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9080a167cf70a842aaef3dbad509b17db985e851
--- /dev/null
+++ b/src/amdis/linear_algebra/DOFMatrixBase.hpp
@@ -0,0 +1,122 @@
+#pragma once
+
+#include <cmath>
+#include <amdis/common/Math.hpp>
+
+namespace AMDiS
+{
+  template <class RowBasisType, class ColBasisType, class Backend>
+  class DOFMatrixBase
+  {
+  public:
+    /// The type of the finite element space / basis of the row
+    using RowBasis = RowBasisType;
+
+    /// The type of the finite element space / basis of the column
+    using ColBasis = ColBasisType;
+
+    /// The index/size - type
+    using size_type = typename RowBasis::size_type;
+
+    using BaseMatrix = typename Backend::BaseMatrix;
+
+  public:
+    /// Constructor. Constructs new BaseVector.
+    DOFMatrixBase(RowBasis const& rowBasis, ColBasis const& colBasis)
+      : rowBasis_(&rowBasis)
+      , colBasis_(&colBasis)
+    {}
+
+    /// Return the row-basis \ref rowBasis of the matrix
+    RowBasis const& rowBasis() const
+    {
+      return *rowBasis_;
+    }
+
+    /// Return the col-basis \ref colBasis of the matrix
+    ColBasis const& colBasis() const
+    {
+      return *colBasis_;
+    }
+
+    /// Return the data-matrix
+    BaseMatrix const& matrix() const
+    {
+      return backend_.matrix();
+    }
+
+    /// Return the data-matrix
+    BaseMatrix& matrix()
+    {
+      return backend_.matrix();
+    }
+
+    /// Return the size of the \ref rowBasis_
+    size_type rows() const
+    {
+      return rowBasis_->dimension();
+    }
+
+    /// Return the size of the \ref colBasis_
+    size_type cols() const
+    {
+      return colBasis_->dimension();
+    }
+
+    /// Initialize the matrix for insertion, e.g. allocate the non-zero pattern
+    /// If \p setToZero is true, the matrix is set to 0
+    void init(bool setToZero)
+    {
+      backend_.init(*rowBasis_, *colBasis_, setToZero);
+    }
+
+    /// Finish the matrix insertion, e.g. cleanup or final insertion
+    void finish()
+    {
+      backend_.finish();
+    }
+
+    /// Insert a block of values into the matrix (add to existing values)
+    template <class ElementMatrix>
+    void insert(typename RowBasis::LocalView const& rowLocalView,
+                typename ColBasis::LocalView const& colLocalView,
+                ElementMatrix const& elementMatrix)
+    {
+      for (size_type i = 0; i < rowLocalView.size(); ++i) {
+        size_type const row = flatMultiIndex(rowLocalView.index(i));
+        for (size_type j = 0; j < colLocalView.size(); ++j) {
+          if (std::abs(elementMatrix[i][j]) > threshold<double>) {
+            size_type const col = flatMultiIndex(colLocalView.index(j));
+            backend_.insert(row, col, elementMatrix[i][j]);
+          }
+        }
+      }
+    }
+
+    /// Insert a single value into the matrix (add to existing value)
+    template <class RowIndex, class ColIndex>
+    void insert(RowIndex row, ColIndex col, typename Backend::value_type const& value)
+    {
+      backend_.insert(flatMultiIndex(row), flatMultiIndex(col), value);
+    }
+
+    /// \brief Deletes all rows with \p dirichletNodes != 0 and if \p apply is true, adds
+    /// a one on the diagonal of the matrix.
+    auto applyDirichletBC(std::vector<char> const& dirichletNodes)
+    {
+      return backend_.applyDirichletBC(dirichletNodes);
+    }
+
+    size_type nnz() const
+    {
+      return backend_.nnz();
+    }
+
+  protected:
+    RowBasis const*	rowBasis_;
+    ColBasis const*	colBasis_;
+
+    Backend backend_;
+  };
+
+} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/DOFVectorBase.hpp b/src/amdis/linear_algebra/DOFVectorBase.hpp
index 2b3902eed018517804ee296c1ba3f36288269f73..33fa8ea8277796806c2c4dbebd00de08fff58c0c 100644
--- a/src/amdis/linear_algebra/DOFVectorBase.hpp
+++ b/src/amdis/linear_algebra/DOFVectorBase.hpp
@@ -1,30 +1,124 @@
 #pragma once
 
+#include <cmath>
+
+#include <dune/functions/functionspacebases/sizeinfo.hh>
+
+#include <amdis/common/Math.hpp>
+#include <amdis/common/ScalarTypes.hpp>
+#include <amdis/linear_algebra/DOFVectorInterface.hpp>
+#include <amdis/utility/MultiIndex.hpp>
+
 namespace AMDiS
 {
-  template <class GlobalBasisType>
+  /// The basic container that stores a base vector and a corresponding basis
+  template <class BasisType, class Backend>
   class DOFVectorBase
+      : public DOFVectorInterface
   {
+    using Self = DOFVectorBase;
+
+  public:
+    /// The type of the \ref basis
+    using Basis = BasisType;
+
+    /// The index/size - type
+    using size_type  = typename BasisType::size_type;
+
+    /// The type of the elements of the DOFVector
+    using value_type = typename Backend::value_type;
+
+    using BaseVector = typename Backend::BaseVector;
+
   public:
-    using GlobalBasis = GlobalBasisType;
-    using SizeType = std::size_t;
+    /// Constructor. Constructs new BaseVector.
+    DOFVectorBase(BasisType const& basis)
+      : basis_(&basis)
+    {
+      compress();
+    }
 
-    DOFVectorBase(GlobalBasisType const& basis)
-      : basis_(basis)
-    {}
+    /// Return the basis \ref basis_ associated to the vector
+    Basis const& basis() const
+    {
+      return *basis_;
+    }
 
-    SizeType size() const
+    /// Return the data-vector
+    BaseVector const& vector() const
     {
-      return basis_.dimension();
+      return backend_.vector();
     }
 
-    GlobalBasis const& basis() const
+    /// Return the data-vector
+    BaseVector& vector()
     {
-      return GlobalBasis;
+      return backend_.vector();
+    }
+
+    /// Return the size of the \ref basis
+    size_type size() const
+    {
+      return basis_->dimension();
+    }
+
+    void resize(Dune::Functions::SizeInfo<Basis> const& s)
+    {
+      backend_.resize(size_type(s));
+    }
+
+    /// Resize the \ref vector to the size of the \ref basis.
+    virtual void compress() override
+    {
+      if (backend_.size() != size()) {
+        backend_.resize(size());
+        vector() = 0;
+      }
+    }
+
+    /// Access the entry \p idx of the \ref vector with read-access.
+    template <class Index>
+    auto const& operator[](Index idx) const
+    {
+      size_type i = flatMultiIndex(idx);
+      return backend_[i];
+    }
+
+    /// Access the entry \p idx of the \ref vector with write-access.
+    template <class Index>
+    auto& operator[](Index idx)
+    {
+      size_type i = flatMultiIndex(idx);
+      return backend_[i];
+    }
+
+    /// Insert a block of values into the matrix (add to existing values)
+    template <class ElementVector>
+    void insert(typename Basis::LocalView const& localView,
+                ElementVector const& elementVector)
+    {
+      for (size_type i = 0; i < localView.size(); ++i) {
+        if (std::abs(elementVector[i]) > threshold<double>) {
+          size_type const idx = flatMultiIndex(localView.index(i));
+          backend_[idx] += elementVector[i];
+        }
+      }
+    }
+
+    /// Sets each DOFVector to the scalar \p value.
+    template <class Scalar,
+      std::enable_if_t<Concepts::Arithmetic<Scalar>, int> = 0>
+    Self& operator=(Scalar value)
+    {
+      vector() = value;
+      return *this;
     }
 
   private:
-    GlobalBasis const& basis_;
+    /// The finite element space / basis associated with the data vector
+    Basis const* basis_;
+
+    Backend backend_;
   };
 
 } // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/DOFVectorInterface.hpp b/src/amdis/linear_algebra/DOFVectorInterface.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f2b5aa84301a305ff5682f01582793410d633132
--- /dev/null
+++ b/src/amdis/linear_algebra/DOFVectorInterface.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+namespace AMDiS
+{
+  class DOFVectorInterface
+  {
+  public:
+    /// Virtual destructor
+    ~DOFVectorInterface() = default;
+
+    /// Change dimension of DOFVector to dimension of basis
+    virtual void compress() = 0;
+  };
+
+} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/HierarchicWrapper.hpp b/src/amdis/linear_algebra/HierarchicWrapper.hpp
index 94617e6de355bc2fbd9b7bb8ea3953fad3abb998..79f1f4c1b576b65bcffe2787fd35cf0deb536a6e 100644
--- a/src/amdis/linear_algebra/HierarchicWrapper.hpp
+++ b/src/amdis/linear_algebra/HierarchicWrapper.hpp
@@ -1,5 +1,9 @@
 #pragma once
 
+#if HAVE_MTL
+#include <boost/numeric/mtl/mtl_fwd.hpp>
+#endif
+
 #include <dune/functions/functionspacebases/sizeinfo.hh>
 
 #include <amdis/utility/MultiIndex.hpp>
@@ -85,11 +89,13 @@ namespace AMDiS
       vec.change_dim(std::size_t(s));
     }
 
+#if HAVE_MTL
     template <class... Params>
-    std::size_t sizeImpl(mtl::dense_vector<Params...> const& v) const
+    std::size_t sizeImpl(mtl::vec::dense_vector<Params...> const& v) const
     {
       return mtl::size(v);
     }
+#endif
 
     template <class V>
     using HasSizeMember = decltype(std::declval<V>().size());
diff --git a/src/amdis/linear_algebra/LinearAlgebraBase.hpp b/src/amdis/linear_algebra/LinearAlgebraBase.hpp
deleted file mode 100644
index 41c3d1601381e12200481f63d4ea7c23ac205a3c..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/LinearAlgebraBase.hpp
+++ /dev/null
@@ -1,65 +0,0 @@
-#pragma once
-
-namespace AMDiS
-{
-  namespace Impl
-  {
-    // Type-Trait needs to be specialized by linear algebra libraries
-    template <class Vector>
-    struct BaseVector { using type = Vector; };
-
-    template <class Matrix>
-    struct BaseMatrix { using type = Matrix; };
-  }
-
-  template <class Vector>
-  using BaseVector_t = typename Impl::BaseVector<Vector>::type;
-
-  template <class Matrix>
-  using BaseMatrix_t = typename Impl::BaseMatrix<Matrix>::type;
-
-  template <class T>
-  struct Triplet
-  {
-    std::size_t row;
-    std::size_t col;
-    T value;
-  };
-
-  namespace Impl
-  {
-    template <class Vector>
-    class BaseWrapper
-    {
-    public:
-      using value_type = typename Vector::value_type;
-      using size_type = typename Vector::size_type;
-
-      explicit BaseWrapper(Vector& vec) : vec(vec) {}
-
-      void resize(size_type s)
-      {
-        vec.resize(s);
-      }
-
-      size_type size() const
-      {
-        return vec.size();
-      }
-
-      value_type&       operator[](size_type i)       { return vec[i]; }
-      value_type const& operator[](size_type i) const { return vec[i]; }
-
-    protected:
-      Vector& vec;
-    };
-
-  } // end namespace Impl
-
-  template <class Vector>
-  Impl::BaseWrapper<std::remove_reference_t<Vector>> wrapper(Vector&& vec)
-  {
-    return {std::forward<Vector>(vec)};
-  }
-
-} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/mtl/LinearSolver.hpp b/src/amdis/linear_algebra/LinearSolver.hpp
similarity index 57%
rename from src/amdis/linear_algebra/mtl/LinearSolver.hpp
rename to src/amdis/linear_algebra/LinearSolver.hpp
index b8a1f70e1a1929b999d6f9abd35c5d603ec14751..b132ef31ba780e5591000c50bf304a5848b29837 100644
--- a/src/amdis/linear_algebra/mtl/LinearSolver.hpp
+++ b/src/amdis/linear_algebra/LinearSolver.hpp
@@ -8,25 +8,24 @@
 #include <amdis/CreatorInterface.hpp>
 #include <amdis/Output.hpp>
 #include <amdis/linear_algebra/LinearSolverInterface.hpp>
-#include <amdis/linear_algebra/mtl/BlockMTLVector.hpp>
 
 namespace AMDiS
 {
   /** \ingroup Solver
    *
    * \brief
-   * Wrapper class for various MTL4 solvers. These solvers
+   * Wrapper class for various solvers. These solvers
    * are parametrized by MatrixType and VectorType. The different
    * algorithms, like krylov subspace methods or other external
-   * solvers where MTL4 provides an interface, can be assigned
+   * solvers where the backend provides an interface, can be assigned
    * by different Runner objects.
    **/
-  template <class Matrix, class Vector, class Runner>
+  template <class Matrix, class VectorX, class VectorB, class Runner>
   class LinearSolver
-      : public LinearSolverInterface<Matrix, Vector, Vector>
+      : public LinearSolverInterface<Matrix, VectorX, VectorB>
   {
     using Self = LinearSolver;
-    using Super = LinearSolverInterface<Matrix, Vector, Vector>;
+    using Super = LinearSolverInterface<Matrix, VectorX, VectorB>;
     using RunnerBase = typename Super::RunnerBase;
 
   public:
@@ -42,44 +41,39 @@ namespace AMDiS
   public:
     /// Constructor
     explicit LinearSolver(std::string prefix)
-      : runner(std::make_shared<Runner>(prefix))
+      : runner_(std::make_shared<Runner>(prefix))
     {}
 
-    /// Implements \ref LinearSolverInterface::getRunner()
-    virtual std::shared_ptr<RunnerBase> getRunner() override
+    /// Implements \ref LinearSolverInterface::runner()
+    virtual std::shared_ptr<RunnerBase> runner() override
     {
-      return runner;
+      return runner_;
     }
 
   private:
     /// Implements \ref LinearSolverInterface::solveSystemImpl()
-    virtual void solveImpl(Matrix const& A, Vector& x, Vector const& b,
+    virtual void solveImpl(Matrix const& A, VectorX& x, VectorB const& b,
                            SolverInfo& solverInfo) override
     {
       Dune::Timer t;
       if (solverInfo.doCreateMatrixData()) {
         // init matrix or wrap block-matrix or ...
-        runner->init(A);
+        runner_->init(A);
       }
 
-      // wrappers copy the data back on destruction
-      auto X = blockWrapper(x);
-      auto B = blockWrapper(b);
+      if (solverInfo.getInfo() > 0)
+        msg("fill matrix needed ", t.elapsed(), " seconds");
 
-      if (solverInfo.getInfo() > 0) {
-        msg("fill MTL4 matrix needed ", t.elapsed(), " seconds");
-      }
-
-      int error = runner->solve(A, X.getVector(), B.getVector(), solverInfo);
+      int error = runner_->solve(A, x, b, solverInfo);
       solverInfo.setError(error);
 
       if (!solverInfo.doStoreMatrixData())
-        runner->exit();
+        runner_->exit();
     }
 
   private:
     /// redirect the implementation to a runner. Implements a \ref RunnerInterface
-    std::shared_ptr<Runner> runner;
+    std::shared_ptr<Runner> runner_;
   };
 
 } // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/LinearSolverInterface.hpp b/src/amdis/linear_algebra/LinearSolverInterface.hpp
index 5d1534f9f522db80170bdd3ee36bea85d25d56cd..54228ef66b9004fd42e0c2c9d1b8907f24cf0d4f 100644
--- a/src/amdis/linear_algebra/LinearSolverInterface.hpp
+++ b/src/amdis/linear_algebra/LinearSolverInterface.hpp
@@ -12,7 +12,6 @@
  */
 
 #include <amdis/common/Utility.hpp>
-#include <amdis/linear_algebra/LinearAlgebraBase.hpp>
 
 #include <amdis/linear_algebra/PreconditionerInterface.hpp>
 #include <amdis/linear_algebra/RunnerInterface.hpp>
@@ -25,12 +24,11 @@ namespace AMDiS
   class LinearSolverInterface
   {
   protected:
-    using RunnerBase = RunnerInterface<Matrix, BaseVector_t<VectorX>,
-                                               BaseVector_t<VectorB>>;
+    using RunnerBase = RunnerInterface<Matrix, VectorX, VectorB>;
 
   public:
     /// Destructor.
-    virtual ~LinearSolverInterface() {}
+    virtual ~LinearSolverInterface() = default;
 
     /// Public method to call in order to solve a linear system Ax = b.
     /**
@@ -45,12 +43,11 @@ namespace AMDiS
     void solve(Matrix const& A, VectorX& x, VectorB const& b,
                SolverInfo& solverInfo)
     {
-      assert( num_cols(A) == size(x) && num_rows(A) == size(b) );
       solveImpl(A, x, b, solverInfo);
     }
 
     // return the runner/worker corresponding to this solver (optional)
-    virtual std::shared_ptr<RunnerBase> getRunner() { return {}; };
+    virtual std::shared_ptr<RunnerBase> runner() { return {}; };
 
   private:
     /// main methods that all solvers must implement
diff --git a/src/amdis/linear_algebra/Mtl.hpp b/src/amdis/linear_algebra/Mtl.hpp
deleted file mode 100644
index 5d89ea427fd21f3cd57d2926100c19586478b532..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/Mtl.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-
-#include <dune/common/ftraits.hh>
-
-#include <boost/numeric/mtl/matrix/compressed2D.hpp>
-#include <boost/numeric/mtl/matrix/dense2D.hpp>
-#include <boost/numeric/mtl/vector/dense_vector.hpp>
-
-namespace Dune
-{
-  template <class Elt, class Parameters>
-  struct FieldTraits<mtl::compressed2D<Elt,Parameters>>
-  {
-    using field_type = typename FieldTraits<Elt>::field_type;
-    using real_type = typename FieldTraits<Elt>::real_type;
-  };
-
-  template <class Value, class Parameters>
-  struct FieldTraits<mtl::dense2D<Value,Parameters>>
-  {
-    using field_type = typename FieldTraits<Value>::field_type;
-    using real_type = typename FieldTraits<Value>::real_type;
-  };
-
-  template <class Value, class Parameters>
-  struct FieldTraits<mtl::dense_vector<Value,Parameters>>
-  {
-    using field_type = typename FieldTraits<Value>::field_type;
-    using real_type = typename FieldTraits<Value>::real_type;
-  };
-
-} // end namespace Dune
diff --git a/src/amdis/linear_algebra/PreconditionerInterface.hpp b/src/amdis/linear_algebra/PreconditionerInterface.hpp
index 692a35250d904b2b5e63bf71f261ffdceaee705f..055ee01b886b6ee3e600583b811fc00c869c6265 100644
--- a/src/amdis/linear_algebra/PreconditionerInterface.hpp
+++ b/src/amdis/linear_algebra/PreconditionerInterface.hpp
@@ -7,7 +7,7 @@ namespace AMDiS
   struct PreconditionerInterface
   {
     /// Virtual destructor.
-    virtual ~PreconditionerInterface() {}
+    virtual ~PreconditionerInterface() = default;
 
     /// Is called a the beginning of a solution procedure
     virtual void init(Matrix const& fullMatrix) = 0;
diff --git a/src/amdis/linear_algebra/RunnerInterface.hpp b/src/amdis/linear_algebra/RunnerInterface.hpp
index 0c81227ce650ab7b3a18929dc7c0e9480bc5aa89..ae7fc03da6e7f36ff8de4cd2a474f6ad93e1b889 100644
--- a/src/amdis/linear_algebra/RunnerInterface.hpp
+++ b/src/amdis/linear_algebra/RunnerInterface.hpp
@@ -14,7 +14,7 @@ namespace AMDiS
 
   public:
     /// virtual destructor
-    virtual ~RunnerInterface() {}
+    virtual ~RunnerInterface() = default;
 
     /// Is called at the beginning of a solution procedure
     virtual void init(Matrix const& A) = 0;
@@ -34,8 +34,8 @@ namespace AMDiS
       return 0;
     }
 
-    virtual std::shared_ptr<PreconBase> getLeftPrecon() { return {}; }
-    virtual std::shared_ptr<PreconBase> getRightPrecon() { return {}; }
+    virtual std::shared_ptr<PreconBase> leftPrecon() { return {}; }
+    virtual std::shared_ptr<PreconBase> rightPrecon() { return {}; }
   };
 
 } // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/istl/CMakeLists.txt b/src/amdis/linear_algebra/istl/CMakeLists.txt
index cd5ee97f5f7fbaf3fa22c39f74a54b6eeb33f9ce..f1e73c05ad38ceff6076ef8155c52301e49c5f6b 100644
--- a/src/amdis/linear_algebra/istl/CMakeLists.txt
+++ b/src/amdis/linear_algebra/istl/CMakeLists.txt
@@ -4,14 +4,11 @@
 #)
 
 install(FILES
+    DirectRunner.hpp
     DOFMatrix.hpp
     DOFVector.hpp
+    Fwd.hpp
     ISTL_Preconditioner.hpp
     ISTL_Solver.hpp
     ISTLRunner.hpp
-    LinearSolver.hpp
-    Preconditioner.hpp
-    SystemMatrix.hpp
-    SystemVector.hpp
-    UmfpackRunner.hpp
 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/amdis/linear_algebra/istl)
diff --git a/src/amdis/linear_algebra/istl/DOFMatrix.hpp b/src/amdis/linear_algebra/istl/DOFMatrix.hpp
index e256a05eecca3bf3460ae2b4a39a102311be6147..61837bf6083cdb3830c306245e1edcff9880edfd 100644
--- a/src/amdis/linear_algebra/istl/DOFMatrix.hpp
+++ b/src/amdis/linear_algebra/istl/DOFMatrix.hpp
@@ -1,5 +1,6 @@
 #pragma once
 
+#include <list>
 #include <string>
 #include <memory>
 
@@ -7,112 +8,73 @@
 #include <dune/istl/matrixindexset.hh>
 
 #include <amdis/Output.hpp>
-#include <amdis/common/ClonablePtr.hpp>
+#include <amdis/linear_algebra/Common.hpp>
+#include <amdis/linear_algebra/DOFMatrixBase.hpp>
+#include <amdis/utility/MultiIndex.hpp>
 
 namespace AMDiS
 {
-  template <class RowFeSpaceType, class ColFeSpaceType,
-            class ValueType = Dune::FieldMatrix<double,1,1>>
-  class DOFMatrix
+  template <class T, class = void>
+  struct BlockMatrixType
+  {
+    using type = Dune::FieldMatrix<T,1,1>;
+  };
+
+  template <class T>
+  struct BlockMatrixType<T, typename T::field_type>
+  {
+    using type = T;
+  };
+
+  template <class ValueType>
+  class IstlMatrix
   {
   public:
-    using RowFeSpace = RowFeSpaceType;
-    using ColFeSpace = ColFeSpaceType;
-    using BaseMatrix = Dune::BCRSMatrix<ValueType>;
+    /// The type of the elements of the DOFMatrix
+    using value_type = typename BlockMatrixType<ValueType>::type;
 
-    using size_type  = typename RowFeSpaceType::size_type;
-    using field_type = typename ValueType::field_type;
+    /// The matrix type of the underlying base matrix
+    using BaseMatrix = Dune::BCRSMatrix<value_type>;
 
-    using value_type = ValueType;
+    /// The index/size - type
+    using size_type = typename BaseMatrix::size_type;
 
+  public:
     /// Constructor. Constructs new BaseVector.
-    DOFMatrix(RowFeSpace const& rowFeSpace, ColFeSpace const& colFeSpace, std::string name)
-      : rowFeSpace(rowFeSpace)
-      , colFeSpace(colFeSpace)
-      , name(name)
-      , matrix(ClonablePtr<BaseMatrix>::make())
-    {}
-
-    /// Constructor. Takes pointer of data-vector.
-    DOFMatrix(RowFeSpace const& rowFeSpace, ColFeSpace const& colFeSpace, std::string name,
-              BaseMatrix& matrix_ref)
-      : rowFeSpace(rowFeSpace)
-      , colFeSpace(colFeSpace)
-      , name(name)
-      , matrix(matrix_ref)
-    {}
-
-    /// Return the row-basis \ref rowFeSpace of the matrix
-    RowFeSpace const& getRowFeSpace() const
-    {
-      return rowFeSpace;
-    }
-
-    /// Return the col-basis \ref colFeSpace of the matrix
-    ColFeSpace const& getColFeSpace() const
-    {
-      return colFeSpace;
-    }
+    IstlMatrix() = default;
 
     /// Return the data-vector \ref vector
-    BaseMatrix const& getMatrix() const
+    BaseMatrix const& matrix() const
     {
-      return *matrix;
+      return matrix_;
     }
 
     /// Return the data-vector \ref vector
-    BaseMatrix& getMatrix()
-    {
-      return *matrix;
-    }
-
-    /// Return the size of the \ref feSpace
-    size_type N() const
-    {
-      return rowFeSpace.size();
-    }
-
-    size_type M() const
-    {
-      return colFeSpace.size();
-    }
-
-    /// Return the \ref name of this vector
-    std::string getName() const
+    BaseMatrix& matrix()
     {
-      return name;
+      return matrix_;
     }
 
 
-    /// Access the entry \p i of the \ref vector with read-access.
-    value_type const& operator()(size_type r, size_type c) const
+    /// Insert a single value into the matrix (add to existing value)
+    void insert(size_type r, size_type c, value_type const& value)
     {
-      test_exit_dbg( initialized, "Occupation pattern not initialized!");
-      test_exit_dbg( r < N() && c < M() ,
-          "Indices out of range [0,", N(), ")x[0,", M(), ")" );
-      return (*matrix)[r][c];
-    }
-
-    /// Access the entry \p i of the \ref vector with write-access.
-    value_type& operator()(size_type r, size_type c)
-    {
-      test_exit_dbg( initialized, "Occupation pattern not initialized!");
-      test_exit_dbg( r < N() && c < M() ,
-          "Indices out of range [0,", N(), ")x[0,", M(), ")" );
-      return (*matrix)[r][c];
+      test_exit_dbg( initialized_, "Occupation pattern not initialized!");
+      test_exit_dbg( r < matrix_.N() && c < matrix_.M() ,
+          "Indices out of range [0,", matrix_.N(), ")x[0,", matrix_.M(), ")" );
+      matrix_[r][c] += value;
     }
 
     /// create occupation pattern and apply it to the matrix
-    void init()
+    template <class RowBasis, class ColBasis>
+    void init(RowBasis const& rowBasis, ColBasis const& colBasis,
+              bool prepareForInsertion)
     {
-      occupationPattern.resize(rowFeSpace.size(), colFeSpace.size());
-      auto meshView = rowFeSpace.gridView();
-
-      // A loop over all elements of the grid
-      auto rowLocalView = rowFeSpace.localView();
-      auto colLocalView = colFeSpace.localView();
+      auto occupationPattern = Dune::MatrixIndexSet{rowBasis.dimension(), colBasis.dimension()};
 
-      for (const auto& element : elements(meshView)) {
+      auto rowLocalView = rowBasis.localView();
+      auto colLocalView = colBasis.localView();
+      for (const auto& element : elements(rowBasis.gridView())) {
         rowLocalView.bind(element);
         colLocalView.bind(element);
 
@@ -126,50 +88,44 @@ namespace AMDiS
           }
         }
       }
-      occupationPattern.exportIdx(*matrix);
+      occupationPattern.exportIdx(matrix_);
 
-      initialized = true;
+      initialized_ = true;
     }
 
     void finish()
     {
-      initialized = false;
+      initialized_ = false;
     }
 
-    std::size_t getNnz()
+    std::size_t nnz() const
     {
-      return matrix->nonzeroes();
+      return matrix_.nonzeroes();
     }
 
-    auto clearDirichletRows(std::vector<char> const& dirichletNodes, bool apply)
+    auto applyDirichletBC(std::vector<char> const& dirichletNodes)
     {
       // loop over the matrix rows
-      for (std::size_t i = 0; i < matrix->N(); ++i) {
+      for (std::size_t i = 0; i < matrix_.N(); ++i) {
         if (dirichletNodes[i]) {
-            auto cIt = (*matrix)[i].begin();
-            auto cEndIt = (*matrix)[i].end();
+            auto cIt = matrix_[i].begin();
+            auto cEndIt = matrix_[i].end();
             // loop over nonzero matrix entries in current row
             for (; cIt != cEndIt; ++cIt)
-                *cIt = (apply && i == cIt.index() ? 1 : 0);
+                *cIt = (i == cIt.index() ? 1 : 0);
         }
       }
 
-      std::vector<std::map<size_t,value_type>> columns; // symmetric dbc not yet implemented
-      return columns;
+      return std::list<Triplet<value_type>>{};
     }
 
   private:
-    RowFeSpace const&	rowFeSpace;
-    ColFeSpace const&	colFeSpace;
-    std::string	        name;
+    BaseMatrix matrix_;
 
-    ClonablePtr<BaseMatrix> matrix;
-    Dune::MatrixIndexSet    occupationPattern;
-
-    bool initialized = false;
-
-    // friend class declarations
-    template <class, class, class> friend class SystemMatrix;
+    bool initialized_ = false;
   };
 
+  template <class RowBasisType, class ColBasisType, class ValueType = double>
+  using DOFMatrix = DOFMatrixBase<RowBasisType, ColBasisType, IstlMatrix<ValueType>>;
+
 } // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/istl/DOFVector.hpp b/src/amdis/linear_algebra/istl/DOFVector.hpp
index 77fa9d66c4cae779646ccf1a69a5638b19abbff4..a1234090740cb542c806b6e13b54bf5817ff1c2a 100644
--- a/src/amdis/linear_algebra/istl/DOFVector.hpp
+++ b/src/amdis/linear_algebra/istl/DOFVector.hpp
@@ -1,124 +1,97 @@
 #pragma once
 
-#include <string>
-#include <memory>
-
 #include <dune/istl/bvector.hh>
 
-#include <dune/functions/functionspacebases/interpolate.hh>
-
 #include <amdis/Output.hpp>
-#include <amdis/common/ClonablePtr.hpp>
+#include <amdis/linear_algebra/DOFVectorBase.hpp>
 
 namespace AMDiS
 {
-    template <class FeSpaceType, class ValueType = Dune::FieldVector<double,1>>
-    class DOFVector
-    {
-        using Self = DOFVector;
-
-    public:
-	using FeSpace    = FeSpaceType;
-	using BaseVector = Dune::BlockVector<ValueType>;
-
-	using size_type  = typename FeSpace::size_type;
-	using field_type = typename ValueType::field_type;
-
-	using value_type = ValueType;
-
-	/// Constructor. Constructs new BaseVector.
-	DOFVector(FeSpace const& feSpace, std::string name)
-	  : feSpace(feSpace)
-	  , name(name)
-	  , vector(ClonablePtr<BaseVector>::make())
-	{
-	    compress();
-	}
-
-	/// Constructor. Takes pointer of data-vector.
-	DOFVector(FeSpace const& feSpace, std::string name,
-		  BaseVector& vector_ref)
-	  : feSpace(feSpace)
-	  , name(name)
-	  , vector(vector_ref)
-	{}
-
-	/// Return the basis \ref feSpace of the vector
-	FeSpace const& getFeSpace() const
-	{
-	    return feSpace;
-	}
-
-	/// Return the data-vector \ref vector
-	BaseVector const& getVector() const
+  template <class T, class = void>
+  struct BlockVectorType
+  {
+    using type = Dune::FieldVector<T,1>;
+  };
+
+  template <class T>
+  struct BlockVectorType<T, typename T::field_type>
+  {
+    using type = T;
+  };
+
+	template <class ValueType>
+	class IstlVector
 	{
-	    return *vector;
-	}
+	public:
+    /// The type of the elements of the DOFVector
+	  using value_type = typename BlockVectorType<ValueType>::type;
 
-	/// Return the data-vector \ref vector
-	BaseVector& getVector()
-	{
-	    return *vector;
-	}
+    /// The vector type of the underlying base vector
+	  using BaseVector = Dune::BlockVector<value_type>;
 
-	/// Return the size of the \ref feSpace
-	size_type getSize() const
-	{
-	    return feSpace.size();
-	}
+    /// The index/size - type
+	  using size_type  = typename BaseVector::size_type;
 
-	/// Return the \ref name of this vector
-	std::string getName() const
-	{
-	    return name;
-	}
+  public:
+    /// Constructor. Constructs new BaseVector.
+    IstlVector() = default;
 
-	/// Resize the \ref vector to the size of the \ref feSpace.
-	void compress()
-	{
-	    vector->resize(getSize() / value_type::dimension);
-	}
+    /// Return the data-vector \ref vector
+    BaseVector const& vector() const
+    {
+      return vector_;
+    }
 
+    /// Return the data-vector \ref vector
+    BaseVector& vector()
+    {
+      return vector_;
+    }
 
-	/// Access the entry \p i of the \ref vector with read-access.
-	value_type const& operator[](size_type i) const
-	{
-	    test_exit_dbg(i < vector->size() ,
-                          "Index ", i, " out of range [0,", vector->size(), ")" );
-	    return (*vector)[i];
-	}
 
-	/// Access the entry \p i of the \ref vector with write-access.
-	value_type& operator[](size_type i)
-	{
-	    test_exit_dbg(i < vector->size() ,
-                          "Index ", i, " out of range [0,", vector->size(), ")" );
-	    return (*vector)[i];
-	}
-
-	/// interpolate a function \p f to the basis \ref feSpace and store the
-	/// coefficients in \ref vector.
-	template <class F>
-	void interpol(F const& f)
-	{
-	    Dune::Functions::interpolate(feSpace, *vector, f);
-	}
+    /// Return the current size of the \ref vector_
+    size_type size() const
+    {
+      return vector_.size();
+    }
 
-	/// Calls the copy assignment operator of the BaseVector \ref vector
-	void copy(Self const& that)
-	{
-		*vector = that.getVector();
-	}
+    /// Resize the \ref vector_ to the size \p s
+    void resize(size_type s)
+    {
+      vector_.resize(s);
+    }
 
-    private:
-	FeSpace const&	feSpace;
-	std::string	name;
 
-	ClonablePtr<BaseVector> vector;
+    /// Access the entry \p i of the \ref vector with read-access.
+    value_type const& operator[](size_type i) const
+    {
+      test_exit_dbg(i < vector_.size(),
+        "Index ", i, " out of range [0,", vector_.size(), ")" );
+      return vector_[i];
+    }
 
-    // friend class declarations
-    template <class, class>
-    friend class SystemVector;
-    };
+    /// Access the entry \p i of the \ref vector with write-access.
+    value_type& operator[](size_type i)
+    {
+      test_exit_dbg(i < vector_.size(),
+        "Index ", i, " out of range [0,", vector_.size(), ")" );
+      return vector_[i];
+    }
+
+	private:
+    BaseVector vector_;
+	};
+
+
+  template <class BasisType, class VectorType = double>
+  using DOFVector = DOFVectorBase<BasisType, IstlVector<VectorType>>;
+
+  /// Constructor a dofvector from given basis and name
+  template <class ValueType = double, class Basis>
+  DOFVector<Basis, ValueType>
+  makeDOFVector(Basis const& basis)
+  {
+    return {basis};
+  }
 
 } // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/istl/DirectRunner.hpp b/src/amdis/linear_algebra/istl/DirectRunner.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..187abadfa5c0767810abf3147a4c28d8ef1e0733
--- /dev/null
+++ b/src/amdis/linear_algebra/istl/DirectRunner.hpp
@@ -0,0 +1,63 @@
+#pragma once
+
+#include <algorithm>
+#include <string>
+
+#include <amdis/Output.hpp>
+#include <amdis/linear_algebra/RunnerInterface.hpp>
+#include <amdis/linear_algebra/SolverInfo.hpp>
+
+namespace AMDiS
+{
+  /**
+   * \ingroup Solver
+   * \class AMDiS::DirectRunner
+   * \brief \implements RunnerInterface for the (external) direct solvers
+   */
+  template <class Solver, class Matrix, class VectorX, class VectorB>
+  class DirectRunner
+      : public RunnerInterface<Matrix, VectorX, VectorB>
+  {
+  protected:
+    using Super = RunnerInterface<Matrix, VectorX, VectorB>;
+    using BaseSolver  = Dune::InverseOperator<VectorX, VectorB>;
+
+  public:
+    /// Constructor.
+    DirectRunner(std::string prefix)
+      : solverCreator_(prefix)
+    {}
+
+    /// Implementes \ref RunnerInterface::init()
+    virtual void init(Matrix const& A) override
+    {
+      solver_ = solverCreator_.create(A);
+    }
+
+    /// Implementes \ref RunnerInterface::exit()
+    virtual void exit() override
+    {
+      solver_.reset();
+    }
+
+    /// Implementes \ref RunnerInterface::solve()
+    virtual int solve(Matrix const& A, VectorX& x, VectorB const& b,
+                      SolverInfo& solverInfo) override
+    {
+      // storing some statistics
+      Dune::InverseOperatorResult statistics;
+
+      // solve the linear system
+      VectorB _b = b;
+      solver_->apply(x, _b, statistics);
+
+      solverInfo.setRelResidual(statistics.reduction);
+
+      return 0;
+    }
+
+  private:
+    ISTLSolverCreator<Solver> solverCreator_;
+    std::shared_ptr<BaseSolver> solver_;
+  };
+}
diff --git a/src/amdis/linear_algebra/istl/Fwd.hpp b/src/amdis/linear_algebra/istl/Fwd.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e2ad22c295e1f6de8e8926c94be5b7bf36fc7f9c
--- /dev/null
+++ b/src/amdis/linear_algebra/istl/Fwd.hpp
@@ -0,0 +1,8 @@
+#pragma once
+
+namespace AMDiS
+{
+  template <class ISTLSolver, bool specialized = true>
+  struct ISTLSolverCreator;
+
+} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/istl/ISTLRunner.hpp b/src/amdis/linear_algebra/istl/ISTLRunner.hpp
index 46d7790fed6db10f62cb510ea65b0e24f200e266..99c4927e876456f1bfffc9c2586467c8ec6fb69e 100644
--- a/src/amdis/linear_algebra/istl/ISTLRunner.hpp
+++ b/src/amdis/linear_algebra/istl/ISTLRunner.hpp
@@ -1,56 +1,45 @@
 #pragma once
 
-#include <amdis/linear_algebra/istl/ISTL_Solver.hpp>
-#include <amdis/linear_algebra/istl/Preconditioner.hpp>
+#include <dune/istl/preconditioner.hh>
+
+#include <amdis/linear_algebra/RunnerInterface.hpp>
+#include <amdis/linear_algebra/SolverInfo.hpp>
+#include <amdis/linear_algebra/istl/Fwd.hpp>
+#include <amdis/linear_algebra/istl/ISTL_Preconditioner.hpp>
 
 namespace AMDiS
 {
-  template <class Matrix, class VectorX, class VectorB>
+  template <class ISTLSolver, class Matrix, class VectorX, class VectorB>
   class ISTLRunner
-    : public RunnerInterface<Matrix, VectorX, VectorB>
+      : public RunnerInterface<Matrix, VectorX, VectorB>
   {
     using LinOperator = Dune::MatrixAdapter<Matrix, VectorX, VectorB>;
     using BaseSolver  = Dune::InverseOperator<VectorX, VectorB>;
-
-    using PreconRunner = ISTLPreconditioner<Matrix, VectorX, VectorB>;
-    using PreconBase   = PreconditionerInterface<Matrix, VectorX, VectorB>;
+    using BasePrecon  = Dune::Preconditioner<VectorX, VectorB>;
+    using ISTLPrecon  = ISTLPreconInterface<Matrix, VectorX, VectorB>;
 
   public:
-    ISTLRunner(std::string solverName, std::string prefix)
-      : solverName(solverName)
-      , prefix(prefix)
-      , solverCreator(prefix)
+    ISTLRunner(std::string prefix)
+      : solverCreator_(prefix)
     {
-      // get creator string for preconditioner
-      std::string preconName = "no";
-      Parameters::get(prefix + "->left precon", preconName);
-      if (preconName.empty() || preconName == "no")
-        Parameters::get(prefix + "->right precon", preconName);
-      if (preconName.empty() || preconName == "no")
-        Parameters::get(prefix + "->precon->name", preconName);
-
-      precon = std::make_shared<PreconRunner>(preconName, prefix + "->precon");
+      initPrecon(prefix);
     }
 
 
     /// Implementes \ref RunnerInterface::init()
     virtual void init(Matrix const& A) override
     {
-      precon->init(A);
-
-      Matrix& _A = const_cast<Matrix&>(A); // Unschoen!!!
-      linOperator = std::make_shared<LinOperator>(_A);
-      solver = solverCreator.create(solverName, *linOperator, *precon);
+      precon_ = preconCreator_->create(A);
+      linOperator_ = std::make_shared<LinOperator>(A);
+      solver_ = solverCreator_.create(*linOperator_, *precon_);
     }
 
     /// Implementes \ref RunnerInterface::exit()
     virtual void exit() override
     {
-      solver.reset();
-      linOperator.reset();
-
-      precon->exit();
-      precon.reset();
+      solver_.reset();
+      linOperator_.reset();
+      precon_.reset();
     }
 
     /// Implementes \ref RunnerInterface::solve()
@@ -62,26 +51,42 @@ namespace AMDiS
 
       // solve the linear system
       VectorB _b = b;
-      solver->apply(x, _b, statistics);
+      solver_->apply(x, _b, statistics);
 
       solverInfo.setRelResidual(statistics.reduction);
+
+      return statistics.converged ? 0 : 1;
     }
 
-    /// Implementes \ref RunnerInterface::getLeftPrecon()
-    virtual std::shared_ptr<PreconBase> getLeftPrecon() override
+  protected:
+    void initPrecon(std::string const& prefix)
     {
-      return preconAdapter;
+      // get creator string for preconditioner
+      std::string preconName = "no";
+      std::string initFileStr = "";
+      for (std::string postfix : {"left precon", "right precon", "precon->name"}) {
+        Parameters::get(prefix + "->" + postfix, preconName);
+        if (!preconName.empty() && preconName != "no") {
+          initFileStr = prefix + "->" + postfix;
+          break;
+        }
+      }
+
+      if (preconName.empty() || preconName == "no")
+        preconName = "default";
+
+      auto* creator = named(CreatorMap<ISTLPrecon>::getCreator(preconName, initFileStr));
+      preconCreator_ = creator->create(initFileStr);
+      assert(preconCreator_);
     }
 
   private:
-    std::string solverName;
-    std::string prefix;
-
-    ISTLSolverCreator<Matrix, VectorX, VectorB> solverCreator;
+    ISTLSolverCreator<ISTLSolver> solverCreator_;
+    std::shared_ptr<ISTLPrecon> preconCreator_;
 
-    std::shared_ptr<PreconRunner> precon;
-    std::shared_ptr<LinOperator>  linOperator;
-    std::shared_ptr<BaseSolver>   solver;
+    std::shared_ptr<BasePrecon>   precon_;
+    std::shared_ptr<LinOperator>  linOperator_;
+    std::shared_ptr<BaseSolver>   solver_;
   };
 
 } // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/istl/ISTL_Preconditioner.hpp b/src/amdis/linear_algebra/istl/ISTL_Preconditioner.hpp
index 750b562b2e714b7a5d9720962017a65decbe23be..4a653fa796949ba28b3e3511da3628f4aed5cd1f 100644
--- a/src/amdis/linear_algebra/istl/ISTL_Preconditioner.hpp
+++ b/src/amdis/linear_algebra/istl/ISTL_Preconditioner.hpp
@@ -2,71 +2,116 @@
 
 #include <dune/istl/preconditioners.hh>
 
+#include <amdis/CreatorInterface.hpp>
+
 namespace AMDiS
 {
+  template <class Matrix, class VectorX, class VectorB>
+  struct ISTLPreconInterface
+  {
+    using PreconBase = Dune::Preconditioner<VectorX, VectorB>;
+    virtual std::unique_ptr<PreconBase> create(Matrix const& matrix) const = 0;
+  };
+
+  template <class> struct Type {};
 
   // creators for preconditioners, depending on matrix-type
   // ---------------------------------------------------------------------------
 
-  template <class Matrix, class VectorX, class VectorB = VectorX>
-  class ISTLPreconCreator;
-
-  template <class... MatrixRows, class VectorX, class VectorB>
-  class ISTLPreconCreator<Dune::MultiTypeBlockMatrix<MatrixRows...>, VectorX, VectorB>
+  template <class Precon, class Matrix>
+  struct ISTLPrecon
+      : public ISTLPreconInterface<Matrix, typename Precon::domain_type, typename Precon::range_type>
   {
-    using BasePreconditioner = Dune::Preconditioner<VectorX, VectorB>;
+    using VectorX = typename Precon::domain_type;
+    using VectorB = typename Precon::range_type;
+    using Super = ISTLPreconInterface<Matrix, VectorX, VectorB>;
+    using Self = ISTLPrecon;
 
-  public:
-    ISTLPreconCreator(std::string prefix)
-      : prefix(prefix)
-    {}
+    struct Creator : CreatorInterfaceName<Super>
+    {
+      virtual std::shared_ptr<Super> create(std::string prefix) override
+      {
+        return std::make_shared<Self>(prefix);
+      }
+    };
 
-    template <class Matrix>
-    std::unique_ptr<BasePreconditioner> create(std::string /*name*/, Matrix const& A)
+    ISTLPrecon(std::string prefix)
     {
-      double w = 1.0;
-      Parameters::get(prefix + "->relaxation", w);
+      Parameters::get(prefix + "->relaxation", w_);
+    }
 
-      warning("Only Richardson preconditioner available for MultiTypeBlockMatrix!");
-      return std::make_unique<Dune::Richardson<VectorX, VectorB>>(w);
+    using PreconBase = Dune::Preconditioner<VectorX, VectorB>;
+    virtual std::unique_ptr<PreconBase> create(Matrix const& A) const override
+    {
+      return createImpl(A, Type<Precon>{});
     }
 
   private:
-    std::string prefix;
+    template <class P>
+    std::unique_ptr<P> createImpl(Matrix const& A, Type<P>) const
+    {
+      return std::make_unique<P>(A, 1, w_);
+    }
+
+    std::unique_ptr<Dune::SeqILU0<Matrix, VectorX, VectorB>>
+    createImpl(Matrix const& A, Type<Dune::SeqILU0<Matrix, VectorX, VectorB>>) const
+    {
+      return std::make_unique<Dune::SeqILU0<Matrix, VectorX, VectorB>>(A, w_);
+    }
+
+    std::unique_ptr<Dune::Richardson<VectorX, VectorB>>
+    createImpl(Matrix const& /*A*/, Type<Dune::Richardson<VectorX, VectorB>>) const
+    {
+      return std::make_unique<Dune::Richardson<VectorX, VectorB>>(w_);
+    }
+
+    double w_ = 1.0;
   };
 
-  template <class Block, class Alloc, class VectorX, class VectorB>
-  class ISTLPreconCreator<Dune::BCRSMatrix<Block,Alloc>, VectorX, VectorB>
+
+  /// Adds default creators for linear solvers based on `Dune::BCRSMatrix`.
+  /**
+   * Adds creators for full-matrix aware solvers.
+   * - *cg*: conjugate gradient method, \see Dune::CGSolver
+   * - *bcgs*: stabilized bi-conjugate gradient method, \see Dune::BiCGSTABSolver
+   * - *minres*: Minimal residul method, \see Dune::MINRESSolver
+   * - *gmres*: Generalized minimal residula method, \see Dune::RestartedGMResSolver
+   * - *umfpack*: external UMFPACK solver, \see Dune::UMFPack
+   **/
+  template <class Matrix, class VectorX, class VectorB>
+  class DefaultCreators<ISTLPreconInterface<Matrix, VectorX, VectorB>>
   {
-    using BasePreconditioner = Dune::Preconditioner<VectorX, VectorB>;
+    template <class Precon>
+    using PreconCreator
+      = typename ISTLPrecon<Precon, Matrix>::Creator;
 
-  public:
-    ISTLPreconCreator(std::string prefix)
-      : prefix(prefix)
-    {}
+    using Map = CreatorMap<ISTLPreconInterface<Matrix, VectorX, VectorB>>;
 
-    template <class Matrix>
-    std::unique_ptr<BasePreconditioner> create(std::string name, Matrix const& A)
+  public:
+    static void init()
     {
-      double w = 1.0;
-      Parameters::get(prefix + "->relaxation", w);
-
-      if (name == "diag" || name == "jacobi")
-        return std::make_unique<Dune::SeqJac<Matrix, VectorX, VectorB>>(A, 1, w);
-      else if (name == "gs" || name == "gauss_seidel")
-        return std::make_unique<Dune::SeqGS<Matrix, VectorX, VectorB>>(A, 1, w);
-      else if (name == "sor")
-        return std::make_unique<Dune::SeqSOR<Matrix, VectorX, VectorB>>(A, 1, w);
-      else if (name == "ssor")
-        return std::make_unique<Dune::SeqSSOR<Matrix, VectorX, VectorB>>(A, 1, w);
-      else if (name == "ilu" || name == "ilu0")
-        return std::make_unique<Dune::SeqILU0<Matrix, VectorX, VectorB>>(A, w);
-      else
-        return std::make_unique<Dune::Richardson<VectorX, VectorB>>(w);
-    }
+      auto jacobi = new PreconCreator<Dune::SeqJac<Matrix, VectorX, VectorB>>;
+      Map::addCreator("diag", jacobi);
+      Map::addCreator("jacobi", jacobi);
 
-  private:
-    std::string prefix;
+      auto gs = new PreconCreator<Dune::SeqGS<Matrix, VectorX, VectorB>>;
+      Map::addCreator("gs", gs);
+      Map::addCreator("gauss_seidel", gs);
+
+      auto sor = new PreconCreator<Dune::SeqSOR<Matrix, VectorX, VectorB>>;
+      Map::addCreator("sor", sor);
+
+      auto ssor = new PreconCreator<Dune::SeqSSOR<Matrix, VectorX, VectorB>>;
+      Map::addCreator("ssor", ssor);
+
+      auto ilu = new PreconCreator<Dune::SeqILU0<Matrix, VectorX, VectorB>>;
+      Map::addCreator("ilu", ilu);
+      Map::addCreator("ilu0", ilu);
+
+      auto richardson = new PreconCreator<Dune::Richardson<VectorX, VectorB>>;
+      Map::addCreator("richardson", richardson);
+      Map::addCreator("default", richardson);
+    }
   };
 
 } // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/istl/ISTL_Solver.hpp b/src/amdis/linear_algebra/istl/ISTL_Solver.hpp
index 558677dbdf152e31750adcbc4efefe9604381d15..e32d52fe3c726a57a951e40ad99819cc59d542a6 100644
--- a/src/amdis/linear_algebra/istl/ISTL_Solver.hpp
+++ b/src/amdis/linear_algebra/istl/ISTL_Solver.hpp
@@ -1,106 +1,196 @@
 #pragma once
 
+#include <memory>
+
 #include <dune/istl/solvers.hh>
 #include <dune/istl/umfpack.hh>
+#include <dune/istl/superlu.hh>
+
+#include <amdis/CreatorMap.hpp>
+#include <amdis/Initfile.hpp>
+
+#include <amdis/linear_algebra/istl/Fwd.hpp>
+#include <amdis/linear_algebra/istl/DirectRunner.hpp>
+#include <amdis/linear_algebra/istl/ISTLRunner.hpp>
 
 namespace AMDiS
 {
-  // creators for solvers, depending on matrix-type
-  // ---------------------------------------------------------------------------
+  template <class ISTLSolver, bool specialized>
+  struct ISTLSolverCreator
+  {
+    ISTLSolverCreator(std::string prefix)
+    {
+      Parameters::get(prefix + "->info", info_);
+      Parameters::get(prefix + "->max iteration", maxIter_);
+      Parameters::get(prefix + "->relative tolerance", rTol_);
+    }
 
-  template <class Matrix, class VectorX, class VectorB = VectorX>
-  class ISTLSolverCreator;
+    template <class LinOperator, class Precon>
+    std::unique_ptr<ISTLSolver> create(LinOperator& A, Precon& P) const
+    {
+      return std::make_unique<ISTLSolver>(A, P, rTol_, maxIter_, info_);
+    }
+
+    int info_ = 2;
+    std::size_t maxIter_ = 500;
+    double rTol_ = 1.e-6;
+  };
 
-  template <class... MatrixRows, class VectorX, class VectorB>
-  class ISTLSolverCreator<Dune::MultiTypeBlockMatrix<MatrixRows...>, VectorX, VectorB>
+  template <class VectorX>
+  struct ISTLSolverCreator<Dune::RestartedGMResSolver<VectorX>, true>
+      : public ISTLSolverCreator<Dune::RestartedGMResSolver<VectorX>, false>
   {
-    using BaseSolver = Dune::InverseOperator<VectorX, VectorB>;
+    using ISTLSolver = Dune::RestartedGMResSolver<VectorX>;
+    using Super = ISTLSolverCreator<ISTLSolver, false>;
 
-  public:
     ISTLSolverCreator(std::string prefix)
-      : prefix(prefix)
-      , info(2)
+      : Super(prefix)
     {
-      Parameters::get(prefix + "->info", info);
+      Parameters::get(prefix + "->restart", restart_);
     }
 
-    template <class Matrix, class Precon>
-    std::unique_ptr<BaseSolver> create(std::string name, Matrix& A, Precon& P)
+    template <class LinOperator, class Precon>
+    std::unique_ptr<ISTLSolver> create(LinOperator& A, Precon& P) const
     {
-      std::size_t maxIter = 500;
-      Parameters::get(prefix + "->max iteration", maxIter);
-
-      double rTol = 1.e-6;
-      Parameters::get(prefix + "->reduction", rTol);
-
-      if (name == "cg")
-        return std::make_unique<Dune::CGSolver<VectorX>>(A, P, rTol, maxIter, info);
-      else if (name == "bicgstab")
-        return std::make_unique<Dune::BiCGSTABSolver<VectorX>>(A, P, rTol, maxIter, info);
-      else if (name == "minres")
-        return std::make_unique<Dune::MINRESSolver<VectorX>>(A, P, rTol, maxIter, info);
-      else if (name == "gmres")
-      {
-        int restart = 30;
-        Parameters::get(prefix + "->restart", restart);
-        return std::make_unique<Dune::RestartedGMResSolver<VectorX>>(A, P, rTol, restart, maxIter, info);
-      }
-      else
-        error_exit("Unknown solver name!");
+      return std::make_unique<ISTLSolver>(A, P, this->rTol_, restart_, this->maxIter_, this->info_);
     }
 
-  private:
-    std::string prefix;
-    int         info;
+    int restart_ = 30;
   };
 
-
-  template <class Block, class Alloc, class VectorX, class VectorB>
-  class ISTLSolverCreator<Dune::BCRSMatrix<Block,Alloc>, VectorX, VectorB>
+  template <class VectorX>
+  struct ISTLSolverCreator<Dune::GeneralizedPCGSolver<VectorX>, true>
+      : public ISTLSolverCreator<Dune::GeneralizedPCGSolver<VectorX>, false>
   {
-    using BaseSolver = Dune::InverseOperator<VectorX, VectorB>;
-    using Matrix     = Dune::BCRSMatrix<Block,Alloc>;
+    using ISTLSolver = Dune::GeneralizedPCGSolver<VectorX>;
+    using Super = ISTLSolverCreator<ISTLSolver, false>;
 
-  public:
     ISTLSolverCreator(std::string prefix)
-      : prefix(prefix)
-      , info(2)
+      : Super(prefix)
     {
-      Parameters::get(prefix + "->info", info);
+      Parameters::get(prefix + "->restart", restart_);
     }
 
     template <class LinOperator, class Precon>
-    std::unique_ptr<BaseSolver> create(std::string name, LinOperator& A, Precon& P)
+    std::unique_ptr<ISTLSolver> create(LinOperator& A, Precon& P) const
     {
-      std::size_t maxIter = 500;
-      Parameters::get(prefix + "->max iteration", maxIter);
-
-      double rTol = 1.e-6;
-      Parameters::get(prefix + "->relative tolerance", rTol);
-
-      if (name == "cg")
-        return std::make_unique<Dune::CGSolver<VectorX>>(A, P, rTol, maxIter, info);
-      else if (name == "bicgstab")
-        return std::make_unique<Dune::BiCGSTABSolver<VectorX>>(A, P, rTol, maxIter, info);
-      else if (name == "minres")
-        return std::make_unique<Dune::MINRESSolver<VectorX>>(A, P, rTol, maxIter, info);
-      else if (name == "gmres")
-      {
-        int restart = 30;
-        Parameters::get(prefix + "->restart", restart);
-        return std::make_unique<Dune::RestartedGMResSolver<VectorX>>(A, P, rTol, restart, maxIter, info);
-      }
+      return std::make_unique<ISTLSolver>(A, P, this->rTol_, this->maxIter_, this->info_, restart_);
+    }
+
+    int restart_ = 30;
+  };
+
+
 #if HAVE_SUITESPARSE_UMFPACK
-      else if (name == "umfpack" || name == "direct")
-        return std::make_unique<Dune::UMFPack<Matrix>>(A, info);
+  template <class Matrix>
+  struct ISTLSolverCreator<Dune::UMFPack<Matrix>, true>
+  {
+    using Solver = Dune::UMFPack<Matrix>;
+    ISTLSolverCreator(std::string prefix)
+    {
+      Parameters::get(prefix + "->info", verbose_);
+    }
+
+    std::unique_ptr<Solver> create(Matrix const& A) const
+    {
+      return std::make_unique<Solver>(A, verbose_);
+    }
+
+  private:
+    int verbose_ = 2;
+  };
 #endif
-      else
-        error_exit("Unknown solver name!");
+
+#if HAVE_SUPERLU
+  template <class Matrix>
+  struct ISTLSolverCreator<Dune::SuperLU<Matrix>, true>
+  {
+    using Solver = Dune::SuperLU<Matrix>;
+    ISTLSolverCreator(std::string prefix)
+    {
+      int info = 2;
+      Parameters::get(prefix + "->info", info);
+      verbose_ = (info != 0);
+
+      Parameters::get(prefix + "->reuse vector", reuseVector_);
+    }
+
+    std::unique_ptr<Solver> create(Matrix const& A) const
+    {
+      return std::make_unique<Solver>(A, verbose_, reuseVector_);
     }
 
   private:
-    std::string prefix;
-    int         info;
+    bool verbose_ = true;
+    bool reuseVector_ = true;
+  };
+#endif
+
+  /// Adds default creators for linear solvers based on `Dune::BCRSMatrix`.
+  /**
+   * Adds creators for full-matrix aware solvers.
+   * - *cg*: conjugate gradient method, \see Dune::CGSolver
+   * - *bcgs*: stabilized bi-conjugate gradient method, \see Dune::BiCGSTABSolver
+   * - *minres*: Minimal residul method, \see Dune::MINRESSolver
+   * - *gmres*: Generalized minimal residual method, \see Dune::RestartedGMResSolver
+   * - *fcg*: Generalized preconditioned conjugate gradient solver, \see Dune::GeneralizedPCGSolver
+   * - *umfpack*: external UMFPACK solver, \see Dune::UMFPack
+   * - *superlu*: external SuperLU solver, \see Dune::SuperLU
+   **/
+  template <class Block, class Alloc, class VectorX, class VectorB>
+  class DefaultCreators<LinearSolverInterface<Dune::BCRSMatrix<Block,Alloc>, VectorX, VectorB>>
+  {
+    using Matrix = Dune::BCRSMatrix<Block,Alloc>;
+    using SolverBase = LinearSolverInterface<Matrix, VectorX, VectorB>;
+
+    template <class ISTLSolver>
+    using SolverCreator
+      = typename LinearSolver<Matrix, VectorX, VectorB,
+          ISTLRunner<ISTLSolver, Matrix, VectorX, VectorB>>::Creator;
+
+    template <class ISTLSolver>
+    using DirectSolverCreator
+      = typename LinearSolver<Matrix, VectorX, VectorB,
+          DirectRunner<ISTLSolver, Matrix, VectorX, VectorB>>::Creator;
+
+    using Map = CreatorMap<SolverBase>;
+
+  public:
+    static void init()
+    {
+      auto cg = new SolverCreator<Dune::CGSolver<VectorX>>;
+      Map::addCreator("cg", cg);
+
+      auto bicgstab = new SolverCreator<Dune::BiCGSTABSolver<VectorX>>;
+      Map::addCreator("bicgstab", bicgstab);
+      Map::addCreator("bcgs", bicgstab);
+
+      auto minres = new SolverCreator<Dune::MINRESSolver<VectorX>>;
+      Map::addCreator("minres", minres);
+
+      auto gmres = new SolverCreator<Dune::RestartedGMResSolver<VectorX>>;
+      Map::addCreator("gmres", gmres);
+
+      // Generalized preconditioned conjugate gradient solver.
+      auto fcg = new SolverCreator<Dune::GeneralizedPCGSolver<VectorX>>;
+      Map::addCreator("fcg", fcg);
+
+#if HAVE_SUITESPARSE_UMFPACK
+      auto umfpack = new DirectSolverCreator<Dune::UMFPack<Matrix>>;
+      Map::addCreator("umfpack", umfpack);
+#endif
+
+#if HAVE_SUPERLU
+      auto superlu = new DirectSolverCreator<Dune::SuperLU<Matrix>>;
+      Map::addCreator("superlu", superlu);
+#endif
+
+#if HAVE_SUITESPARSE_UMFPACK
+      Map::addCreator("direct", umfpack);
+#elif HAVE_SUPERLU
+      Map::addCreator("direct", superlu);
+#endif
+    }
   };
 
 } // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/istl/LinearSolver.hpp b/src/amdis/linear_algebra/istl/LinearSolver.hpp
deleted file mode 100644
index 7799eaa29ae2c1d1407bf049d3f2d6d7f87043c8..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/istl/LinearSolver.hpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#pragma once
-
-#include <amdis/linear_algebra/LinearSolverInterface.hpp>
-#include <amdis/linear_algebra/istl/ISTLRunner.hpp>
-
-namespace AMDiS
-{
-  // A general solver class for istl solvers
-  // ---------------------------------------------------------------------------
-
-  template <class Matrix, class VectorX, class VectorB, class Runner>
-  class LinearSolver
-    : public LinearSolverInterface<Matrix, VectorX, VectorB>
-  {
-    using Super = LinearSolverInterface<Matrix, Vector, Vector>;
-    using RunnerBase = typename Super::RunnerBase;
-
-  public:
-    /// Constructor
-    LinearSolver(std::string name, std::string prefix)
-      : runner(std::make_shared<Runner>(name, prefix))
-    {}
-
-
-  private:
-    /// Implements \ref LinearSolverInterface::solveImpl()
-    virtual void solveImpl(Matrix const& A, VectorX& x, VectorB const& b,
-                           SolverInfo& solverInfo) override
-    {
-      if (solverInfo.doCreateMatrixData()) {
-        // init matrix or wrap block-matrix or ...
-        runner->init(A);
-      }
-
-      // solve the linear system
-      int error = runner->solve(A, x, b, solverInfo);
-      solverInfo.setError(error);
-
-      if (!solverInfo.doStoreMatrixData())
-        runner->exit();
-    }
-
-  private:
-    /// redirect the implementation to a runner. Implements a \ref RunnerInterface
-    std::shared_ptr<Runner> runner;
-  };
-
-
-  template <class Matrix, class VectorX, class VectorB>
-  class SolverCreator<Matrix, VectorX, VectorB>
-  {
-    using SolverBase = LinearSolverInterface<Matrix, VectorX, VectorB>;
-
-    template <class Runner>
-    using Solver = LinearSolver<Matrix, VectorX, VectorB, Runner>;
-
-    /// Instantiate a new linear solver
-    static std::unique_ptr<SolverBase> create(std::string name, std::string prefix)
-    {
-      using ISTL = ISTLRunner<Matrix, VectorX, VectorB>;
-
-      if (name == "cg" || name == "bicgstab" || name == "minres" || name == "gmres")
-        return std::make_unique<Solver<ISTL>>(name, prefix);
-      else
-        error_exit("Unknown solver name!"); // TODO: add direct solver interface here
-    }
-  };
-
-
-} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/istl/Preconditioner.hpp b/src/amdis/linear_algebra/istl/Preconditioner.hpp
deleted file mode 100644
index 6c331d53e789198dee9dd064479ef48aca5dd97c..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/istl/Preconditioner.hpp
+++ /dev/null
@@ -1,80 +0,0 @@
-#pragma once
-
-#include <type_traits>
-
-#include <dune/istl/preconditioner.hh>
-#include <dune/istl/solvercategory.hh>
-
-#include <amdis/linear_algebra/istl/ISTL_Preconditioner.hpp>
-
-namespace AMDiS {
-
-namespace detail
-{
-    template <class T, class = typename T::category >
-    std::integral_constant<bool, true> HasCategoryImpl(int);
-
-    template <class T>
-    std::integral_constant<bool, false> HasCategoryImpl(...);
-
-    template <class T>
-    using HasCategory = decltype(HasCategoryImpl<T>(int{}));
-
-} // end namespace detail
-
-
-template <class Matrix, class VectorX, class VectorB>
-class ISTLPreconditioner
-  : public Dune::Preconditioner<VectorX, VectorB>
-  , public PreconditionerInterface<Matrix, VectorX, VectorB>
-{
-public:
-    enum {category=Dune::SolverCategory::sequential};
-
-    ISTLPreconditioner(std::string preconName, std::string prefix)
-      : preconName(preconName)
-      , prefix(prefix)
-      , preconCreator(prefix)
-    {}
-
-    /// Implementation of \ref Dune::Preconditioner::pre()
-    virtual void pre(VectorX& x, VectorB& b) override { runner.pre(x, b); }
-
-    /// Implementation of \ref Dune::Preconditioner::apply()
-    virtual void apply(VectorX& v, const VectorB& d) override { runner.apply(v, d); }
-
-    /// Implementation of \ref Dune::Preconditioner::post()
-    virtual void post(VectorX& x) override { runner.post(x); }
-
-    // -------------------------------------------------------------------------
-
-    /// Implementation of \ref PreconditionerInterface::init()
-    virtual void init(Matrix const& A) override
-    {
-      Matrix& _A = const_cast<Matrix&>(A); // Unschoen!!!
-
-      runner = preconCreator.create(preconName, _A);
-    };
-
-    /// Implementation of \ref PreconditionerInterface::exit()
-    virtual void exit() override
-    {
-      runner.reset();
-    };
-
-    /// Implementation of \ref PreconditionerInterface::solve()
-    virtual void solve(VectorX const& x, VectorX& y) const override
-    {
-      runner.apply(v, d);
-    }
-
-private:
-    std::string preconName;
-    std::string prefix;
-
-    ISTLPreconCreator<Matrix, VectorX, VectorB> preconCreator;
-
-    std::shared_ptr<PreconRunner> runner;
-};
-
-} // end namespace AMDiS
\ No newline at end of file
diff --git a/src/amdis/linear_algebra/istl/SystemMatrix.cpp b/src/amdis/linear_algebra/istl/SystemMatrix.cpp
deleted file mode 100644
index 26d4d975b2d79c524632b40f846bbb0c2b84c0cc..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/istl/SystemMatrix.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#define AMDIS_NO_EXTERN_SYSTEMMATRIX
-#include <amdis/linear_algebra/istl/SystemMatrix.hpp>
-#undef AMDIS_NO_EXTERN_SYSTEMMATRIX
-
-
-namespace AMDiS
-{
-  // explicit template instatiation
-  template class SystemMatrix<typename TestTraits<2,1>::FeSpaces>;
-  template class SystemMatrix<typename TestTraits<2,1,2>::FeSpaces>;
-} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/istl/SystemMatrix.hpp b/src/amdis/linear_algebra/istl/SystemMatrix.hpp
deleted file mode 100644
index fa3e50b219658eef03b2ea288132132eba7c9f9c..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/istl/SystemMatrix.hpp
+++ /dev/null
@@ -1,318 +0,0 @@
-#pragma once
-
-#include <vector>
-#include <string>
-#include <memory>
-#include <tuple>
-
-#include <dune/istl/multitypeblockmatrix.hh>
-#include <dune/istl/multitypeblockvector.hh>
-
-#include <amdis/Output.hpp>
-#include <amdis/common/TupleUtility.hpp>
-#include <amdis/common/Utility.hpp>
-#include <amdis/linear_algebra/istl/DOFMatrix.hpp>
-
-// for explicit instantiation
-#include <amdis/ProblemStatTraits.hpp>
-
-namespace AMDiS
-{
-  namespace Impl
-  {
-    // DOFMatrices = std::tuple< std::tuple< DOFMatrix<RowFeSpace, ColFeSpace, ValueType>... >... >
-    template <class DOFMatrices>
-    struct BuildDOFMatrices
-    {
-      template <std::size_t R>
-      using DOFMatrixRow = std::tuple_element_t<R, DOFMatrices>;
-
-      template <std::size_t R, std::size_t C>
-      using DOFMatrixRowCol = std::tuple_element_t<C, DOFMatrixRow<R>>;
-
-      // add arg to repeated constructor argument list
-      template <std::size_t... R, class RowFeSpaces, class ColFeSpaces, class MultiMatrix>
-      static DOFMatrices make(Indices<R...>,
-                              RowFeSpaces&& rowFeSpaces,
-                              ColFeSpaces&& colFeSpace,
-                              MultiMatrix&& multiMatrix)
-      {
-        return DOFMatrices{make_row(
-          index_<R>,
-          MakeSeq_t<std::tuple_size<std::decay_t<ColFeSpaces>>::value>(),
-          std::get<R>(std::forward<RowFeSpaces>(rowFeSpaces)),
-          std::forward<ColFeSpaces>(colFeSpace),
-          std::get<R>(std::forward<MultiMatrix>(multiMatrix))
-          )...};
-      }
-
-      template <std::size_t R, std::size_t... C, class RowFeSpace, class ColFeSpaces, class MultiVector>
-      static DOFMatrixRow<R> make_row(index_t<R>,
-                                      Indices<C...>,
-                                      RowFeSpace&& rowFeSpace,
-                                      ColFeSpaces&& colFeSpace,
-                                      MultiVector&& multiVector)
-      {
-        return DOFMatrixRow<R>{DOFMatrixRowCol<R,C>(
-          std::forward<RowFeSpace>(rowFeSpace),
-          std::get<C>(std::forward<ColFeSpaces>(colFeSpace)),
-          "matrix[" + std::to_string(R) + "][" + std::to_string(C) + "]",
-          std::get<C>(std::forward<MultiVector>(multiVector))
-          )...};
-      }
-    };
-
-    template <class DOFMatrices, class RowFeSpaces, class ColFeSpaces, class MultiMatrix>
-    DOFMatrices buildDOFMatrices(RowFeSpaces&& rowFeSpaces,
-                                  ColFeSpaces&& colFeSpace,
-                                  MultiMatrix&& multiMatrix)
-    {
-        return BuildDOFMatrices<DOFMatrices>::make(
-            MakeSeq_t<std::tuple_size<std::decay_t<RowFeSpaces>>::value>(), // traverse rows first
-            std::forward<RowFeSpaces>(rowFeSpaces),
-            std::forward<ColFeSpaces>(colFeSpace),
-            std::forward<MultiMatrix>(multiMatrix));
-    }
-
-  } // end namespace Impl
-
-
-
-
-  /// \brief Container that repesents multiple data-Vectors of different value types.
-  /**
-    *  Represents a \ref Dune::MultiTypeBlockVector + a tuple of corresponding
-    *  feSpaces. This I'th \ref Dune::BlockVector compbined with the I'th FeSpace
-    *  builds a \ref DOFVector  and can be return by the \ref operator[].
-    *
-    *  By default, the ValueTypes are all \ref Dune::FieldMatrix of 1x1 double entry.
-    **/
-  template <class FeSpaces,
-            class FieldType  = double,
-            class Dimensions = Repeat_t<std::tuple_size<FeSpaces>::value, index_t<1>> >
-  class SystemMatrix
-  {
-    template <class RowFeSpace, class RowDim>
-    struct MultiMatrixRowGenerator
-    {
-      template <class ColDim>
-      using ValueTypeGenerator = Dune::FieldMatrix<FieldType, RowDim::value, ColDim::value>;
-      using ValueTypes = MakeTuple_t<ValueTypeGenerator, Dimensions>;
-
-      template <class ColFeSpace, class VT>
-      using DOFMatrixGenerator = DOFMatrix<RowFeSpace, ColFeSpace, VT>;
-      using DOFMatrices  = MakeTuple2_t<DOFMatrixGenerator, FeSpaces, ValueTypes>;
-
-      template <class VT>
-      using BaseMatrixGenerator = Dune::BCRSMatrix<VT, std::allocator<VT>>;
-      using BaseMatrices = MakeTuple_t<BaseMatrixGenerator, ValueTypes>;
-
-      using MultiVector = ExpandTuple_t<Dune::MultiTypeBlockVector, BaseMatrices>;
-    };
-
-    template <class RowFeSpace, class RowDim>
-    using MultiVectorGenerator = typename MultiMatrixRowGenerator<RowFeSpace, RowDim>::MultiVector;
-
-    template <class RowFeSpace, class RowDim>
-    using ValueTypeGenerator = typename MultiMatrixRowGenerator<RowFeSpace, RowDim>::ValueTypes;
-
-    template <class RowFeSpace, class RowDim>
-    using DOFMatrixGenerator = typename MultiMatrixRowGenerator<RowFeSpace, RowDim>::DOFMatrices;
-
-  public:
-    using MultiVectors = MakeTuple2_t<MultiVectorGenerator, FeSpaces, Dimensions>;
-    using ValueTypes   = MakeTuple2_t<ValueTypeGenerator, FeSpaces, Dimensions>;
-    using DOFMatrices  = MakeTuple2_t<DOFMatrixGenerator, FeSpaces, Dimensions>;
-    using MultiMatrix  = ExpandTuple_t<Dune::MultiTypeBlockMatrix, MultiVectors>;
-
-    static constexpr std::size_t nComponents = std::tuple_size<FeSpaces>::value;
-
-    AMDIS_STATIC_ASSERT( nComponents > 0 );
-    AMDIS_STATIC_ASSERT( nComponents == std::tuple_size<Dimensions>::value );
-
-    /// Constructor that constructs new base-vectors
-    SystemMatrix(FeSpaces const& feSpaces)
-      : feSpaces(feSpaces)
-      , matrix{}
-      , dofmatrices(Impl::buildDOFMatrices<DOFMatrices>(feSpaces, feSpaces, matrix))
-    {}
-
-
-    /// Return the number of vector entries
-    static constexpr std::size_t N()
-    {
-      return std::tuple_size<FeSpaces>::value;
-    }
-
-    static constexpr std::size_t M()
-    {
-      return std::tuple_size<FeSpaces>::value;
-    }
-
-    /// Return a shared pointer to the i'th underlaying base vector
-    template <std::size_t R, std::size_t C>
-    auto& getMatrix(const index_t<R> = {}, const index_t<C> = {})
-    {
-      static_assert(R < N() && C < M(), "Indices out of range [0,N)x[0,M)");
-      return std::get<C>(std::get<R>(matrix));
-    }
-
-    /// Return a shared pointer to the i'th underlaying base vector
-    template <std::size_t R, std::size_t C>
-    auto const& getMatrix(const index_t<R> = {}, const index_t<C> = {}) const
-    {
-      static_assert(R < N() && C < M(), "Indices out of range [0,N)x[0,M)");
-      return std::get<C>(std::get<R>(matrix));
-    }
-
-    /// Return the underlying multi vector
-    MultiMatrix& getMatrix()
-    {
-        return matrix;
-    }
-
-    MultiMatrix const& getMatrix() const
-    {
-      return matrix;
-    }
-
-    /// Return the I'th finite element space
-    template <std::size_t I = 0>
-    auto& getRowFeSpace(const index_t<I> = {}) const
-    {
-      static_assert(I < N(), "Index out of range [0,N)");
-      return std::get<I>(feSpaces);
-    }
-
-    template <std::size_t I = 0>
-    auto const& getColFeSpace(const index_t<I> = {}) const
-    {
-      static_assert(I < M(), "Index out of range [0,M)");
-      return std::get<I>(feSpaces);
-    }
-
-    template <std::size_t R = 0, std::size_t C = 0>
-    auto& operator()(const index_t<R> = {}, const index_t<C> = {})
-    {
-      static_assert(R < N() && C < M(), "Indices out of range [0,N)x[0,M)");
-      return std::get<C>(std::get<R>(dofmatrices));
-    }
-
-    /// Create a DOFVector with references to the unerlaying data
-    template <std::size_t R = 0, std::size_t C = 0>
-    auto const& operator()(const index_t<R> = {}, const index_t<C> = {}) const
-    {
-      static_assert(R < N() && C < M(), "Indices out of range [0,N)x[0,M)");
-      return std::get<C>(std::get<R>(dofmatrices));
-    }
-
-  private:
-    FeSpaces const& feSpaces;	///< a tuple of feSpaces
-    MultiMatrix 	matrix;		///< a tuple of data-vectors
-    DOFMatrices     dofmatrices;
-  };
-
-
-  // specialization for 1 component
-  // -------------------------------------------------------------------------
-
-  template <class FeSpace,
-            class FieldType,
-            int dim>
-  class SystemMatrix<std::tuple<FeSpace>, FieldType, std::tuple<index_t<dim>>>
-  {
-    using ValueType     = Dune::FieldMatrix<FieldType, dim, dim>;
-    using DOFMatrixType = DOFMatrix<FeSpace, FeSpace, ValueType>;
-
-  public:
-    using MultiMatrix   = typename DOFMatrixType::BaseMatrix;
-
-    static constexpr std::size_t nComponent = 1;
-
-
-    /// Constructor that constructs new base-vectors
-    template <class FeSpaces>
-    SystemMatrix(FeSpaces const& feSpaces)
-      : dofmatrix(std::get<0>(feSpaces), std::get<0>(feSpaces), "")
-    {}
-
-
-    /// Return the number of vector entries
-    static constexpr std::size_t N()
-    {
-      return 1;
-    }
-
-    static constexpr std::size_t M()
-    {
-      return 1;
-    }
-
-    /// Return a shared pointer to the i'th underlaying base vector
-    template <std::size_t R = 0, std::size_t C = 0>
-    MultiMatrix& getMatrix(const index_t<R> = {}, const index_t<C> = {})
-    {
-      static_assert(R == 0 && C == 0, "Indices out of range [0,1)x[0,1)");
-      return dofmatrix.getMatrix();
-    }
-
-    /// Return a shared pointer to the i'th underlaying base vector
-    template <std::size_t R = 0, std::size_t C = 0>
-    MultiMatrix const& getMatrix(const index_t<R> = {}, const index_t<C> = {}) const
-    {
-      static_assert(R == 0 && C == 0, "Indices out of range [0,1)x[0,1)");
-      return dofmatrix.getMatrix();
-    }
-
-    /// Return the underlying multi vector
-    MultiMatrix const& getMatrix() const
-    {
-      return dofmatrix.getMatrix();
-    }
-
-    MultiMatrix& getMatrix()
-    {
-      return dofmatrix.getMatrix();
-    }
-
-    /// Return the I'th finite element space
-    template <std::size_t I = 0>
-    FeSpace const& getRowFeSpace(const index_t<I> = {}) const
-    {
-      static_assert(I == 0, "Index out of range [0,1)");
-      return dofmatrix.getRowFeSpace();
-    }
-
-    template <std::size_t I = 0>
-    FeSpace const& getColFeSpace(const index_t<I> = {}) const
-    {
-      static_assert(I == 0, "Index out of range [0,1)");
-      return dofmatrix.getColFeSpace();
-    }
-
-    template <std::size_t R = 0, std::size_t C = 0>
-    DOFMatrixType& operator()(const index_t<R> = {}, const index_t<C> = {})
-    {
-      static_assert(R == 0 && C == 0, "Indices out of range [0,1)x[0,1)");
-      return dofmatrix;
-    }
-
-    /// Create a DOFVector with references to the unerlaying data
-    template <std::size_t R = 0, std::size_t C = 0>
-    DOFMatrixType const& operator()(const index_t<R> = {}, const index_t<C> = {}) const
-    {
-      static_assert(R == 0 && C == 0, "Indices out of range [0,1)x[0,1)");
-      return dofmatrix;
-    }
-
-  private:
-    DOFMatrixType  dofmatrix;
-  };
-
-#ifndef AMDIS_NO_EXTERN_SYSTEMMATRIX
-    // explicit instantiation in SystemMatrix.cpp
-    extern template class SystemMatrix<typename TestTraits<2,1>::FeSpaces>;
-    extern template class SystemMatrix<typename TestTraits<2,1,2>::FeSpaces>;
-#endif
-
-} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/istl/SystemVector.cpp b/src/amdis/linear_algebra/istl/SystemVector.cpp
deleted file mode 100644
index fc04f99bd3495ed19e973913814e6a57c97732c0..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/istl/SystemVector.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#define AMDIS_NO_EXTERN_SYSTEMVECTOR
-#include <amdis/linear_algebra/istl/SystemVector.hpp>
-#undef AMDIS_NO_EXTERN_SYSTEMVECTOR
-
-
-namespace AMDiS
-{
-  // explicit template instatiation
-  template class SystemVector<typename TestTraits<2,1>::FeSpaces>;
-  template class SystemVector<typename TestTraits<2,1,2>::FeSpaces>;
-} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/istl/SystemVector.hpp b/src/amdis/linear_algebra/istl/SystemVector.hpp
deleted file mode 100644
index 7dfcbb2bad000c96ee0a7fd6ee8e5daf012a08e4..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/istl/SystemVector.hpp
+++ /dev/null
@@ -1,383 +0,0 @@
-#pragma once
-
-#include <vector>
-#include <string>
-#include <memory>
-#include <tuple>
-
-#include <dune/istl/multitypeblockvector.hh>
-
-#include <amdis/Output.hpp>
-#include <amdis/common/Loops.hpp>
-#include <amdis/common/TupleUtility.hpp>
-#include <amdis/common/Utility.hpp>
-
-#include <amdis/linear_algebra/istl/DOFVector.hpp>
-
-// for explicit instantiation
-#include <amdis/ProblemStatTraits.hpp>
-
-namespace AMDiS
-{
-
-  namespace Impl
-  {
-    // DOFVectors = std::tuple< DOFVector<FeSpace, ValueType>... >
-    template <class DOFVectors>
-    struct BuildDOFVectors
-    {
-      template <std::size_t I>
-      using DOFVectorIdx = std::tuple_element_t<I, DOFVectors>;
-
-      template <std::size_t... I, class FeSpaces, class MultiVector>
-      static DOFVectors make(Indices<I...>,
-                              FeSpaces&& feSpaces,
-                              std::vector<std::string> const& names,
-                              MultiVector&& multiVector)
-      {
-        return DOFVectors{DOFVectorIdx<I>(
-          std::get<I>(std::forward<FeSpaces>(feSpaces)),
-          names[I],
-          std::get<I>(std::forward<MultiVector>(multiVector))
-          )...};
-      }
-    };
-
-    template <class DOFVectors, class FeSpaces, class MultiVector>
-    DOFVectors buildDOFVectors(FeSpaces&& feSpaces,
-                                    std::vector<std::string> const& names,
-                                    MultiVector&& multiVector)
-    {
-        return BuildDOFVectors<DOFVectors>::make(
-            MakeSeq_t<std::tuple_size<std::decay_t<FeSpaces>>::value>(),
-            std::forward<FeSpaces>(feSpaces),
-            names,
-            std::forward<MultiVector>(multiVector));
-    }
-
-  } // end namespace Impl
-
-
-  /// \brief Container that repesents multiple data-Vectors of different value types.
-  /**
-    *  Represents a \ref Dune::MultiTypeBlockVector + a tuple of corresponding
-    *  feSpaces. This I'th \ref Dune::BlockVector compbined with the I'th FeSpace
-    *  builds a \ref DOFVector  and can be return by the \ref operator[].
-    *
-    *  By default, the ValueTypes are all \ref Dune::FieldVector of 1 double entry.
-    **/
-  template <class FeSpaces,
-            class ValueTypes = Repeat_t<std::tuple_size<FeSpaces>::value, Dune::FieldVector<double,1>> >
-  class SystemVector
-  {
-    using Self = SystemVector;
-
-  public:
-    template <class T> using BlockVectorGenerator = Dune::BlockVector<T, std::allocator<T>>;
-
-    using BaseVectors = MakeTuple_t<BlockVectorGenerator, ValueTypes>;
-    using MultiVector = ExpandTuple_t<Dune::MultiTypeBlockVector, BaseVectors>;
-
-    using DOFVectors  = MakeTuple2_t<DOFVector, FeSpaces, ValueTypes>;
-
-    static constexpr std::size_t nComponents = std::tuple_size<FeSpaces>::value;
-
-    AMDIS_STATIC_ASSERT( nComponents > 0 );
-    AMDIS_STATIC_ASSERT( nComponents == std::tuple_size<ValueTypes>::value );
-
-    /// Constructor that constructs new base-vectors
-    SystemVector(FeSpaces const& feSpaces, std::vector<std::string> const& names)
-      : feSpaces(feSpaces)
-      , names(names)
-      , vector{}
-      , dofvectors(Impl::buildDOFVectors<DOFVectors>(feSpaces, names, vector))
-    {
-      compress();
-    }
-
-
-    /// Return the number of vector entries
-    static constexpr std::size_t size()
-    {
-      return std::tuple_size<FeSpaces>::value;
-    }
-
-    /// Return number of elements
-    int count() const
-    {
-      return int(size());
-    }
-
-    /// Return a shared pointer to the i'th underlaying base vector
-    template <std::size_t I>
-    auto& getVector(const index_t<I> = {})
-    {
-      static_assert(I < size(), "Index out of range [0,SIZE)" );
-      return std::get<I>(vector);
-    }
-
-    /// Return a shared pointer to the i'th underlaying base vector
-    template <std::size_t I>
-    auto const& getVector(const index_t<I> = {}) const
-    {
-      static_assert(I < size(), "Index out of range [0,SIZE)" );
-      return std::get<I>(vector);
-    }
-
-    /// Return the underlying multi vector
-    MultiVector& getVector()
-    {
-      return vector;
-    }
-
-    MultiVector const& getVector() const
-    {
-      return vector;
-    }
-
-    /// Return the I'th finite element space
-    template <std::size_t I = 0>
-    auto const& getFeSpace(const index_t<I> = {}) const
-    {
-      static_assert(I < size(), "Index out of range [0,SIZE)" );
-      return std::get<I>(feSpaces);
-    }
-
-    /// Return the name of the i'th DOFVector
-    std::string getName(std::size_t i) const
-    {
-        return names[i];
-    }
-
-    template <std::size_t I>
-    auto& operator[](const index_t<I>)
-    {
-      static_assert(I < size(), "Index out of range [0,SIZE)" );
-      return std::get<I>(dofvectors);
-    }
-
-    template <std::size_t I>
-    auto const& operator[](const index_t<I>) const
-    {
-      static_assert(I < size(), "Index out of range [0,SIZE)" );
-      return std::get<I>(dofvectors);
-    }
-
-    template <std::size_t I>
-    auto& getDOFVector(const index_t<I> = {})
-    {
-      static_assert(I < size(), "Index out of range [0,SIZE)" );
-      return std::get<I>(dofvectors);
-    }
-
-    template <std::size_t I>
-    auto const& getDOFVector(const index_t<I> = {}) const
-    {
-      static_assert(I < size(), "Index out of range [0,SIZE)" );
-      return std::get<I>(dofvectors);
-    }
-
-    /// Resize the I'th \ref vector to the sizes of the I'th \ref feSpaces.
-    template <std::size_t I = 0>
-    void compress(const index_t<I> = {})
-    {
-      std::get<I>(dofvectors).compress();
-    }
-
-    /// Resize the \ref vectors to the sizes of the \ref feSpaces.
-    void compress()
-    {
-      forEach(range_<0, size()>, [this](const auto I) {
-        std::get<I>(dofvectors).compress();
-      });
-    }
-
-    void copy(Self const& that)
-    {
-      forEach(range_<0, size()>, [this, &that](const auto I) {
-        std::get<I>(dofvectors).copy(that[I]);
-      });
-    }
-
-    template <class Scalar>
-    std::enable_if_t< std::is_arithmetic<Scalar>::value, Self&>
-    operator*=(Scalar s)
-    {
-      forEach(range_<0, size()>, [this, s](const auto I) {
-        std::get<I>(vector) *= s;
-      });
-      return *this;
-    }
-
-    template <class Scalar>
-    std::enable_if_t< std::is_arithmetic<Scalar>::value, Self&>
-    operator=(Scalar s)
-    {
-      forEach(range_<0, size()>, [this, s](const auto I) {
-        std::get<I>(vector) = s;
-      });
-      return *this;
-    }
-
-  private:
-    FeSpaces const& feSpaces;	///< a tuple of feSpaces
-    std::vector<std::string> names;
-
-    MultiVector vector;		///< a tuple of data-vectors
-    DOFVectors	dofvectors;	///< a tuple of dofvectors referencing \ref vector
-  };
-
-
-  // specialization for the case of only 1 component.
-
-  template <class FeSpace, class ValueType>
-  class SystemVector<std::tuple<FeSpace>, std::tuple<ValueType>>
-  {
-    using Self = SystemVector;
-
-  public:
-    using MultiVector = Dune::BlockVector<ValueType>;
-    using DOFVectors  = DOFVector<FeSpace, ValueType>;
-
-    static constexpr std::size_t nComponent = 1;
-
-    /// Constructor that constructs new base-vectors
-    template <class FeSpaces>
-    SystemVector(FeSpaces const& feSpaces, std::vector<std::string> const& names)
-      : dofvector(std::get<0>(feSpaces), names.front())
-    {
-      compress();
-    }
-
-
-    /// Return the number of vector entries
-    static constexpr std::size_t size()
-    {
-      return 1;
-    }
-
-    /// Return number of elements
-    int count() const
-    {
-      return 1;
-    }
-
-    /// Return a shared pointer to the i'th underlaying base vector
-    template <std::size_t I = 0>
-    MultiVector& getVector(const index_t<I> = {})
-    {
-      static_assert(I == 0, "Index out of range [0,1)");
-      return dofvector.getVector();
-    }
-
-    /// Return a shared pointer to the i'th underlaying base vector
-    template <std::size_t I = 0>
-    MultiVector const& getVector(const index_t<I> = {}) const
-    {
-      static_assert(I == 0, "Index out of range [0,1)");
-      return dofvector.getVector();
-    }
-
-    /// Return the underlying multi vector
-    MultiVector& getVector()
-    {
-      return dofvector.getVector();
-    }
-
-    MultiVector const& getVector() const
-    {
-      return dofvector.getVector();
-    }
-
-    /// Return the I'th finite element space
-    template <std::size_t I = 0>
-    auto const& getFeSpace(const index_t<I> = {}) const
-    {
-      static_assert(I == 0, "Index out of range [0,1)");
-      return dofvector.getFeSpace();
-    }
-
-    /// Return the name of the i'th DOFVector
-    std::string getName(std::size_t i = 0) const
-    {
-      test_exit(i == 0, "Index out of range [0,1)");
-      return dofvector.getName();
-    }
-
-    template <std::size_t I>
-    auto& operator[](const index_t<I>)
-    {
-      static_assert(I == 0, "Index out of range [0,1)");
-      return dofvector;
-    }
-
-    template <std::size_t I>
-    auto const& operator[](const index_t<I>) const
-    {
-      static_assert(I == 0, "Index out of range [0,1)");
-      return dofvector;
-    }
-
-    template <std::size_t I>
-    auto& getDOFVector(const index_t<I> = {})
-    {
-      static_assert(I == 0, "Index out of range [0,1)");
-      return dofvector;
-    }
-
-    template <std::size_t I>
-    auto const& getDOFVector(const index_t<I> = {}) const
-    {
-      static_assert(I == 0, "Index out of range [0,1)");
-      return dofvector;
-    }
-
-    /// Resize the I'th \ref vector to the sizes of the I'th \ref feSpaces.
-    template <std::size_t I = 0>
-    void compress(const index_t<I> = {})
-    {
-      static_assert(I == 0, "Index out of range [0,1)");
-      dofvector.compress();
-    }
-
-    /// Resize the \ref vectors to the sizes of the \ref feSpaces.
-    void compress()
-    {
-      dofvector.compress();
-    }
-
-    void copy(Self const& that)
-    {
-      dofvector.copy(that[_0]);
-    }
-
-    template <class Scalar>
-    std::enable_if_t< std::is_arithmetic<Scalar>::value, Self&>
-    operator*=(Scalar s)
-    {
-      dofvector.getVector() *= s;
-      return *this;
-    }
-
-    template <class Scalar>
-    std::enable_if_t< std::is_arithmetic<Scalar>::value, Self&>
-    operator=(Scalar s)
-    {
-      dofvector.getVector() = s;
-      return *this;
-    }
-
-  private:
-    DOFVectors      dofvector;  ///< a tuple of sofvectors referencing \ref vector
-  };
-
-
-
-
-#ifndef AMDIS_NO_EXTERN_SYSTEMVECTOR
-    // explicit instantiation in SystemVector.cpp
-    extern template class SystemVector<typename TestTraits<2,1>::FeSpaces>;
-    extern template class SystemVector<typename TestTraits<2,1,2>::FeSpaces>;
-#endif
-
-} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/mtl/BITL_Preconditioner.hpp b/src/amdis/linear_algebra/mtl/BITL_Preconditioner.hpp
deleted file mode 100644
index 8a5739689d56b9406fc696096879fb6a6ff1dc84..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/mtl/BITL_Preconditioner.hpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma once
-
-#include "itl/block_diagonal.hpp"
-
-#include <amdis/CreatorMap.hpp>
-#include <amdis/linear_algebra/mtl/ITL_Preconditioner.hpp>
-
-namespace AMDiS
-{
-
-  template <class SubMatrix, std::size_t _N, std::size_t _M, class Vector>
-  class DefaultCreators<PreconditionerInterface<BlockMTLMatrix<SubMatrix, _N, _M>, Vector>>
-  {
-    using Matrix = BlockMTLMatrix<SubMatrix, _N, _M>;
-    using PreconBase = PreconditionerInterface<Matrix, Vector>;
-
-    template <template<class> class ITLPrecon>
-    using PreconCreator
-      = typename Preconditioner<Matrix, Vector, ITLPrecon<Matrix>>::Creator;
-
-    using Map = CreatorMap<PreconBase>;
-
-  public:
-    static void init()
-    {
-      auto pc_diag = new PreconCreator<DiagonalPreconditioner>;
-      Map::addCreator("diag", pc_diag);
-      Map::addCreator("jacobi", pc_diag);
-
-      auto pc_id = new PreconCreator<IdentityPreconditioner>;
-      Map::addCreator("identity", pc_id);
-      Map::addCreator("no", pc_id);
-
-      Map::addCreator("default", pc_id);
-    }
-  };
-
-} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/mtl/BITL_Solver.hpp b/src/amdis/linear_algebra/mtl/BITL_Solver.hpp
deleted file mode 100644
index c011bdc769633a0d49c109d654763dc56efd6b41..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/mtl/BITL_Solver.hpp
+++ /dev/null
@@ -1,83 +0,0 @@
-#pragma once
-
-#include <amdis/CreatorMap.hpp>
-#include <amdis/linear_algebra/mtl/ITL_Solver.hpp>
-
-namespace AMDiS
-{
-  /// Adds default creators for linear solvers based on `BlockMTLMatrix`.
-  /**
-   * Adds creators for block matrix aware solvers.
-   * - *cg*: conjugate gradient method, \see cg_solver_type
-   * - *cgs*: stabilized conjugate gradient mtheod, \see cgs_solver_type
-   * - *bcgs*: stabilized bi-conjugate gradient method, \see bicgstab_type
-   * - *tfqmr*: Transposed-Free Quasi-Minimal Residual method, \see tfqmr_solver_type
-   * - *bcgsl*: stabilized BiCG(ell) method, \see bicgstab_ell_type
-   * - *gmres*: Generalized minimal residula method, \see gmres_type
-   * - *fgmres*: Flexible GMRES, \see fgmres_type
-   * - *minres*: Minimal residul method, \see minres_solver_type
-   * - *gcr*: Generalized conjugate residual method, \see gcr_type
-   * - *umfpack*: external UMFPACK solver, \see UmfpackRunner
-   **/
-  template <class SubMatrix, std::size_t _N, std::size_t _M, class Vector>
-  class DefaultCreators<LinearSolverInterface<BlockMTLMatrix<SubMatrix, _N, _M>, Vector, Vector>>
-  {
-    using Matrix = BlockMTLMatrix<SubMatrix, _N, _M>;
-    using SolverBase = LinearSolverInterface<Matrix, Vector, Vector>;
-
-    template <class ITLSolver>
-    using SolverCreator
-      = typename LinearSolver<Matrix, Vector,
-          KrylovRunner<ITLSolver, Matrix, BaseVector_t<Vector>>>::Creator;
-
-#ifdef HAVE_UMFPACK
-    using UmfpackSolverCreator
-      = typename LinearSolver<Matrix, Vector,
-          UmfpackRunner<Matrix, BaseVector_t<Vector>>>::Creator;
-#endif
-
-    using Map = CreatorMap<SolverBase>;
-
-  public:
-    static void init()
-    {
-      auto cg = new SolverCreator<cg_solver_type>;
-      Map::addCreator("cg", cg);
-
-      auto cgs = new SolverCreator<cgs_solver_type>;
-      Map::addCreator("cgs", cgs);
-
-      auto bcgs = new SolverCreator<bicgstab_type>;
-      Map::addCreator("bicgstab", bcgs);
-      Map::addCreator("bcgs", bcgs);
-
-      auto tfqmr = new SolverCreator<tfqmr_solver_type>;
-      Map::addCreator("tfqmr", tfqmr);
-
-      auto bcgsl = new SolverCreator<bicgstab_ell_type>;
-      Map::addCreator("bicgstab_ell", bcgsl);
-      Map::addCreator("bcgsl", bcgsl);
-
-      auto gmres = new SolverCreator<gmres_type>;
-      Map::addCreator("gmres", gmres);
-
-      auto fgmres = new SolverCreator<fgmres_type>;
-      Map::addCreator("fgmres", fgmres);
-
-      auto minres = new SolverCreator<minres_solver_type>;
-      Map::addCreator("minres", minres);
-
-      auto gcr = new SolverCreator<gcr_type>;
-      Map::addCreator("gcr", gcr);
-
-#ifdef HAVE_UMFPACK
-      auto umfpack = new UmfpackSolverCreator;
-      Map::addCreator("umfpack", umfpack);
-      Map::addCreator("direct", umfpack);
-#endif
-
-      Map::addCreator("default", gmres);
-    }
-  };
-
-} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/mtl/BlockMTLMatrix.hpp b/src/amdis/linear_algebra/mtl/BlockMTLMatrix.hpp
deleted file mode 100644
index ef661b363706530a4b5672b1a9b2f808f91295ca..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/mtl/BlockMTLMatrix.hpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/** \file BlockMTLMatrix.hpp */
-
-#pragma once
-
-#include <array>
-
-#include <boost/numeric/mtl/matrices.hpp>
-
-#include <amdis/common/Utility.hpp>
-#include <amdis/common/Literals.hpp>
-#include <amdis/common/Loops.hpp>
-#include <amdis/linear_algebra/LinearAlgebraBase.hpp>
-
-namespace AMDiS
-{
-  /// A wrapper for AMDiS::SolverMatrix to be used in MTL/ITL solvers
-  template <class MTLMatrix, std::size_t _N, std::size_t _M>
-  class BlockMTLMatrix
-      : public std::array<std::array<MTLMatrix, _M>, _N>
-  {
-    using Self = BlockMTLMatrix;
-
-  public:
-    /// The index/size - type
-    using size_type  = typename MTLMatrix::size_type;
-
-    /// The type of the elements of the MTLMatrix
-    using value_type = typename MTLMatrix::value_type;
-
-    /// The underlying mtl matrix type
-    using BaseMatrix = MTLMatrix;
-
-  public:
-    /// Return the (R,C)'th matrix block
-    template <std::size_t R, std::size_t C>
-    auto& operator()(const index_t<R>, const index_t<C>)
-    {
-      static_assert(R < N() && C < M(), "Indices out of range [0,N)x[0,M)");
-      return std::get<C>(std::get<R>(*this));
-    }
-
-    /// Return the (R,C)'th matrix block
-    template <std::size_t R, std::size_t C>
-    auto const& operator()(const index_t<R>, const index_t<C>) const
-    {
-      static_assert(R < N() && C < M(), "Indices out of range [0,N)x[0,M)");
-      return std::get<C>(std::get<R>(*this));
-    }
-
-    /// Return the number of row blocks
-    static constexpr std::size_t N() { return _N; }
-
-    /// Return the number of column blocks
-    static constexpr std::size_t M() { return _M; }
-
-    /// perform blockwise multiplication A*b -> x
-    template <class VectorIn, class VectorOut, class Assign>
-    void mult(VectorIn const& b, VectorOut& x, Assign) const
-    {
-      // create iranges to access array blocks
-      std::array<mtl::irange, _N> r_rows;
-      std::array<mtl::irange, _M> r_cols;
-      getRanges(r_rows, r_cols);
-
-      forEach(range_<0, _N>, [&](const auto _i)
-      {
-        bool first = true;
-
-        // a reference to the i'th block of x
-        VectorOut x_i(x[r_rows[_i]]);
-        forEach(range_<0, _M>, [&](const auto _j)
-        {
-          auto const& A_ij = this->operator()(_i, _j);
-          if (num_rows(A_ij) > 0 && A_ij.nnz() > 0) {
-            // a reference to the j'th block of b
-            const VectorIn b_j(b[r_cols[_j]]);
-
-            if (first) {
-              Assign::first_update(x_i, A_ij * b_j);
-              first = false;
-            }
-            else {
-              Assign::update(x_i, A_ij * b_j);
-            }
-          }
-        });
-      });
-    }
-
-    /// A Multiplication operator returns a multiplication-expresssion.
-    /// Calls \ref mult internally.
-    template <class VectorIn>
-    mtl::vec::mat_cvec_multiplier<Self, VectorIn>
-    operator*(VectorIn const& v) const
-    {
-      return {*this, v};
-    }
-
-    /// Fill an array of irange corresponding to the row-sizes, used
-    /// to access sub-vectors
-    void getRowRanges(std::array<mtl::irange, _N>& r_rows) const
-    {
-      std::size_t start = 0;
-      forEach(range_<0, _N>, [&](const auto _r) {
-        std::size_t finish = start + num_rows((*this)(_r, 0_c));
-        r_rows[_r].set(start, finish);
-        start = finish;
-      });
-    }
-
-    /// Fill an array of irange corresponding to the column-sizes, used
-    /// to access sub-vectors
-    void getColRanges(std::array<mtl::irange, _M>& r_cols) const
-    {
-      std::size_t start = 0;
-      forEach(range_<0, _M>, [&](const auto _c) {
-        std::size_t finish = start + num_cols((*this)(0_c, _c));
-        r_cols[_c].set(start, finish);
-        start = finish;
-      });
-    }
-
-    /// Fill two arrays of irange corresponding to row and column sizes.
-    /// \see getRowRanges() and \see getColRanges()
-    void getRanges(std::array<mtl::irange, _N>& r_rows,
-                   std::array<mtl::irange, _M>& r_cols) const
-    {
-      getRowRanges(r_rows);
-      getColRanges(r_cols);
-    }
-  };
-
-
-  namespace Impl
-  {
-    /// Specialization of Impl::MTLMatrix from \file LinearAlgebraBase.hpp
-    template <class MTLMatrix, std::size_t _N, std::size_t _M>
-    struct BaseMatrix<BlockMTLMatrix<MTLMatrix, _N, _M>>
-    {
-      using type = MTLMatrix;
-    };
-  }
-
-  /// Return the number of overall rows of a BlockMTLMatrix
-  template <class MTLMatrix, std::size_t _N, std::size_t _M>
-  inline std::size_t num_rows(BlockMTLMatrix<MTLMatrix, _N, _M> const& A)
-  {
-    std::size_t nRows = 0;
-    forEach(range_<0, _N>, [&](const auto _r) {
-      nRows += num_rows(A(_r, 0_c));
-    });
-    return nRows;
-  }
-
-  /// Return the number of overall columns of a BlockMTLMatrix
-  template <class MTLMatrix, std::size_t _N, std::size_t _M>
-  inline std::size_t num_cols(BlockMTLMatrix<MTLMatrix, _N, _M> const& A)
-  {
-    std::size_t nCols = 0;
-    forEach(range_<0, _M>, [&](const auto _c) {
-      nCols += num_cols(A(0_c, _c));
-    });
-    return nCols;
-  }
-
-  /// Return the size, i.e. rows*columns of a BlockMTLMatrix
-  template <class MTLMatrix, std::size_t _N, std::size_t _M>
-  inline std::size_t size(BlockMTLMatrix<MTLMatrix, _N, _M> const& A)
-  {
-    return num_rows(A) * num_cols(A);
-  }
-
-  /// Nullify a BlockMTLMatrix, i.e. nullify each block.
-  template <class MTLMatrix, std::size_t _N, std::size_t _M>
-  inline void set_to_zero(BlockMTLMatrix<MTLMatrix, _N, _M>& A)
-  {
-    forEach(range_<0, _N>, [&](const auto _r) {
-      forEach(range_<0, _M>, [&](const auto _c) {
-        set_to_zero(A(_r,_c));
-      });
-    });
-  }
-
-} // end namespace AMDiS
-
-
-/// \cond HIDDEN_SYMBOLS
-namespace mtl
-{
-  template <class MTLMatrix, std::size_t _N, std::size_t _M>
-  struct Collection<AMDiS::BlockMTLMatrix<MTLMatrix, _N, _M>>
-  {
-    using value_type = typename MTLMatrix::value_type;
-    using size_type  = typename MTLMatrix::size_type;
-  };
-
-  namespace ashape
-  {
-    template <class MTLMatrix, std::size_t _N, std::size_t _M>
-    struct ashape_aux<AMDiS::BlockMTLMatrix<MTLMatrix, _N, _M>>
-    {
-      using type = nonscal;
-    };
-
-  } // end namespace ashape
-
-} // end namespace mtl
-/// \endcond
diff --git a/src/amdis/linear_algebra/mtl/BlockMTLVector.hpp b/src/amdis/linear_algebra/mtl/BlockMTLVector.hpp
deleted file mode 100644
index 05d93d238c0798722d1682b17689493d009c1671..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/mtl/BlockMTLVector.hpp
+++ /dev/null
@@ -1,186 +0,0 @@
-#pragma once
-
-#include <array>
-#include <type_traits>
-
-#include <boost/numeric/mtl/utility/irange.hpp>
-
-#include <amdis/common/Mpl.hpp>
-#include <amdis/linear_algebra/LinearAlgebraBase.hpp>
-#include <amdis/linear_algebra/mtl/MTLDenseVector.hpp>
-
-namespace AMDiS
-{
-  /// A simple block-vector class
-  template <class MTLVector, std::size_t N>
-  class BlockMTLVector
-      : public std::array<MTLVector, N>
-  {
-  public:
-    /// The type of the blocks
-    using BaseVector = MTLVector;
-
-    /// The index/size - type
-    using size_type  = typename MTLVector::size_type;
-
-    /// The type of the elements of the MTLVector
-    using value_type = typename MTLVector::value_type;
-  };
-
-
-  namespace Impl
-  {
-    /// Specialization of Impl::BaseVector from \file LinearAlgebraBase.hpp
-    template <class MTLVector, std::size_t N>
-    struct BaseVector<BlockMTLVector<MTLVector, N>>
-    {
-      using type = MTLVector;
-    };
-  }
-
-
-  /// Return the number of overall rows of a BlockMTLVector
-  template <class MTLVector, std::size_t N>
-  inline std::size_t num_rows(BlockMTLVector<MTLVector, N> const& vec)
-  {
-    std::size_t nRows = 0;
-    forEach(range_<0, N>, [&](const auto _i) {
-      nRows += num_rows(std::get<_i>(vec));
-    });
-    return nRows;
-  }
-
-  /// Return the number of overall columns of a BlockMTLVector
-  template <class MTLVector, std::size_t N>
-  inline std::size_t num_cols(BlockMTLVector<MTLVector, N> const& vec)
-  {
-    return 1;
-  }
-
-  /// Return the size, i.e. rows*columns of a BlockMTLVector
-  template <class MTLVector, std::size_t N>
-  inline std::size_t size(BlockMTLVector<MTLVector, N> const& vec)
-  {
-    return num_rows(vec);
-  }
-
-  /// Nullify a BlockMTLVector, i.e. nullify each block.
-  template <class MTLVector, std::size_t N>
-  inline void set_to_zero(BlockMTLVector<MTLVector, N>& vec)
-  {
-    forEach(range_<0, N>, [&](const auto _i) {
-      set_to_zero(std::get<_i>(vec));
-    });
-  }
-
-
-  /// A wrapper, that creates a contiguos vector corresponding to a block-vector
-  /// and copy the value on construction and eventually back on destruction, if
-  /// required.
-  template <class BlockVector, class Vector, class NonConstBlockVector>
-  class BlockVectorWrapper;
-
-  // specialization for BlockMTLVector
-  template <class BlockVector, class Vector, class MTLVector, std::size_t N>
-  class BlockVectorWrapper<BlockVector, Vector, BlockMTLVector<MTLVector, N>>
-  {
-    static_assert( std::is_same< std::remove_const_t<BlockVector>, BlockMTLVector<MTLVector, N> >::value,
-                   "This specialization is for BlockMTLVectors only.");
-
-  public:
-    explicit BlockVectorWrapper(BlockVector& blockVector,
-                                bool copyBack = !std::is_const<BlockVector>::value)
-      : blockVector(blockVector)
-      , vector(num_rows(blockVector))
-      , copyBack(copyBack)
-    {
-      assignTo();
-    }
-
-    ~BlockVectorWrapper()
-    {
-      if (copyBack)
-        assignFrom(bool_<!std::is_const<BlockVector>::value>);
-    }
-
-    /// Return a reference to the block-vector
-    BlockVector const&  getBlockVector() const  { return blockVector; }
-
-    /// Return a reference to the contiguose-vector
-    Vector&       getVector()       { return vector; }
-    Vector const& getVector() const { return vector; }
-
-  private:
-    /// copy from block-vector to vector
-    void assignTo()
-    {
-      std::size_t start = 0;
-      for (std::size_t r = 0; r < N; ++r) {
-        std::size_t finish = start + num_rows(blockVector[r]);
-        mtl::irange range(start, finish);
-
-        vector[range] = blockVector[r];
-        start = finish;
-      }
-    }
-
-    /// do not copy vector to block-vector since this is const
-    template <bool Copy>
-    std::enable_if_t<!Copy> assignFrom(bool_t<Copy>) { /* Do nothing */ }
-
-    /// copy from vector to block-vector
-    template <bool Copy>
-    std::enable_if_t<Copy> assignFrom(bool_t<Copy>)
-    {
-      std::size_t start = 0;
-      for (std::size_t r = 0; r < N; ++r) {
-        std::size_t finish = start + num_rows(blockVector[r]);
-        mtl::irange range(start, finish);
-
-        blockVector[r] = vector[range];
-        start = finish;
-      }
-    }
-
-  private:
-    BlockVector& blockVector;
-    Vector vector;
-
-    /// Copy data back to block-vector on destruction
-    bool copyBack;
-  };
-
-
-  // Specialization for non-block-vectors
-  template <class BlockVector, class Vector>
-  class BlockVectorWrapper<BlockVector, Vector, Vector>
-  {
-    static_assert( std::is_same< std::remove_const_t<BlockVector>, Vector >::value,
-                   "This specialization is for contiguose vectors only.");
-  public:
-    explicit BlockVectorWrapper(BlockVector& vector, bool = false)
-      : vector(vector)
-    {}
-
-    /// Return a reference to the vector
-    BlockVector const& getBlockVector() const { return vector; }
-    BlockVector&       getVector()            { return vector; }
-    BlockVector const& getVector()      const { return vector; }
-
-  private:
-    BlockVector& vector;
-  };
-
-  template <class BlockVector, class Vector>
-  using BlockVectorWrapper_t
-    = BlockVectorWrapper<BlockVector, Vector, std::remove_const_t<BlockVector>>;
-
-
-  template <class BlockVector, class Vector = MTLDenseVector<typename BlockVector::value_type>>
-  auto blockWrapper(BlockVector& bvec)
-  {
-    return BlockVectorWrapper_t<BlockVector, Vector>{bvec};
-  }
-
-
-} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/mtl/CMakeLists.txt b/src/amdis/linear_algebra/mtl/CMakeLists.txt
index 0e6d6a6706c12d6bc4d862d2dfb09b1ff4649065..e295f73f7767c0b95987825dd993f89720bc30f5 100644
--- a/src/amdis/linear_algebra/mtl/CMakeLists.txt
+++ b/src/amdis/linear_algebra/mtl/CMakeLists.txt
@@ -1,25 +1,10 @@
-#dune_library_add_sources(amdis SOURCES
-#    SystemMatrix.cpp
-#    SystemVector.cpp
-#)
-
 install(FILES
-    BITL_Preconditioner.hpp
-    BITL_Solver.hpp
-    BlockMTLMatrix.hpp
-    BlockMTLVector.hpp
-    Copy.hpp
     DOFMatrix.hpp
     DOFVector.hpp
     ITL_Preconditioner.hpp
     ITL_Solver.hpp
     KrylovRunner.hpp
-    LinearSolver.hpp
-    Mapper.hpp
-    MTLDenseVector.hpp
     Preconditioner.hpp
-    SystemMatrix.hpp
-    SystemVector.hpp
     UmfpackRunner.hpp
 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/amdis/linear_algebra/mtl)
 
diff --git a/src/amdis/linear_algebra/mtl/Copy.hpp b/src/amdis/linear_algebra/mtl/Copy.hpp
deleted file mode 100644
index 1724b311ac95756a312d1c5bf8d5f3b348e8e842..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/mtl/Copy.hpp
+++ /dev/null
@@ -1,52 +0,0 @@
-#pragma once
-
-#include <algorithm>
-
-#include <amdis/linear_algebra/mtl/BlockMTLVector.hpp>
-#include <amdis/linear_algebra/mtl/BlockMTLMatrix.hpp>
-
-#include <amdis/linear_algebra/mtl/SystemVector.hpp>
-#include <amdis/linear_algebra/mtl/SystemMatrix.hpp>
-
-#include <amdis/linear_algebra/mtl/Mapper.hpp>
-
-namespace AMDiS
-{
-  // requires MatrixType to have an inserter
-  template <class Value, std::size_t _N, std::size_t _M, class TargetType>
-  void copy(BlockMTLMatrix<Value, _N, _M> const& source, TargetType& target)
-  {
-    using Mapper = std::conditional_t<(_N == _M), BlockMapper, RectangularMapper>;
-    using value_type = typename TargetType::value_type;
-    using BaseInserter = mtl::mat::inserter<TargetType, mtl::operations::update_plus<value_type>>;
-    using MappedInserter = typename Mapper::template Inserter<BaseInserter>::type;
-
-    std::size_t nnz = 0;
-    for (std::size_t rb = 0; rb < _N; ++rb)
-      for (std::size_t cb = 0; cb < _M; ++cb)
-        nnz += source[rb][cb].nnz();
-
-    {
-      target.change_dim(num_rows(source), num_cols(source));
-      set_to_zero(target);
-
-      Mapper mapper(source);
-      MappedInserter ins(target, mapper, int(1.2 * nnz / target.dim1()));
-
-      for (std::size_t rb = 0; rb < _N; ++rb) {
-        mapper.setRow(rb);
-        for (std::size_t cb = 0; cb < _M; ++cb) {
-	        mapper.setCol(cb);
-          ins << source[rb][cb];
-        }
-      }
-    }
-  }
-
-  template <class FeSpaces, class Value, class TargetType>
-  void copy(SystemMatrix<FeSpaces, Value> const& source, TargetType& target)
-  {
-    copy(source.getMatrix(), target);
-  }
-
-} // end namespace AMDiS
\ No newline at end of file
diff --git a/src/amdis/linear_algebra/mtl/DOFMatrix.hpp b/src/amdis/linear_algebra/mtl/DOFMatrix.hpp
index dba705f9dba0809107058fb1ea8e3e12dd71ccb3..5d3824c10d697d0d442f7714904e57f3c0b6a69c 100644
--- a/src/amdis/linear_algebra/mtl/DOFMatrix.hpp
+++ b/src/amdis/linear_algebra/mtl/DOFMatrix.hpp
@@ -1,7 +1,6 @@
 #pragma once
 
 #include <list>
-#include <map>
 #include <memory>
 #include <string>
 #include <vector>
@@ -11,148 +10,74 @@
 #include <boost/numeric/mtl/utility/property_map.hpp>
 #include <boost/numeric/mtl/utility/range_wrapper.hpp>
 
-#include <dune/common/std/optional.hh>
-#include <dune/common/reservedvector.hh>
-#include <dune/functions/functionspacebases/flatmultiindex.hh>
-
 #include <amdis/Output.hpp>
-#include <amdis/common/ClonablePtr.hpp>
+#include <amdis/linear_algebra/Common.hpp>
+#include <amdis/linear_algebra/DOFMatrixBase.hpp>
+#include <amdis/utility/MultiIndex.hpp>
 
 namespace AMDiS
 {
   /// \brief The basic container that stores a base matrix and a corresponding
   /// row/column feSpace.
-  template <class RowFeSpaceType,
-            class ColFeSpaceType,
-            class ValueType = double>
-  class DOFMatrix
+  template <class ValueType>
+  class MtlMatrix
   {
   public:
-    /// The type of the finite element space / basis of the row
-    using RowFeSpace = RowFeSpaceType;
-
-    /// The type of the finite element space / basis of the column
-    using ColFeSpace = ColFeSpaceType;
-
     /// The matrix type of the underlying base matrix
     using BaseMatrix = mtl::compressed2D<ValueType>;
 
-    /// The index/size - type
-    using size_type  = typename BaseMatrix::size_type;
-
     /// The type of the elements of the DOFMatrix
     using value_type = ValueType;
 
-    /// The underlying field-type (typically the same as \ref value_type)
-    using field_type = typename BaseMatrix::value_type;
+    /// The index/size - type
+    using size_type = typename BaseMatrix::size_type;
 
     /// The type of the inserter used when filling the matrix. NOTE: need not be public
     using Inserter = mtl::mat::inserter<BaseMatrix, mtl::operations::update_plus<value_type>>;
 
   public:
     /// Constructor. Constructs new BaseMatrix.
-    DOFMatrix(RowFeSpace const& rowFeSpace,
-              ColFeSpace const& colFeSpace,
-              std::string name)
-      : rowFeSpace(rowFeSpace)
-      , colFeSpace(colFeSpace)
-      , name(name)
-      , matrix(ClonablePtr<BaseMatrix>::make())
-    {}
-
-    /// Constructor. Takes pointer of data-matrix.
-    DOFMatrix(RowFeSpace const& rowFeSpace,
-              ColFeSpace const& colFeSpace,
-              std::string name,
-              BaseMatrix& matrix_ref)
-      : rowFeSpace(rowFeSpace)
-      , colFeSpace(colFeSpace)
-      , name(name)
-      , matrix(matrix_ref)
-    {}
-
-    /// Return the row-basis \ref rowFeSpace of the matrix
-    RowFeSpace const& getRowFeSpace() const
-    {
-      return rowFeSpace;
-    }
-
-    /// Return the col-basis \ref colFeSpace of the matrix
-    ColFeSpace const& getColFeSpace() const
-    {
-      return colFeSpace;
-    }
+    MtlMatrix() = default;
 
     /// Return a reference to the data-matrix \ref matrix
-    BaseMatrix& getMatrix()
+    BaseMatrix& matrix()
     {
-      assert( !insertionMode );
-      return *matrix;
+      assert( !inserter_ );
+      return matrix_;
     }
 
     /// Return a reference to the data-matrix \ref matrix
-    BaseMatrix const& getMatrix() const
+    BaseMatrix const& matrix() const
     {
-      assert( !insertionMode );
-      return *matrix;
+      assert( !inserter_ );
+      return matrix_;
     }
 
-    /// Return the size of the row \ref feSpace
-    size_type N() const
-    {
-      return rowFeSpace.size();
-    }
-
-    /// Return the size of the column \ref feSpace
-    size_type M() const
-    {
-      return colFeSpace.size();
-    }
-
-    /// Return the \ref name of this matrix
-    std::string getName() const
-    {
-      return name;
-    }
-
-
-    using FlatIndex = Dune::Functions::FlatMultiIndex<size_type>;
-    using BlockIndex = Dune::ReservedVector<size_type,1>;
 
     /// \brief Returns an update-proxy of the inserter, to inserte/update a value at
     /// position (\p r, \p c) in the matrix. Need an insertionMode inserter, that can
     /// be created by \ref init and must be closed by \ref finish after insertion.
-    auto operator()(FlatIndex row, FlatIndex col)
+    void insert(size_type r, size_type c, value_type const& value)
     {
-      size_type r = row[0], c = col[0];
-      test_exit_dbg( insertionMode, "Inserter not initilized!");
-      test_exit_dbg( r < N() && c < M() ,
-          "Indices out of range [0,", N(), ")x[0,", M(), ")" );
-      return (*inserter)[r][c];
+      test_exit_dbg(inserter_, "Inserter not initilized!");
+      test_exit_dbg(r < num_rows(matrix_) && c < num_cols(matrix_),
+          "Indices out of range [0,", num_rows(matrix_), ")x[0,", num_cols(matrix_), ")" );
+      (*inserter_)[r][c] += value;
     }
 
-    auto operator()(BlockIndex row, BlockIndex col)
-    {
-      size_type r = row[0], c = col[0];
-      test_exit_dbg( insertionMode, "Inserter not initilized!");
-      test_exit_dbg( r < N() && c < M() ,
-          "Indices out of range [0,", N(), ")x[0,", M(), ")" );
-      return (*inserter)[r][c];
-    }
 
     /// Create inserter. Assumes that no inserter is currently active on this matrix.
-    void init(bool prepareForInsertion)
+    template <class RowBasis, class ColBasis>
+    void init(RowBasis const& rowBasis, ColBasis const& colBasis,
+              bool prepareForInsertion)
     {
-      test_exit(!insertionMode && !inserter, "Matrix already in insertion mode!");
+      test_exit(!inserter_, "Matrix already in insertion mode!");
 
       calculateSlotSize();
-      matrix->change_dim(rowFeSpace.dimension(), colFeSpace.dimension());
-      test_exit(num_rows(*matrix) == rowFeSpace.dimension() && num_cols(*matrix) == colFeSpace.dimension(),
-        "Wrong dimensions in matrix");
+      matrix_.change_dim(rowBasis.dimension(), colBasis.dimension());
       if (prepareForInsertion) {
-        set_to_zero(*matrix);
-        inserter = new Inserter(*matrix, slot_size);
-        insertionMode = true;
+        set_to_zero(matrix_);
+        inserter_ = new Inserter(matrix_, slotSize_);
       }
     }
 
@@ -160,45 +85,27 @@ namespace AMDiS
     /// final construction of the matrix.
     void finish()
     {
-      delete inserter;
-      inserter = NULL;
-      insertionMode = false;
+      delete inserter_;
+      inserter_ = nullptr;
     }
 
     /// Return the number of nonzeros in the matrix
-    std::size_t getNnz() const
+    std::size_t nnz() const
     {
-      return matrix->nnz();
+      return matrix_.nnz();
     }
 
     /// \brief Deletes all rows with \p dirichletNodes != 0 and if \p apply is true, adds
     /// a one on the diagonal of the matrix.
     auto applyDirichletBC(std::vector<char> const& dirichletNodes)
     {
-      std::list<Triplet<value_type>> columns;
-
       // Define the property maps
-      auto row   = mtl::mat::row_map(*matrix);
-      auto col   = mtl::mat::col_map(*matrix);
-      auto value = mtl::mat::value_map(*matrix);
+      auto row   = mtl::mat::row_map(matrix_);
+      auto col   = mtl::mat::col_map(matrix_);
+      auto value = mtl::mat::value_map(matrix_);
 
       // iterate over the matrix
-#if 0
-      for (auto r : mtl::major_of(*matrix)) {   // rows or columns
-        for (auto i : mtl::nz_of(r)) {          // non-zeros within
-          if (dirichletNodes[row(i)]) {
-            // set identity row
-            value(i, (row(i) == col(i) ? value_type(1) : value_type(0)) );
-          }
-          else if (dirichletNodes[col(i)]) {
-            columns.push_back({row(i), col(i), value(i)});
-            value(i, value_type(0));
-          }
-        }
-      }
-#endif
-
-      for (auto r : mtl::rows_of(*matrix)) {   // rows or columns
+      for (auto r : mtl::rows_of(matrix_)) {   // rows of the matrix
         if (dirichletNodes[r.value()]) {
           for (auto i : mtl::nz_of(r)) {          // non-zeros within
             // set identity row
@@ -207,107 +114,36 @@ namespace AMDiS
         }
       }
 
-      return columns;
-    }
-
-#if 0
-    void applyPeriodicBC(std::vector<char> const& periodicNodes,
-                         std::map<size_t, size_t> const& association, bool applyRow, bool applyCol)
-    {
-      bool apply = applyRow && applyCol;
-
-      // Define the property maps
-      auto row   = mtl::mat::row_map(*matrix);
-      auto col   = mtl::mat::col_map(*matrix);
-      auto value = mtl::mat::value_map(*matrix);
-
-      std::vector<std::map<size_t, std::list<value_type>>> row_values(num_cols(*matrix));
-      std::vector<std::map<size_t, std::list<value_type>>> col_values(num_rows(*matrix));
-      std::vector<char> dualNodes(periodicNodes.size(), 0);
-
-      // iterate over the matrix to collect the values and erase the source-row/col
-      for (auto r : mtl::major_of(*matrix)) {   // rows or columns
-        for (auto i : mtl::nz_of(r)) {          // non-zeros within
-          if (applyRow && periodicNodes[row(i)]) {
-            row_values[col(i)][association[row(i)]].push_back(value(i));
-            value(i, value_type(0));
-            dualNodes[association[row(i)]] = 1;
-          } else if (applyCol && periodicNodes[col(i)]) {
-            col_values[row(i)][association[col(i)]].push_back(value(i));
-            value(i, value_type(0));
-          }
-        }
-      }
-
-      // TODO: use inserter for assignment of values!!!
-      // iterate over the matrix to assign the values
-      for (auto r : mtl::major_of(*matrix)) {   // rows or columns
-        for (auto i : mtl::nz_of(r)) {          // non-zeros within
-          if (applyRow && dualNodes[row(i)]) {
-            value(i, std::accumulate(row_values[col(i)][row(i)].begin(),
-                                     row_values[col(i)][row(i)].end(),
-                                     value(i)) );
-          }
-          if (applyCol && dualNodes[col(i)]) {
-            value(i, std::accumulate(col_values[row(i)][col(i)].begin(),
-                                     col_values[row(i)][col(i)].end(),
-                                     value(i)) );
-          }
-        }
-      }
-
-      // assign values 1, -1 to diagonal and associated entries
-      if (apply) {
-        Inserter ins(*matrix);
-        for (auto const& a : association) {
-          ins[a.first][a.first]   << value_type( 1);
-          ins[a.second][a.second] << value_type( 1);
-          ins[a.first][a.second]  << value_type(-1);
-          ins[a.second][a.first]  << value_type(-1);
-        }
-      }
+      return std::list<Triplet<value_type>>{};
     }
-#endif
 
   protected:
     // Estimates the slot-size used in the inserter to reserve enough space per row.
     void calculateSlotSize()
     {
-      slot_size = 0;
+      slotSize_ = 0;
 
-      if (num_rows(*matrix) != 0)
-        slot_size = int(double(matrix->nnz()) / num_rows(*matrix) * 1.2);
-      if (slot_size < MIN_NNZ_PER_ROW)
-        slot_size = MIN_NNZ_PER_ROW;
+      if (num_rows(matrix_) != 0)
+        slotSize_ = int(double(matrix_.nnz()) / num_rows(matrix_) * 1.2);
+      if (slotSize_ < MIN_NNZ_PER_ROW)
+        slotSize_ = MIN_NNZ_PER_ROW;
     }
 
   private:
     /// The minimal number of nonzeros per row
     static constexpr int MIN_NNZ_PER_ROW = 50;
 
-    /// The finite element space / basis of the row
-    RowFeSpace const& rowFeSpace;
-
-    /// The finite element space / basis of the column
-    ColFeSpace const& colFeSpace;
-
-    /// The name of the DOFMatrix
-    std::string name;
-
     /// The data-matrix (can hold a new BaseMatrix or a pointer to external data
-    ClonablePtr<BaseMatrix> matrix;
+    BaseMatrix matrix_;
 
     /// A pointer to the inserter. Created in \ref init and destroyed in \ref finish
-    Inserter* inserter = NULL;
-
-    /// A flag that indicates whether the matrix is in insertion mode
-    bool insertionMode = false;
+    Inserter* inserter_ = nullptr;
 
     /// The size of the slots used to insert values per row
-    int slot_size = MIN_NNZ_PER_ROW;
-
-    // friend class declarations
-    template <class, class> friend class SystemMatrix;
+    int slotSize_ = MIN_NNZ_PER_ROW;
   };
 
+  template <class RowBasisType, class ColBasisType, class ValueType = double>
+  using DOFMatrix = DOFMatrixBase<RowBasisType, ColBasisType, MtlMatrix<ValueType>>;
+
 } // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/mtl/DOFVector.hpp b/src/amdis/linear_algebra/mtl/DOFVector.hpp
index 6cfb293aac137b7c371a73642be289c0f64e54cb..01842741a5ffae416f7fe4866204bab847b3072a 100644
--- a/src/amdis/linear_algebra/mtl/DOFVector.hpp
+++ b/src/amdis/linear_algebra/mtl/DOFVector.hpp
@@ -1,179 +1,87 @@
 #pragma once
 
-#include <algorithm>
-#include <memory>
-#include <string>
-
-#include <dune/common/reservedvector.hh>
-#include <dune/functions/functionspacebases/flatmultiindex.hh>
-#include <dune/functions/functionspacebases/interpolate.hh>
+#include <boost/numeric/mtl/vector/dense_vector.hpp>
 
 #include <amdis/Output.hpp>
-#include <amdis/common/ClonablePtr.hpp>
-#include <amdis/common/ScalarTypes.hpp>
-#include <amdis/linear_algebra/mtl/MTLDenseVector.hpp>
-#include <amdis/utility/MultiIndex.hpp>
+#include <amdis/linear_algebra/DOFVectorBase.hpp>
 
 namespace AMDiS
 {
-  /// The basic container that stores a base vector and a corresponding feSpace
-  template <class Traits, class ValueType = double>
-  class DOFVector
+  /// The basic container that stores a base vector and a corresponding basis
+  template <class ValueType>
+  class MtlVector
   {
-    using Self = DOFVector;
-
   public:
-    /// The type of the \ref feSpace
-    using GlobalBasis = typename Traits::GlobalBasis;
-
     /// The type of the base vector
-    using BaseVector = MTLDenseVector<ValueType>;
+    using BaseVector = mtl::vec::dense_vector<ValueType>;
 
     /// The index/size - type
-    using size_type  = typename GlobalBasis::size_type;
+    using size_type  = typename BaseVector::size_type;
 
     /// The type of the elements of the DOFVector
     using value_type = ValueType;
 
-    /// The underlying field-type (typically the same as \ref value_type)
-    using field_type = typename BaseVector::value_type;
-
+  public:
     /// Constructor. Constructs new BaseVector.
-    DOFVector(GlobalBasis const& feSpace, std::string name)
-      : feSpace(feSpace)
-      , name(name)
-      , vector(ClonablePtr<BaseVector>::make())
-    {
-      compress();
-    }
-
-    /// Constructor. Takes reference to existing BaseVector
-    DOFVector(GlobalBasis const& feSpace, std::string name,
-              BaseVector& vector_ref)
-      : feSpace(feSpace)
-      , name(name)
-      , vector(vector_ref)
-    {}
-
-    /// Return the basis \ref feSpace of the vector
-    GlobalBasis const& getFeSpace() const
-    {
-        return feSpace;
-    }
-
-    /// Return the data-vector \ref vector
-    BaseVector const& getVector() const
-    {
-      return *vector;
-    }
-
-    /// Return the data-vector \ref vector
-    BaseVector& getVector()
-    {
-      return *vector;
-    }
+    MtlVector() = default;
 
-    /// Return the size of the \ref feSpace
-    size_type getSize() const
+    /// Return the data-vector \ref vector_
+    BaseVector const& vector() const
     {
-      return feSpace.dimension();
+      return vector_;
     }
 
-    /// Return the \ref name of this vector
-    std::string getName() const
+    /// Return the data-vector \ref vector_
+    BaseVector& vector()
     {
-      return name;
+      return vector_;
     }
 
-    /// Resize the \ref vector to the size of the \ref feSpace.
-    void compress()
+    /// Return the current size of the \ref vector_
+    size_type size() const
     {
-      if (num_rows(*vector) != getSize()) {
-        resize(getSize());
-        *vector = ValueType(0);
-      }
+      return mtl::vec::size(vector_);
     }
 
-    template <class SizeInfo>
-    void resize(SizeInfo s)
+    /// Resize the \ref vector_ to the size \p s
+    void resize(size_type s)
     {
-      vector->change_dim(size_type(s));
+      vector_.change_dim(s);
     }
 
 
     /// Access the entry \p i of the \ref vector with read-access.
-    template <class Index>
-    value_type const& operator[](Index idx) const
+    value_type const& operator[](size_type i) const
     {
-      auto const i = flatMultiIndex(idx);
-      test_exit_dbg( i < num_rows(*vector) ,
-        "Index ", i, " out of range [0,", num_rows(*vector), ")" );
-      return (*vector)[i];
+      test_exit_dbg(i < mtl::vec::size(vector_),
+        "Index ", i, " out of range [0,", mtl::vec::size(vector_), ")" );
+      return vector_[i];
     }
 
     /// Access the entry \p i of the \ref vector with write-access.
-    template <class Index>
-    value_type& operator[](Index idx)
+    value_type& operator[](size_type i)
     {
-      auto const i = flatMultiIndex(idx);
-      test_exit_dbg( i < num_rows(*vector) ,
-        "Index ", i, " out of range [0,", num_rows(*vector), ")" );
-      return (*vector)[i];
-    }
-
-    /// \brief interpolate a function \p f to the basis \ref feSpace and store the
-    /// coefficients in \ref vector.
-    template <class F>
-    void interpol(F&& f)
-    {
-      Dune::Functions::interpolate(feSpace, *this, std::forward<F>(f));
-    }
-
-    /// Scale each DOFVector by the factor \p s.
-    template <class Scalar>
-    std::enable_if_t< Concepts::Arithmetic<Scalar>, Self&>
-    operator*=(Scalar s)
-    {
-      (*vector) *= s;
-      return *this;
-    }
-
-    /// Sets each DOFVector to the scalar \p s.
-    template <class Scalar>
-    std::enable_if_t< Concepts::Arithmetic<Scalar>, Self&>
-    operator=(Scalar s)
-    {
-      (*vector) = s;
-      return *this;
-    }
-
-    /// Calls the copy assignment operator of the BaseVector \ref vector
-    void copy(Self const& that)
-    {
-      *vector = that.getVector();
+      test_exit_dbg(i < mtl::vec::size(vector_),
+        "Index ", i, " out of range [0,", mtl::vec::size(vector_), ")" );
+      return vector_[i];
     }
 
   private:
-    /// The finite element space / basis associated with the data vector
-    GlobalBasis const& feSpace;
-
-    /// The name of the DOFVector (used in file-writing)
-    std::string	name;
-
     /// The data-vector (can hold a new BaseVector or a pointer to external data
-    ClonablePtr<BaseVector> vector;
-
-    // friend class declarations
-    template <class, class> friend class SystemVector;
+    BaseVector vector_;
   };
 
 
-  /// Constructor a dofvector from given feSpace and name
-  template <class Traits, class ValueType = double>
-  DOFVector<Traits, ValueType>
-  makeDOFVector(typename Traits::GlobalBasis const& basis, std::string name)
+  template <class BasisType, class VectorType = double>
+  using DOFVector = DOFVectorBase<BasisType, MtlVector<VectorType>>;
+
+
+  /// Constructor a dofvector from given basis and name
+  template <class ValueType = double, class Basis>
+  DOFVector<Basis, ValueType>
+  makeDOFVector(Basis const& basis)
   {
-    return {basis, name};
+    return {basis};
   }
 
 } // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/mtl/ITL_Preconditioner.hpp b/src/amdis/linear_algebra/mtl/ITL_Preconditioner.hpp
index 2e8ac6ef19f5ed4dbd640d5628e66fb90fdcb9d7..42e25d04fb451bbd41363d9d318ed7b2aed2b4c9 100644
--- a/src/amdis/linear_algebra/mtl/ITL_Preconditioner.hpp
+++ b/src/amdis/linear_algebra/mtl/ITL_Preconditioner.hpp
@@ -1,5 +1,3 @@
-/** \file ITL_Preconditioner.h */
-
 #pragma once
 
 // MTL4 headers
diff --git a/src/amdis/linear_algebra/mtl/ITL_Solver.hpp b/src/amdis/linear_algebra/mtl/ITL_Solver.hpp
index c60b372cd5f30d18eb71b83b38cb37adc187c174..258e37500039cb67f5c59f617abb1f111c465aef 100644
--- a/src/amdis/linear_algebra/mtl/ITL_Solver.hpp
+++ b/src/amdis/linear_algebra/mtl/ITL_Solver.hpp
@@ -1,21 +1,9 @@
-/** \file ITL_Solver.h */
-
 #pragma once
 
 #include <string>
 
 // MTL4 includes
 #include <boost/numeric/itl/itl.hpp>
-// #include <boost/numeric/itl/krylov/bicg.hpp>
-// #include <boost/numeric/itl/krylov/bicgstab_2.hpp>
-// #include <boost/numeric/itl/krylov/bicgstab_ell.hpp>
-// #include <boost/numeric/itl/krylov/bicgstab.hpp>
-// #include <boost/numeric/itl/krylov/cg.hpp>
-// #include <boost/numeric/itl/krylov/cgs.hpp>
-// #include <boost/numeric/itl/krylov/gmres.hpp>
-// #include <boost/numeric/itl/krylov/idr_s.hpp>
-// #include <boost/numeric/itl/krylov/qmr.hpp>
-// #include <boost/numeric/itl/krylov/tfqmr.hpp>
 
 // more solvers defined in AMDiS
 #include <amdis/linear_algebra/mtl/itl/minres.hpp>
@@ -28,7 +16,7 @@
 
 #include <amdis/CreatorMap.hpp>
 #include <amdis/Initfile.hpp>
-#include <amdis/linear_algebra/mtl/LinearSolver.hpp>
+#include <amdis/linear_algebra/LinearSolver.hpp>
 #include <amdis/linear_algebra/mtl/KrylovRunner.hpp>
 #include <amdis/linear_algebra/mtl/UmfpackRunner.hpp>
 
@@ -405,13 +393,13 @@ namespace AMDiS
 
     template <class ITLSolver>
     using SolverCreator
-      = typename LinearSolver<Matrix, Vector,
-          KrylovRunner<ITLSolver, Matrix, BaseVector_t<Vector>>>::Creator;
+      = typename LinearSolver<Matrix, Vector, Vector,
+          KrylovRunner<ITLSolver, Matrix, Vector>>::Creator;
 
 #ifdef HAVE_UMFPACK
     using UmfpackSolverCreator
-      = typename LinearSolver<Matrix, Vector,
-          UmfpackRunner<Matrix, BaseVector_t<Vector>>>::Creator;
+      = typename LinearSolver<Matrix, Vector, Vector,
+          UmfpackRunner<Matrix, Vector>>::Creator;
 #endif
 
     using Map = CreatorMap<SolverBase>;
diff --git a/src/amdis/linear_algebra/mtl/KrylovRunner.hpp b/src/amdis/linear_algebra/mtl/KrylovRunner.hpp
index 45b9ea2a1475e777a9cf7a671b098cf4e34443ad..2927909c207baba7066ab66cba64476561ef54c2 100644
--- a/src/amdis/linear_algebra/mtl/KrylovRunner.hpp
+++ b/src/amdis/linear_algebra/mtl/KrylovRunner.hpp
@@ -1,5 +1,3 @@
-/** \file ITL_Runner.h */
-
 #pragma once
 
 #include <string>
@@ -14,7 +12,6 @@
 #include <amdis/linear_algebra/SolverInfo.hpp>
 
 #include <amdis/linear_algebra/mtl/ITL_Preconditioner.hpp>
-#include <amdis/linear_algebra/mtl/BITL_Preconditioner.hpp>
 
 namespace AMDiS
 {
@@ -22,10 +19,11 @@ namespace AMDiS
    *
    * \brief
    * Wrapper class for different MTL4 itl-solvers. These solvers
-   * are parametrized by Matrix- and Vector.
+   * are parametrized by Matrix and Vector.
    **/
   template <class ITLSolver, class Matrix, class Vector>
-  class KrylovRunner : public RunnerInterface<Matrix, Vector>
+  class KrylovRunner
+      : public RunnerInterface<Matrix, Vector>
   {
     using Super = RunnerInterface<Matrix, Vector>;
     using PreconBase = typename Super::PreconBase;
@@ -33,71 +31,71 @@ namespace AMDiS
   public:
     /// Constructor.
     explicit KrylovRunner(std::string prefix)
-      : itlSolver(prefix)
+      : itlSolver_(prefix)
     {
       initPrecon(prefix);
 
-      Parameters::get(prefix + "->max iteration", maxIter);
-      Parameters::get(prefix + "->print cycle", printCycle);
+      Parameters::get(prefix + "->max iteration", maxIter_);
+      Parameters::get(prefix + "->print cycle", printCycle_);
     }
 
-    /// Implements \ref RunnerInterface::getLeftPrecon(), Returns \ref L
-    virtual std::shared_ptr<PreconBase> getLeftPrecon() override
+    /// Implements \ref RunnerInterface::lLeftPrecon(), Returns \ref L_
+    virtual std::shared_ptr<PreconBase> leftPrecon() override
     {
-      return L;
+      return L_;
     }
 
-    /// Implements \ref RunnerInterface::getRightPrecon(), Returns \ref R
-    virtual std::shared_ptr<PreconBase> getRightPrecon() override
+    /// Implements \ref RunnerInterface::rightPrecon(), Returns \ref R_
+    virtual std::shared_ptr<PreconBase> rightPrecon() override
     {
-      return R;
+      return R_;
     }
 
-    /// Set a new left preconditioner \ref L
+    /// Set a new left preconditioner \ref L_
     void setLeftPrecon(std::shared_ptr<PreconBase> const& precon)
     {
-      L = precon;
+      L_ = precon;
     }
 
-    /// Set a new right preconditioner \ref R
+    /// Set a new right preconditioner \ref R_
     void setRightPrecon(std::shared_ptr<PreconBase> const& precon)
     {
-      R = precon;
+      R_ = precon;
     }
 
     /// Implementation of \ref RunnerInterface::init()
     virtual void init(Matrix const& A) override
     {
-      L->init(A);
-      R->init(A);
+      L_->init(A);
+      R_->init(A);
     }
 
     /// Implementation of \ref RunnerInterface::exit()
     virtual void exit() override
     {
-      L->exit();
-      R->exit();
+      L_->exit();
+      R_->exit();
     }
 
     /// Implementation of \ref RunnerInterface::solve()
     virtual int solve(Matrix const& A, Vector& x, Vector const& b,
                       SolverInfo& solverInfo) override
     {
-      test_exit(bool(L), "There is no left preconditioner");
-      test_exit(bool(R), "There is no right preconditioner");
+      test_exit(bool(L_), "There is no left preconditioner");
+      test_exit(bool(R_), "There is no right preconditioner");
 
       auto r = Vector(b);
       if (two_norm(x) != 0)
         r -= A * x;
 
       // print information about the solution process
-      itl::cyclic_iteration<double> iter(r, maxIter, solverInfo.getRelTolerance(),
-                                                     solverInfo.getAbsTolerance(),
-                                                     printCycle);
+      itl::cyclic_iteration<double> iter(r, maxIter_, solverInfo.getRelTolerance(),
+                                                      solverInfo.getAbsTolerance(),
+                                                      printCycle_);
       iter.set_quite(solverInfo.getInfo() == 0);
       iter.suppress_resume(solverInfo.getInfo() == 0);
 
-      int error = itlSolver(A, x, b, *L, *R, iter);
+      int error = itlSolver_(A, x, b, *L_, *R_, iter);
       solverInfo.setAbsResidual(iter.resid());
       solverInfo.setRelResidual(iter.relresid());
 
@@ -109,32 +107,31 @@ namespace AMDiS
     void initPrecon(std::string prefix)
     {
       // Creator for the left preconditioner
-      std::string leftPrecon = "", rightPrecon = "";
-      Parameters::get(prefix + "->left precon", leftPrecon);
-      Parameters::get(prefix + "->right precon", rightPrecon);
+      std::string leftPreconName = "", rightPreconName = "";
+      Parameters::get(prefix + "->left precon", leftPreconName);
+      Parameters::get(prefix + "->right precon", rightPreconName);
 
       auto leftCreator
-        = CreatorMap<PreconBase>::getCreator(leftPrecon, prefix + "->left precon");
+        = CreatorMap<PreconBase>::getCreator(leftPreconName, prefix + "->left precon");
       auto rightCreator
-        = CreatorMap<PreconBase>::getCreator(rightPrecon, prefix + "->right precon");
+        = CreatorMap<PreconBase>::getCreator(rightPreconName, prefix + "->right precon");
 
-      L = leftCreator->create();
-      R = rightCreator->create();
+      L_ = leftCreator->create();
+      R_ = rightCreator->create();
     }
 
   private:
     /// The itl solver object that performes the actual solve
-    ITLSolver itlSolver;
+    ITLSolver itlSolver_;
 
     /// Pointer to the left and right preconditioner
-    std::shared_ptr<PreconBase> L, R;
+    std::shared_ptr<PreconBase> L_, R_;
 
     /// The maximal number of iterations
-    std::size_t maxIter = 1000;
+    std::size_t maxIter_ = 1000;
 
     /// Print solver residuals every \ref printCycle 's iteration
-    std::size_t printCycle = 100;
-
+    std::size_t printCycle_ = 100;
   };
 
 } // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/mtl/MTLDenseVector.hpp b/src/amdis/linear_algebra/mtl/MTLDenseVector.hpp
deleted file mode 100644
index 4e08e4698dca62edaafda5c74647266decfc4911..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/mtl/MTLDenseVector.hpp
+++ /dev/null
@@ -1,50 +0,0 @@
-#pragma once
-
-
-#include <boost/numeric/mtl/vector/dense_vector.hpp>
-
-#include <amdis/linear_algebra/LinearAlgebraBase.hpp>
-
-namespace AMDiS
-{
-  template <class Value>
-  using MTLDenseVector = mtl::vec::dense_vector<Value>;
-
-  namespace Impl
-  {
-    template <class Vector>
-    class MTLWrapper
-      : public BaseWrapper<Vector>
-    {
-      using Super = BaseWrapper<Vector>;
-
-    public:
-      using value_type = typename Super::value_type;
-      using size_type = typename Super::size_type;
-
-      template <class Vector_>
-      MTLWrapper(Vector_&& vec)
-        : Super(std::forward<Vector_>(vec))
-      {}
-
-      void resize(size_type s)
-      {
-        this->vec.change_dim(s);
-      }
-
-      size_type size() const
-      {
-        return num_rows(this->vec);
-      }
-    };
-
-  } // end namespace Impl
-
-  /// wrap the mtl dense_vector class to provide resize and size member-functions
-  template <class Value>
-  Impl::MTLWrapper<MTLDenseVector<Value>> wrapper(MTLDenseVector<Value>& vec)
-  {
-    return {vec};
-  }
-
-} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/mtl/Mapper.hpp b/src/amdis/linear_algebra/mtl/Mapper.hpp
deleted file mode 100644
index 6249f0949554a1e13a49edcac61b74855e868df0..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/mtl/Mapper.hpp
+++ /dev/null
@@ -1,241 +0,0 @@
-#pragma once
-
-#include <vector>
-
-#include <boost/numeric/mtl/matrix/mapped_inserter.hpp>
-
-#include <amdis/linear_algebra/mtl/BlockMTLMatrix.hpp>
-#include <amdis/linear_algebra/mtl/SystemMatrix.hpp>
-
-namespace AMDiS
-{
-
-  /**
-   * \brief BaseClass for all mapper types
-   *
-   * A mapper assigned a local row/column index of a cell of
-   * a block matrix to a global matrix index.
-   * Call \ref setRow and \ref setCol first, to select a block
-   * in the block matrix. Then get with \ref row, respective \ref col,
-   * the global matrix index to the assigned local index.
-   **/
-  template <class Derived>
-  struct MapperBase
-  {
-    using size_type = std::size_t;
-
-    template <class BaseInserter>
-    struct Inserter {
-      using type = mtl::mat::mapped_inserter<BaseInserter, Derived>;
-    };
-
-    /// set the current block row
-    void setRow(size_type rb) { self().setRow(rb); }
-
-    /// set the current block columns
-    void setCol(size_type cb) { self().setCol(cb); }
-
-    /// return global matrix row, for local row in the current matrix block
-    size_type row(size_type r) const { return self().row(r); }
-
-    /// return global matrix column, for local column in the current matrix block
-    size_type col(size_type c) const { return self().col(c); }
-
-    /// return overall number of rows
-    size_type getNumRows() const { return self().getNumRows(); }
-
-    /// return overall number of columns
-    size_type getNumCols() const { return self().getNumCols(); }
-
-    size_type getNumRows(size_type comp) const { return self().getNumRows(comp); }
-    size_type getNumCols(size_type comp) const { return self().getNumCols(comp); }
-
-    /// return number of components/blocks
-    size_type getNumComponents() const { return self().getNumComponents(); }
-
-    size_type row(size_type rb, size_type cb, size_type r)
-    {
-      setRow(rb);
-      setCol(cb);
-      return row(r);
-    }
-
-    size_type col(size_type rb, size_type cb, size_type c)
-    {
-      setRow(rb);
-      setCol(cb);
-      return col(c);
-    }
-
-    Derived&       self()       { return static_cast<Derived&>(*this); }
-    Derived const& self() const { return static_cast<Derived const&>(*this); }
-  };
-
-
-  /// Mapper implementation for non-parallel block matrices
-  struct BlockMapper : public MapperBase<BlockMapper>
-  {
-    /// Default constructor
-    BlockMapper() = default;
-    BlockMapper(BlockMapper const& other) = default;
-    BlockMapper& operator=(BlockMapper const& other) = default;
-
-    /// Constructor for BlockMTLMatrix
-    template <class Value, std::size_t _N>
-    explicit BlockMapper(BlockMTLMatrix<Value, _N, _N> const& mat)
-      : nComp(_N)
-      , rowOffset(0), colOffset(0)
-      , nrow(num_rows(mat)), ncol(nrow)
-      , sizes(nComp)
-    {
-      for (std::size_t i = 0; i < _N; ++i)
-        sizes[i] = num_rows(mat[i][i]);
-    }
-
-    /// Constructor for SystemMatrix
-    template <class FeSpaces, class Value>
-    explicit BlockMapper(SystemMatrix<FeSpaces, Value> const& mat)
-      : BlockMapper(mat.getMatrix())
-    {}
-
-    /// Constructor for single DOFMatrix
-    template <class FeSpace, class Value>
-    explicit BlockMapper(DOFMatrix<FeSpace, Value> const& mat)
-      : nComp(1)
-      , rowOffset(0), colOffset(0)
-      , nrow(0), ncol(0)
-      , sizes(nComp)
-    {
-      sizes[0] = mat.N();
-      nrow += sizes[0];
-      ncol = nrow;
-    }
-
-    /// Constructor for system with equal components
-    BlockMapper(size_type nComp, size_type nDOFperComp)
-    : nComp(nComp),
-      rowOffset(0), colOffset(0),
-      nrow(nComp*nDOFperComp), ncol(nrow),
-      sizes(nComp)
-    {
-       for (size_type i = 0; i < nComp; ++i)
-         sizes[i] = nDOFperComp;
-    }
-
-    /// calculate row offset for row component \param r
-    void setRow(size_type rb)
-    {
-      test_exit_dbg(rb <= sizes.size(), "row nr out of range!");
-      rowOffset = sum(rb);
-    }
-
-    /// calculate column offset for col component \param c
-    void setCol(size_type cb)
-    {
-      test_exit_dbg(cb <= sizes.size(), "column nr out of range!");
-      colOffset = sum(cb);
-    }
-
-    size_type row(size_type r) const { return r + rowOffset; }
-    size_type col(size_type c) const { return c + colOffset; }
-
-    size_type getNumRows() const { return nrow; }
-    size_type getNumCols() const { return ncol; }
-
-    size_type getNumRows(size_type comp) const { return sizes[comp]; }
-    size_type getNumCols(size_type comp) const { return sizes[comp]; }
-
-    size_type getNumComponents() const { return nComp; }
-
-  private: // methods
-
-    ///compute the sum of sizes from [0, end)
-    size_type sum(size_type end) const
-    {
-      size_type ret = 0;
-      for (size_type i = 0; i < end; ++i)
-	ret += sizes[i];
-      return ret;
-    }
-
-  private: // variables
-
-    size_type nComp = 0;
-    size_type rowOffset = 0;
-    size_type colOffset = 0;
-    size_type nrow = 0;
-    size_type ncol = 0;
-
-    std::vector<size_type> sizes;
-  };
-
-
-  /// Mapper implementation for non-parallel rectangular block matrices
-  struct RectangularMapper : public MapperBase<RectangularMapper>
-  {
-    /// Constructor for block-matrices
-    template <class Value, std::size_t _N, std::size_t _M>
-    explicit RectangularMapper(BlockMTLMatrix<Value, _N, _M> const& mat)
-      : nRowComp(_N), nColComp(_M)
-      , rowOffset(0), colOffset(0)
-      , nrow(num_rows(mat)), ncol(num_cols(mat))
-      , sizes_rows(nRowComp), sizes_cols(nColComp)
-    {
-      for (size_type i = 0; i < _N; ++i)
-        sizes_rows[i] = num_rows(mat[i][0]);
-      for (size_type j = 0; j < _M; ++j)
-        sizes_cols[j] = num_cols(mat[0][j]);
-    }
-
-    /// calculate row offset for row component \param r
-    void setRow(size_type rb)
-    {
-      test_exit_dbg(rb <= sizes_rows.size(), "row nr out of range!");
-      rowOffset = sum(rb, sizes_rows);
-    }
-
-    /// calculate column offset for col component \param c
-    void setCol(size_type cb)
-    {
-      test_exit_dbg(cb <= sizes_cols.size(), "column nr out of range!");
-      colOffset = sum(cb, sizes_cols);
-    }
-
-    size_type row(size_type r) const { return r + rowOffset; }
-    size_type col(size_type c) const { return c + colOffset; }
-
-    size_type getNumRows() const { return nrow; }
-    size_type getNumCols() const { return ncol; }
-
-    size_type getNumRows(size_type comp) const { return sizes_rows[comp]; }
-    size_type getNumCols(size_type comp) const { return sizes_cols[comp]; }
-
-    size_type getNumComponents() const { return nRowComp; }
-    size_type getNumRowComponents() const { return nRowComp; }
-    size_type getNumColComponents() const { return nColComp; }
-
-  private: // methods
-
-    ///compute the sum of sizes from [0, end)
-    size_type sum(size_type end, std::vector<size_type> const& sizes) const
-    {
-      size_type ret = 0;
-      for (size_type i = 0; i < end; ++i)
-	ret += sizes[i];
-      return ret;
-    }
-
-  private: // variables
-
-    size_type nRowComp = 0;
-    size_type nColComp = 0;
-    size_type rowOffset = 0;
-    size_type colOffset = 0;
-    size_type nrow = 0;
-    size_type ncol = 0;
-
-    std::vector<size_type> sizes_rows;
-    std::vector<size_type> sizes_cols;
-  };
-
-} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/mtl/Preconditioner.hpp b/src/amdis/linear_algebra/mtl/Preconditioner.hpp
index 822d1221841e73676e74b282f74571fa1460fc3b..cc610a82cacf5a498ca9c67bcf55de638e4296bc 100644
--- a/src/amdis/linear_algebra/mtl/Preconditioner.hpp
+++ b/src/amdis/linear_algebra/mtl/Preconditioner.hpp
@@ -1,5 +1,3 @@
-/** \file ITL_Preconditioner.h */
-
 #pragma once
 
 #include <amdis/linear_algebra/PreconditionerInterface.hpp>
@@ -12,7 +10,8 @@ namespace AMDiS
    * \brief Wrapper for using ITL preconditioners in AMDiS.
    */
   template <class Matrix, class Vector, class PreconRunner>
-  class Preconditioner : public PreconditionerInterface<Matrix, Vector>
+  class Preconditioner
+      : public PreconditionerInterface<Matrix, Vector>
   {
     using Self = Preconditioner;
     using Super = PreconditionerInterface<Matrix, Vector>;
@@ -31,31 +30,31 @@ namespace AMDiS
     /// Implementation of \ref PreconditionerBase::init()
     virtual void init(Matrix const& fullMatrix) override
     {
-      precon.reset(new PreconRunner(fullMatrix));
+      precon_.reset(new PreconRunner(fullMatrix));
     }
 
     /// Implementation of \ref PreconditionerInterface::exit()
     virtual void exit() override
     {
-      precon.reset();
+      precon_.reset();
     }
 
     /// Implementation of \ref PreconditionerBase::solve()
     virtual void solve(Vector const& vin, Vector& vout) const override
     {
-      test_exit_dbg(bool(precon), "No preconditioner initialized!");
-      precon->solve(vin, vout);
+      test_exit_dbg(bool(precon_), "No preconditioner initialized!");
+      precon_->solve(vin, vout);
     }
 
     /// Implementation of \ref PreconditionerBase::adjoint_solve()
     virtual void adjoint_solve(Vector const& vin, Vector& vout) const override
     {
-      test_exit_dbg(bool(precon), "No preconditioner initialized!");
-      precon->adjoint_solve(vin, vout);
+      test_exit_dbg(bool(precon_), "No preconditioner initialized!");
+      precon_->adjoint_solve(vin, vout);
     }
 
   private:
-    std::shared_ptr<PreconRunner> precon;
+    std::shared_ptr<PreconRunner> precon_;
   };
 
 } // namespace AMDiS
diff --git a/src/amdis/linear_algebra/mtl/SystemMatrix.cpp b/src/amdis/linear_algebra/mtl/SystemMatrix.cpp
deleted file mode 100644
index 6182e50796fac5ccbea79435d9e3c444df2f91f3..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/mtl/SystemMatrix.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-#define AMDIS_NO_EXTERN_SYSTEMMATRIX
-#include <amdis/linear_algebra/mtl/SystemMatrix.hpp>
-#undef AMDIS_NO_EXTERN_SYSTEMMATRIX
-
-
-namespace AMDiS
-{
-  // explicit template instatiation
-  // template class SystemMatrix<typename TestTraits<2,1,2>::FeSpaces>;
-} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/mtl/SystemMatrix.hpp b/src/amdis/linear_algebra/mtl/SystemMatrix.hpp
deleted file mode 100644
index a674fd16a44fc8afa275cfd2a00faa4ebaeea3de..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/mtl/SystemMatrix.hpp
+++ /dev/null
@@ -1,207 +0,0 @@
-#pragma once
-
-#include <vector>
-#include <string>
-#include <memory>
-#include <tuple>
-
-#include <boost/numeric/mtl/matrix/dense2D.hpp>
-#include <boost/numeric/mtl/matrix/compressed2D.hpp>
-
-#include <amdis/Output.hpp>
-#include <amdis/common/TupleUtility.hpp>
-#include <amdis/common/Utility.hpp>
-#include <amdis/linear_algebra/mtl/BlockMTLMatrix.hpp>
-#include <amdis/linear_algebra/mtl/DOFMatrix.hpp>
-
-// for explicit instantiation
-#include <amdis/ProblemStatTraits.hpp>
-
-namespace AMDiS
-{
-  /// \cond HIDDEN_SYMBOLS
-  namespace Impl
-  {
-    // DOFMatrices = std::tuple< std::tuple< DOFMatrix<RowFeSpace, ColFeSpace, ValueType>... >... >
-    template <class DOFMatrices>
-    struct BuildDOFMatrices
-    {
-      template <std::size_t R>
-      using DOFMatrixRow = std::tuple_element_t<R, DOFMatrices>;
-
-      template <std::size_t R, std::size_t C>
-      using DOFMatrixRowCol = std::tuple_element_t<C, DOFMatrixRow<R>>;
-
-      // add arg to repeated constructor argument list
-      template <std::size_t... R, class RowFeSpaces, class ColFeSpaces, class MultiMatrix>
-      static DOFMatrices make(Indices<R...>,
-                              RowFeSpaces&& rowFeSpaces,
-                              ColFeSpaces&& colFeSpace,
-                              MultiMatrix&& multiMatrix)
-      {
-        return DOFMatrices{make_row(
-          index_<R>,
-          MakeSeq_t<std::tuple_size<std::decay_t<ColFeSpaces>>::value>(),
-          std::get<R>(std::forward<RowFeSpaces>(rowFeSpaces)),
-          std::forward<ColFeSpaces>(colFeSpace),
-          std::forward<MultiMatrix>(multiMatrix)
-          )...};
-      }
-
-      template <std::size_t R, std::size_t... C, class RowFeSpace, class ColFeSpaces, class MultiMatrix>
-      static DOFMatrixRow<R> make_row(index_t<R>,
-                                      Indices<C...>,
-                                      RowFeSpace&& rowFeSpace,
-                                      ColFeSpaces&& colFeSpace,
-                                      MultiMatrix&& multiMatrix)
-      {
-        return DOFMatrixRow<R>{DOFMatrixRowCol<R,C>(
-          std::forward<RowFeSpace>(rowFeSpace),
-          std::get<C>(std::forward<ColFeSpaces>(colFeSpace)),
-          "matrix[" + std::to_string(R) + "][" + std::to_string(C) + "]",
-          multiMatrix(index_<R>, index_<C>)
-          )...};
-      }
-    };
-
-    // construction method to construct a tuple of tuples of DOFMatrices
-    template <class DOFMatrices, class RowFeSpaces, class ColFeSpaces, class MultiMatrix>
-    DOFMatrices buildDOFMatrices(RowFeSpaces&& rowFeSpaces,
-                                  ColFeSpaces&& colFeSpace,
-                                  MultiMatrix&& multiMatrix)
-    {
-        return BuildDOFMatrices<DOFMatrices>::make(
-            MakeSeq_t<std::tuple_size<std::decay_t<RowFeSpaces>>::value>(), // traverse rows first
-            std::forward<RowFeSpaces>(rowFeSpaces),
-            std::forward<ColFeSpaces>(colFeSpace),
-            std::forward<MultiMatrix>(multiMatrix));
-    }
-
-  } // end namespace Impl
-  /// \endcond
-
-
-  /// \brief Container that repesents multiple data-matrices.
-  /**
-    *  Represents a fixed-size matrix of \ref mtl::compressed2D + a tuple of corresponding
-    *  feSpaces. This (R,C)'th matrix combined with the (R,C)'th FeSpace
-    *  builds a \ref DOFMatrix and can be return by the \ref operator().
-    **/
-  template <class FeSpaces, class ValueType = double>
-  class SystemMatrix
-  {
-    template <class RowFeSpace>
-    struct MultiMatrixRowGenerator
-    {
-      template <class ColFeSpace>
-      using DOFMatrixGenerator = DOFMatrix<RowFeSpace, ColFeSpace, ValueType>;
-      using DOFMatrices  = MakeTuple_t<DOFMatrixGenerator, FeSpaces>;
-    };
-
-    template <class RowFeSpace>
-    using DOFMatrixGenerator = typename MultiMatrixRowGenerator<RowFeSpace>::DOFMatrices;
-
-  public:
-    /// The number of blocks per row/column
-    static constexpr std::size_t nComponent = std::tuple_size<FeSpaces>::value;
-    AMDIS_STATIC_ASSERT( nComponent > 0 );
-
-    /// The type of the matrix in each block
-    using BaseMatrix = mtl::compressed2D<ValueType>;
-
-    /// The type of the matrix of DOFMatrices
-    using DOFMatrices = MakeTuple_t<DOFMatrixGenerator, FeSpaces>;
-
-    /// The type of the matrix of base-matrices
-    using MultiMatrix = BlockMTLMatrix<BaseMatrix, nComponent, nComponent>;
-
-
-    /// Constructor that constructs new base-matrices
-    explicit SystemMatrix(FeSpaces const& feSpaces)
-      : feSpaces(feSpaces)
-      , matrix()
-      , dofmatrices(Impl::buildDOFMatrices<DOFMatrices>(feSpaces, feSpaces, matrix))
-    {}
-
-
-    /// Return the number of blocks per row
-    static constexpr std::size_t N()
-    {
-      return std::tuple_size<FeSpaces>::value;
-    }
-
-    /// Return the number of blocks per column
-    static constexpr std::size_t M()
-    {
-      return std::tuple_size<FeSpaces>::value;
-    }
-
-    /// Return the (R,C)'th underlaying base matrix
-    template <std::size_t R, std::size_t C>
-    auto& getMatrix(const index_t<R> _r = {}, const index_t<C> _c = {})
-    {
-      static_assert(R < N() && C < M(), "Indices out of range [0,N)x[0,M)");
-      return matrix(_r, _c);
-    }
-
-    /// Return the (R,C)'th underlaying base matrix
-    template <std::size_t R, std::size_t C>
-    auto const& getMatrix(const index_t<R> _r = {}, const index_t<C> _c = {}) const
-    {
-      static_assert(R < N() && C < M(), "Indices out of range [0,N)x[0,M)");
-      return matrix(_r, _c);
-    }
-
-    /// Return the underlying multi matrix
-    MultiMatrix&        getMatrix()       { return matrix; }
-    MultiMatrix const&  getMatrix() const { return matrix; }
-
-    /// Return the I'th row finite element space
-    template <std::size_t I = 0>
-    auto& getRowFeSpace(const index_t<I> = {}) const
-    {
-      static_assert(I < N(), "Index out of range [0,N)");
-      return std::get<I>(feSpaces);
-    }
-
-    /// Return the I'th column finite element space
-    template <std::size_t I = 0>
-    auto const& getColFeSpace(const index_t<I> = {}) const
-    {
-      static_assert(I < M(), "Index out of range [0,M)");
-      return std::get<I>(feSpaces);
-    }
-
-    /// Return the (R,C)'th DOFMatrix
-    template <std::size_t R = 0, std::size_t C = 0>
-    auto& operator()(const index_t<R> = {}, const index_t<C> = {})
-    {
-      static_assert(R < N() && C < M(), "Indices out of range [0,N)x[0,M)");
-      return std::get<C>(std::get<R>(dofmatrices));
-    }
-
-    /// Return the (R,C)'th DOFMatrix
-    template <std::size_t R = 0, std::size_t C = 0>
-    auto const& operator()(const index_t<R> = {}, const index_t<C> = {}) const
-    {
-      static_assert(R < N() && C < M(), "Indices out of range [0,N)x[0,M)");
-      return std::get<C>(std::get<R>(dofmatrices));
-    }
-
-  private:
-    /// a tuple of feSpaces for rows and columns of the matrix
-    FeSpaces const& feSpaces;
-
-    /// a tuple of data-matrices
-    MultiMatrix matrix;
-
-    /// a tuple of DOFMatrices
-    DOFMatrices dofmatrices;
-  };
-
-// #ifndef AMDIS_NO_EXTERN_SYSTEMMATRIX
-//     // explicit instantiation in SystemMatrix.cpp
-//     extern template class SystemMatrix<typename TestTraits<2,1,2>::FeSpaces>;
-// #endif
-
-} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/mtl/SystemVector.cpp b/src/amdis/linear_algebra/mtl/SystemVector.cpp
deleted file mode 100644
index 6fe23e982458095ec98ca59a2564cafb541cc638..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/mtl/SystemVector.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-#define AMDIS_NO_EXTERN_SYSTEMVECTOR
-#include <amdis/linear_algebra/mtl/SystemVector.hpp>
-#undef AMDIS_NO_EXTERN_SYSTEMVECTOR
-
-
-namespace AMDiS
-{
-  // explicit template instatiation
-  // template class SystemVector<typename TestTraits<2,1,2>::FeSpaces>;
-} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/mtl/SystemVector.hpp b/src/amdis/linear_algebra/mtl/SystemVector.hpp
deleted file mode 100644
index 93123b79b26a328fcd345c29a51fab599c31e567..0000000000000000000000000000000000000000
--- a/src/amdis/linear_algebra/mtl/SystemVector.hpp
+++ /dev/null
@@ -1,263 +0,0 @@
-#pragma once
-
-#include <algorithm>
-#include <memory>
-#include <string>
-#include <tuple>
-#include <vector>
-
-#include <amdis/Output.hpp>
-#include <amdis/common/Loops.hpp>
-#include <amdis/common/ScalarTypes.hpp>
-#include <amdis/common/TupleUtility.hpp>
-#include <amdis/common/Utility.hpp>
-
-#include <amdis/linear_algebra/mtl/BlockMTLVector.hpp>
-#include <amdis/linear_algebra/mtl/DOFVector.hpp>
-
-// for explicit instantiation
-#include <amdis/ProblemStatTraits.hpp>
-
-namespace AMDiS
-{
-  namespace Impl
-  {
-    // DOFVectors = std::tuple< DOFVector<FeSpace, ValueType>... >
-    template <class DOFVectors>
-    struct BuildDOFVectors
-    {
-      template <std::size_t I>
-      using DOFVectorIdx = std::tuple_element_t<I, DOFVectors>;
-
-      template <std::size_t... I, class FeSpaces, class MultiVector>
-      static DOFVectors make(Indices<I...>,
-                              FeSpaces&& feSpaces,
-                              std::vector<std::string> const& names,
-                              MultiVector&& multiVector)
-      {
-        return DOFVectors{DOFVectorIdx<I>(
-          std::get<I>(std::forward<FeSpaces>(feSpaces)),
-          names[I],
-          multiVector[I]
-          )...};
-      }
-    };
-
-    // construction method to construct a tuple of DOFVectors
-    template <class DOFVectors, class FeSpaces, class MultiVector>
-    DOFVectors buildDOFVectors(FeSpaces&& feSpaces,
-                                    std::vector<std::string> const& names,
-                                    MultiVector&& multiVector)
-    {
-      return BuildDOFVectors<DOFVectors>::make(
-          MakeSeq_t<std::tuple_size<std::decay_t<FeSpaces>>::value>(),
-          std::forward<FeSpaces>(feSpaces),
-          names,
-          std::forward<MultiVector>(multiVector));
-    }
-
-  } // end namespace Impl
-
-
-  /// \brief Container that repesents multiple data-Vectors of different value types.
-  /**
-    *  Represents a std::array of \ref mtl::dense_vector + a tuple of corresponding
-    *  feSpaces. This I'th matrix combined with the I'th FeSpace
-    *  builds a \ref DOFVector  and can be return by the \ref operator().
-    **/
-  template <class FeSpaces, class ValueType = double>
-  class SystemVector
-  {
-    using Self = SystemVector;
-
-    template <class FeSpace>
-    using DOFVectorGenerator = DOFVector<FeSpace, ValueType>;
-
-  public:
-    /// The number of blocks
-    static constexpr std::size_t nComponents = std::tuple_size<FeSpaces>::value;
-    AMDIS_STATIC_ASSERT( nComponents > 0 );
-
-    /// The type of the block-vector
-    using BaseVector = typename DOFVectorGenerator<std::tuple_element_t<0, FeSpaces>>::BaseVector;
-    using MultiVector = BlockMTLVector<BaseVector, nComponents>;
-
-    /// The type of the vector of DOFVectors
-    using DOFVectors  = MakeTuple_t<DOFVectorGenerator, FeSpaces>;
-
-    /// Constructor that constructs new base-vectors
-    SystemVector(FeSpaces const& feSpaces, std::vector<std::string> const& names)
-      : feSpaces(feSpaces)
-      , names(names)
-      , vector{}
-      , dofvectors(Impl::buildDOFVectors<DOFVectors>(feSpaces, names, vector))
-    {
-      compress();
-    }
-
-
-    /// Return the number of blocks
-    static constexpr std::size_t size()
-    {
-      return std::tuple_size<FeSpaces>::value;
-    }
-
-    /// Return the number of blocks
-    int count() const
-    {
-      return int(size());
-    }
-
-    /// Return a shared pointer to the I'th underlaying base vector
-    template <std::size_t I>
-    auto& getVector(const index_t<I> = {})
-    {
-      static_assert(I < size(), "Index out of range [0,SIZE)" );
-      return vector[I];
-    }
-
-    /// Return a shared pointer to the I'th underlaying base vector
-    template <std::size_t I>
-    auto const& getVector(const index_t<I> = {}) const
-    {
-      static_assert(I < size(), "Index out of range [0,SIZE)" );
-      return vector[I];
-    }
-
-    /// Return the underlying multi vector
-    MultiVector&        getVector()       { return vector; }
-    MultiVector const&  getVector() const { return vector; }
-
-    /// Return the I'th finite element space
-    template <std::size_t I = 0>
-    auto const& getFeSpace(const index_t<I> = {}) const
-    {
-      static_assert(I < size(), "Index out of range [0,SIZE)" );
-      return std::get<I>(feSpaces);
-    }
-
-    /// Return the name of the i'th DOFVector
-    std::string getName(std::size_t i) const
-    {
-        return names[i];
-    }
-
-    /// Return the I'th DOFVector
-    template <std::size_t I>
-    auto& operator[](const index_t<I>)
-    {
-      static_assert(I < size(), "Index out of range [0,SIZE)" );
-      return std::get<I>(dofvectors);
-    }
-
-    /// Return the I'th DOFVector
-    template <std::size_t I>
-    auto const& operator[](const index_t<I>) const
-    {
-      static_assert(I < size(), "Index out of range [0,SIZE)" );
-      return std::get<I>(dofvectors);
-    }
-
-    /// Return the I'th DOFVector
-    template <std::size_t I>
-    auto& getDOFVector(const index_t<I> = {})
-    {
-      static_assert(I < size(), "Index out of range [0,SIZE)" );
-      return std::get<I>(dofvectors);
-    }
-
-    /// Return the I'th DOFVector
-    template <std::size_t I>
-    auto const& getDOFVector(const index_t<I> = {}) const
-    {
-      static_assert(I < size(), "Index out of range [0,SIZE)" );
-      return std::get<I>(dofvectors);
-    }
-
-    /// Resize the I'th \ref vector to the sizes of the I'th \ref feSpaces.
-    template <std::size_t I = 0>
-    void compress(const index_t<I> = {})
-    {
-      std::get<I>(dofvectors).compress();
-    }
-
-    /// Resize the \ref vectors to the sizes of the \ref feSpaces.
-    void compress()
-    {
-      forEach(range_<0, size()>, [this](const auto I) {
-        std::get<I>(dofvectors).compress();
-      });
-    }
-
-    /// Copy the Systemvector \p that element-wise
-    void copy(Self const& that)
-    {
-      forEach(range_<0, size()>, [this, &that](const auto I) {
-        std::get<I>(dofvectors).copy(that[I]);
-      });
-    }
-
-    /// Scale each DOFVector by the factor \p s.
-    template <class Scalar>
-    std::enable_if_t< Concepts::Arithmetic<Scalar>, Self&>
-    operator*=(Scalar s)
-    {
-      forEach(range_<0, size()>, [this, s](const auto I) {
-        vector[I] *= s;
-      });
-      return *this;
-    }
-
-    /// Sets each DOFVector to the scalar \p s.
-    template <class Scalar>
-    std::enable_if_t< Concepts::Arithmetic<Scalar>, Self&>
-    operator=(Scalar s)
-    {
-      forEach(range_<0, size()>, [this, s](const auto I) {
-        vector[I] = s;
-      });
-      return *this;
-    }
-
-  private:
-    /// a tuple of feSpaces
-    FeSpaces const& feSpaces;
-
-    /// The names of the DOFVectors
-    std::vector<std::string> names;
-
-    /// a tuple of base vectors, i.e. mtl::dense_vectors
-    MultiVector vector;
-
-    /// a tuple of dofvectors referencing \ref vector
-    DOFVectors dofvectors;
-  };
-
-
-  /// Construct a systemvector from given feSpace-tuple and names-vector
-  template <class FeSpacesType, class ValueType = double>
-  SystemVector<FeSpacesType, ValueType>
-  makeSystemVector(FeSpacesType const& feSpaces, std::vector<std::string> names)
-  {
-    return {feSpaces, names};
-  }
-
-  /// Construct a systemvector from given feSpace-tuple. Create vector of names
-  /// from base_name, i.e. {base_name_0, base_name_1, ...}
-  template <class FeSpaces, class ValueType = double>
-  SystemVector<FeSpaces, ValueType>
-  makeSystemVector(FeSpaces const& feSpaces, std::string base_name)
-  {
-    std::vector<std::string> names;
-    for (std::size_t i = 0; i < std::tuple_size<FeSpaces>::value; ++i)
-      names.push_back(base_name + "_" + std::to_string(i));
-    return {feSpaces, names};
-  }
-
-
-// #ifndef AMDIS_NO_EXTERN_SYSTEMVECTOR
-//     // explicit instantiation in SystemVector.cpp
-//     extern template class SystemVector<typename TestTraits<2,1,2>::FeSpaces>;
-// #endif
-
-} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/mtl/UmfpackRunner.hpp b/src/amdis/linear_algebra/mtl/UmfpackRunner.hpp
index fbca866f1b4cef556ec22cb702df3c28f21f8eb8..26b0cb0805edca1fa5c349f0268be75264b56a38 100644
--- a/src/amdis/linear_algebra/mtl/UmfpackRunner.hpp
+++ b/src/amdis/linear_algebra/mtl/UmfpackRunner.hpp
@@ -1,23 +1,17 @@
 #pragma once
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
 #ifdef HAVE_UMFPACK
 
 #include <algorithm>
-#include <iostream>
 #include <string>
 
 #include <boost/numeric/mtl/operation/two_norm.hpp>
 #include <boost/numeric/mtl/interface/umfpack_solve.hpp>
 
+#include <amdis/Output.hpp>
 #include <amdis/linear_algebra/RunnerInterface.hpp>
 #include <amdis/linear_algebra/SolverInfo.hpp>
 
-#include <amdis/linear_algebra/mtl/Copy.hpp>
-
 namespace AMDiS
 {
   /**
@@ -40,16 +34,16 @@ namespace AMDiS
     using Super = RunnerInterface<Matrix, Vector>;
     using PreconBase = typename Super::PreconBase;
 
-    using FullMatrix = BaseMatrix_t<Matrix>;
+    using FullMatrix = Matrix;
     using SolverType = mtl::mat::umfpack::solver<FullMatrix>;
 
   public:
     /// Constructor. Reads UMFPACK parameters from initfile
     UmfpackRunnerBase(std::string prefix)
     {
-      Parameters::get(prefix + "->store symbolic", store_symbolic); // ?
-      Parameters::get(prefix + "->symmetric strategy", symmetric_strategy);
-      Parameters::get(prefix + "->alloc init", alloc_init);
+      Parameters::get(prefix + "->store symbolic", storeSymbolic_); // ?
+      Parameters::get(prefix + "->symmetric strategy", symmetricStrategy_);
+      Parameters::get(prefix + "->alloc init", allocInit_);
     }
 
     /// Destructor
@@ -60,11 +54,11 @@ namespace AMDiS
                       SolverInfo& solverInfo) override
     {
       AMDIS_FUNCNAME("Umfpack_Runner::solve()");
-      test_exit(bool(solver), "The umfpack solver was not initialized\n");
+      test_exit(bool(solver_), "The umfpack solver was not initialized\n");
 
       int code = 0;
       try {
-	      code = (*solver)(x, b);
+	      code = (*solver_)(x, b);
       } catch (mtl::mat::umfpack::error& e) {
 	      error_exit("UMFPACK_ERROR(solve, ", e.code, ") = ", e.what());
       }
@@ -79,47 +73,17 @@ namespace AMDiS
       return code;
     }
 
-    /// Implementation of \ref RunnerInterface::adjoint_solve()
+    /// Implementation of \ref RunnerInterface::exit()
     virtual void exit() override {}
 
   protected:
-    std::shared_ptr<SolverType> solver;
+    std::shared_ptr<SolverType> solver_;
 
-    int store_symbolic = 0;
-    int symmetric_strategy = 0;
-    double alloc_init = 0.7;
+    int storeSymbolic_ = 0;
+    int symmetricStrategy_ = 0;
+    double allocInit_ = 0.7;
   };
 
-  // specialization for block-matrices
-  template <class SubMatrix, std::size_t _N, std::size_t _M, class Vector>
-  class UmfpackRunner<BlockMTLMatrix<SubMatrix, _N, _M>, Vector>
-      : public UmfpackRunnerBase<BlockMTLMatrix<SubMatrix, _N, _M>, Vector>
-  {
-    using Matrix = BlockMTLMatrix<SubMatrix, _N, _M>;
-    using Super = UmfpackRunnerBase<Matrix, Vector>;
-
-    using SolverType = typename Super::SolverType;
-
-  public:
-    UmfpackRunner(std::string prefix)
-      : Super(prefix)
-    {}
-
-    /// Implementation of \ref RunnerInterface::init()
-    virtual void init(Matrix const& A) override
-    {
-      copy(A, fullMatrix);
-
-      try {
-        Super::solver.reset(new SolverType(fullMatrix, Super::symmetric_strategy, Super::alloc_init));
-      } catch (mtl::mat::umfpack::error const& e) {
-        error_exit("UMFPACK_ERROR(factorize, ", e.code, ") = ", e.what());
-      }
-    }
-
-  private:
-    typename Super::FullMatrix fullMatrix;
-  };
 
   // specialization for full-matrices
   template <class T, class Param, class Vector>
@@ -140,7 +104,7 @@ namespace AMDiS
     virtual void init(FullMatrix const& fullMatrix) override
     {
       try {
-        Super::solver.reset(new SolverType(fullMatrix, Super::symmetric_strategy, Super::alloc_init));
+        Super::solver_.reset(new SolverType(fullMatrix, Super::symmetricStrategy_, Super::allocInit_));
       } catch (mtl::mat::umfpack::error const& e) {
         error_exit("UMFPACK_ERROR(factorize, ", e.code, ") = ", e.what());
       }
diff --git a/src/amdis/utility/MultiIndex.hpp b/src/amdis/utility/MultiIndex.hpp
index 196f12d70829ba7f3abbbfb24f72ce625e9e02b4..424e70aedd8da13f50bd1f5b780525d1e733b37a 100644
--- a/src/amdis/utility/MultiIndex.hpp
+++ b/src/amdis/utility/MultiIndex.hpp
@@ -1,17 +1,23 @@
 #pragma once
 
 #include <dune/common/reservedvector.hh>
-#include <dune/functions/common/indexaccess.hh>
 #include <dune/functions/functionspacebases/flatmultiindex.hh>
 
-#include <amdis/common/Mpl.hpp>
-
 namespace AMDiS
 {
-  std::size_t flatMultiIndex(std::size_t idx) { return idx; }
+  std::size_t flatMultiIndex(std::size_t idx)
+  {
+    return idx;
+  }
 
-  std::size_t flatMultiIndex(Dune::Functions::FlatMultiIndex<std::size_t> const& idx) { return idx[0]; }
+  std::size_t flatMultiIndex(Dune::Functions::FlatMultiIndex<std::size_t> const& idx)
+  {
+    return idx[0];
+  }
 
-  std::size_t flatMultiIndex(Dune::ReservedVector<std::size_t,1> const& idx) { return idx[0]; }
+  std::size_t flatMultiIndex(Dune::ReservedVector<std::size_t,1> const& idx)
+  {
+    return idx[0];
+  }
 
 } // end namespace AMDiS
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index b5eb3aaba4cf03f3d7803773612b3456642963a3..afb4a3ccb701712555aa9c954ca56d6c346907e1 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -8,6 +8,9 @@ dune_add_test(SOURCES ClonablePtrTest.cpp
 dune_add_test(SOURCES ConceptsTest.cpp
   LINK_LIBRARIES amdis)
 
+dune_add_test(SOURCES DOFVectorTest.cpp
+  LINK_LIBRARIES amdis)
+
 dune_add_test(SOURCES ExpressionsTest.cpp
   LINK_LIBRARIES amdis
   CMD_ARGS "${CMAKE_SOURCE_DIR}/examples/init/ellipt.dat.2d")
diff --git a/test/DOFVectorTest.cpp b/test/DOFVectorTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a1706a5b90537cb71dbd8bb2ec952e1fc5f5285e
--- /dev/null
+++ b/test/DOFVectorTest.cpp
@@ -0,0 +1,56 @@
+#include <dune/common/filledarray.hh>
+#include <dune/grid/yaspgrid.hh>
+#include <dune/functions/functionspacebases/compositebasis.hh>
+#include <dune/functions/functionspacebases/powerbasis.hh>
+#include <dune/functions/functionspacebases/lagrangebasis.hh>
+
+#include <amdis/LinearAlgebra.hpp>
+
+#include "Tests.hpp"
+
+using namespace AMDiS;
+using namespace Dune::Functions::BasisFactory;
+
+template <class B, class T>
+void test_dofvector(B const& basis, DOFVector<B,T>& vec)
+{
+  AMDIS_TEST( vec.size() == basis.dimension() );
+  vec.compress();
+
+  vec = T(0);
+  vec[0] = T(1);
+  auto m0 = std::min_element(std::begin(vec.vector()), std::end(vec.vector()));
+  auto m1 = std::max_element(std::begin(vec.vector()), std::end(vec.vector()));
+  AMDIS_TEST( *m0 == T(0) );
+  AMDIS_TEST( *m1 == T(1) );
+}
+
+int main()
+{
+  // create grid
+  Dune::FieldVector<double, 2> L; L = 1.0;
+  auto s = Dune::filledArray<2>(1);
+  Dune::YaspGrid<2> grid(L, s);
+
+  // create basis
+  auto basis = makeBasis(grid.leafGridView(),
+    composite(power<2>(lagrange<2>(), flatInterleaved()), lagrange<1>(), flatLexicographic()));
+
+  using Basis = decltype(basis);
+  DOFVector<Basis> vec1(basis);
+  test_dofvector(basis, vec1);
+
+  DOFVector<Basis, float> vec2(basis);
+  test_dofvector(basis, vec2);
+
+  auto vec3 = makeDOFVector(basis);
+  test_dofvector(basis, vec3);
+
+  auto vec4 = makeDOFVector<float>(basis);
+  test_dofvector(basis, vec4);
+
+#if DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
+  DOFVector vec5(basis);
+  test_dofvector(basis, vec5);
+#endif
+}
\ No newline at end of file