From 4a878787e8252a9c318c6a565972bb0293acc1f0 Mon Sep 17 00:00:00 2001
From: Simon Praetorius <simon.praetorius@tu-dresden.de>
Date: Sun, 23 Sep 2018 19:39:42 +0200
Subject: [PATCH] ISTL solvers and data structured usable

---
 examples/ellipt.cc                            |   2 +-
 examples/init/ellipt.dat.2d                   |   8 +-
 examples/stokes0.cc                           |   2 +
 examples/stokes1.cc                           |   2 +
 examples/vecellipt.cc                         |   2 +
 src/amdis/Assembler.inc.hpp                   |   4 +-
 src/amdis/LinearAlgebra.hpp                   |  12 +-
 src/amdis/linear_algebra/DOFMatrixBase.hpp    |  14 +
 src/amdis/linear_algebra/DOFVectorBase.hpp    |  53 +++
 .../linear_algebra/{mtl => }/LinearSolver.hpp |  21 +-
 .../linear_algebra/LinearSolverInterface.hpp  |   2 +-
 src/amdis/linear_algebra/istl/CMakeLists.txt  |   3 -
 src/amdis/linear_algebra/istl/DOFMatrix.hpp   | 165 ++++----
 src/amdis/linear_algebra/istl/DOFVector.hpp   | 200 ++++-----
 .../linear_algebra/istl/DirectRunner.hpp      |  63 +++
 src/amdis/linear_algebra/istl/Fwd.hpp         |   8 +
 src/amdis/linear_algebra/istl/ISTLRunner.hpp  |  87 ++--
 .../istl/ISTL_Preconditioner.hpp              | 133 ++++--
 src/amdis/linear_algebra/istl/ISTL_Solver.hpp | 230 +++++++----
 .../linear_algebra/istl/LinearSolver.hpp      |  70 ----
 .../linear_algebra/istl/Preconditioner.hpp    |  80 ----
 .../linear_algebra/istl/SystemMatrix.cpp      |  11 -
 .../linear_algebra/istl/SystemMatrix.hpp      | 318 ---------------
 .../linear_algebra/istl/SystemVector.cpp      |  11 -
 .../linear_algebra/istl/SystemVector.hpp      | 383 ------------------
 src/amdis/linear_algebra/mtl/DOFMatrix.hpp    |  22 +-
 src/amdis/linear_algebra/mtl/DOFVector.hpp    |  73 +---
 src/amdis/linear_algebra/mtl/ITL_Solver.hpp   |   6 +-
 .../linear_algebra/mtl/Preconditioner.hpp     |   3 +-
 29 files changed, 689 insertions(+), 1299 deletions(-)
 create mode 100644 src/amdis/linear_algebra/DOFMatrixBase.hpp
 create mode 100644 src/amdis/linear_algebra/DOFVectorBase.hpp
 rename src/amdis/linear_algebra/{mtl => }/LinearSolver.hpp (72%)
 create mode 100644 src/amdis/linear_algebra/istl/DirectRunner.hpp
 create mode 100644 src/amdis/linear_algebra/istl/Fwd.hpp
 delete mode 100644 src/amdis/linear_algebra/istl/LinearSolver.hpp
 delete mode 100644 src/amdis/linear_algebra/istl/Preconditioner.hpp
 delete mode 100644 src/amdis/linear_algebra/istl/SystemMatrix.cpp
 delete mode 100644 src/amdis/linear_algebra/istl/SystemMatrix.hpp
 delete mode 100644 src/amdis/linear_algebra/istl/SystemVector.cpp
 delete mode 100644 src/amdis/linear_algebra/istl/SystemVector.hpp

diff --git a/examples/ellipt.cc b/examples/ellipt.cc
index fdfc81c6..fc7830e8 100644
--- a/examples/ellipt.cc
+++ b/examples/ellipt.cc
@@ -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/init/ellipt.dat.2d b/examples/init/ellipt.dat.2d
index f1256572..0ef4d635 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/stokes0.cc b/examples/stokes0.cc
index e3785be1..40a8c425 100644
--- a/examples/stokes0.cc
+++ b/examples/stokes0.cc
@@ -80,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().matrix();
     std::cout << prob.getSystemMatrix().matrix() << '\n';
+#endif
 
     prob.solve(adaptInfo);
 
diff --git a/examples/stokes1.cc b/examples/stokes1.cc
index 9126c3d4..bdb95a3b 100644
--- a/examples/stokes1.cc
+++ b/examples/stokes1.cc
@@ -81,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().matrix();
     std::cout << prob.getSystemMatrix().matrix() << '\n';
+#endif
 
     prob.solve(adaptInfo);
 
diff --git a/examples/vecellipt.cc b/examples/vecellipt.cc
index f078cdd7..a4dfb407 100644
--- a/examples/vecellipt.cc
+++ b/examples/vecellipt.cc
@@ -42,6 +42,7 @@ 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");
@@ -49,6 +50,7 @@ int main(int argc, char** argv)
 
     std::cout << prob.getSystemMatrix().matrix() << '\n';
   }
+#endif
 
   prob.solve(adaptInfo);
   prob.writeFiles(adaptInfo, true);
diff --git a/src/amdis/Assembler.inc.hpp b/src/amdis/Assembler.inc.hpp
index 2d4610a8..ac0ccb05 100644
--- a/src/amdis/Assembler.inc.hpp
+++ b/src/amdis/Assembler.inc.hpp
@@ -24,8 +24,8 @@ void Assembler<Traits>::assemble(
   // 2. create a local matrix and vector
   std::size_t localSize = localView.maxSize();
 
-  mtl::mat::dense2D<typename SystemMatrixType::value_type> elementMatrix(localSize, localSize);
-  mtl::vec::dense_vector<typename SystemVectorType::value_type> elementVector(localSize);
+  mtl::mat::dense2D<double> elementMatrix(localSize, localSize);
+  mtl::vec::dense_vector<double> elementVector(localSize);
 
   // 3. traverse grid and assemble operators on the elements
   for (auto const& element : elements(globalBasis_.gridView()))
diff --git a/src/amdis/LinearAlgebra.hpp b/src/amdis/LinearAlgebra.hpp
index 898404a0..d0ec769f 100644
--- a/src/amdis/LinearAlgebra.hpp
+++ b/src/amdis/LinearAlgebra.hpp
@@ -1,8 +1,16 @@
 #pragma once
 
-#include <amdis/linear_algebra/LinearSolverInterface.hpp>
+#include <amdis/linear_algebra/LinearSolver.hpp>
 #include <amdis/linear_algebra/SolverInfo.hpp>
+
+#if HAVE_MTL
 #include <amdis/linear_algebra/mtl/DOFVector.hpp>
 #include <amdis/linear_algebra/mtl/DOFMatrix.hpp>
-#include <amdis/linear_algebra/mtl/LinearSolver.hpp>
 #include <amdis/linear_algebra/mtl/ITL_Solver.hpp>
+#include <amdis/linear_algebra/mtl/ITL_Preconditioner.hpp>
+#else
+#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/linear_algebra/DOFMatrixBase.hpp b/src/amdis/linear_algebra/DOFMatrixBase.hpp
new file mode 100644
index 00000000..e7bf16d9
--- /dev/null
+++ b/src/amdis/linear_algebra/DOFMatrixBase.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/DOFVectorBase.hpp b/src/amdis/linear_algebra/DOFVectorBase.hpp
new file mode 100644
index 00000000..68cb1c99
--- /dev/null
+++ b/src/amdis/linear_algebra/DOFVectorBase.hpp
@@ -0,0 +1,53 @@
+#pragma once
+
+#include <algorithm>
+#include <memory>
+#include <string>
+
+#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/DOFVectorInterface.hpp>
+#include <amdis/utility/MultiIndex.hpp>
+
+namespace AMDiS
+{
+  /// The basic container that stores a base vector and a corresponding basis
+  template <class BasisType>
+  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;
+
+    /// Constructor. Constructs new BaseVector.
+    DOFVectorBase(BasisType const& basis)
+      : basis_(&basis)
+    {}
+
+    /// Return the basis \ref basis_ of the vector
+    Basis const& basis() const
+    {
+        return *basis_;
+    }
+
+    /// Return the size of the \ref basis
+    size_type size() const
+    {
+      return basis_->dimension();
+    }
+
+  private:
+    /// The finite element space / basis associated with the data vector
+    Basis const* basis_;
+  };
+
+} // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/mtl/LinearSolver.hpp b/src/amdis/linear_algebra/LinearSolver.hpp
similarity index 72%
rename from src/amdis/linear_algebra/mtl/LinearSolver.hpp
rename to src/amdis/linear_algebra/LinearSolver.hpp
index ed44e4c2..b132ef31 100644
--- a/src/amdis/linear_algebra/mtl/LinearSolver.hpp
+++ b/src/amdis/linear_algebra/LinearSolver.hpp
@@ -14,18 +14,18 @@ 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:
@@ -44,15 +44,15 @@ namespace AMDiS
       : 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_;
     }
 
   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;
@@ -61,9 +61,8 @@ namespace AMDiS
         runner_->init(A);
       }
 
-      if (solverInfo.getInfo() > 0) {
-        msg("fill MTL4 matrix needed ", t.elapsed(), " seconds");
-      }
+      if (solverInfo.getInfo() > 0)
+        msg("fill matrix needed ", t.elapsed(), " seconds");
 
       int error = runner_->solve(A, x, b, solverInfo);
       solverInfo.setError(error);
diff --git a/src/amdis/linear_algebra/LinearSolverInterface.hpp b/src/amdis/linear_algebra/LinearSolverInterface.hpp
index 3edf1d2d..da59c028 100644
--- a/src/amdis/linear_algebra/LinearSolverInterface.hpp
+++ b/src/amdis/linear_algebra/LinearSolverInterface.hpp
@@ -48,7 +48,7 @@ namespace AMDiS
     }
 
     // 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/istl/CMakeLists.txt b/src/amdis/linear_algebra/istl/CMakeLists.txt
index cd5ee97f..26238d75 100644
--- a/src/amdis/linear_algebra/istl/CMakeLists.txt
+++ b/src/amdis/linear_algebra/istl/CMakeLists.txt
@@ -11,7 +11,4 @@ install(FILES
     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 fbaaa635..09739652 100644
--- a/src/amdis/linear_algebra/istl/DOFMatrix.hpp
+++ b/src/amdis/linear_algebra/istl/DOFMatrix.hpp
@@ -8,111 +8,126 @@
 
 #include <amdis/Output.hpp>
 #include <amdis/common/ClonablePtr.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>>
+  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 RowBasisType, class ColBasisType,
+            class ValueType = double>
   class DOFMatrix
   {
   public:
-    using RowFeSpace = RowFeSpaceType;
-    using ColFeSpace = ColFeSpaceType;
-    using BaseMatrix = Dune::BCRSMatrix<ValueType>;
+    /// 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;
 
-    using size_type  = typename RowFeSpaceType::size_type;
-    using field_type = typename ValueType::field_type;
+    /// The type of the elements of the DOFMatrix
+    using value_type = typename BlockMatrixType<ValueType>::type;
 
-    using value_type = ValueType;
+    /// The matrix type of the underlying base matrix
+    using BaseMatrix = Dune::BCRSMatrix<value_type>;
 
+    /// 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())
+    DOFMatrix(RowBasis const& rowBasis, ColBasis const& colBasis)
+      : rowBasis_(&rowBasis)
+      , colBasis_(&colBasis)
+      , 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)
+    /// Constructor. Takes reference to a base matrix.
+    DOFMatrix(RowBasis const& rowBasis, ColBasis const& colBasis, BaseMatrix& matrix)
+      : rowBasis_(&rowBasis)
+      , colBasis_(&colBasis)
+      , matrix_(matrix)
     {}
 
-    /// Return the row-basis \ref rowFeSpace of the matrix
-    RowFeSpace const& getRowFeSpace() const
+    /// Return the row-basis \ref rowBasis of the matrix
+    RowBasis const& rowBasis() const
     {
-      return rowFeSpace;
+      return *rowBasis_;
     }
 
-    /// Return the col-basis \ref colFeSpace of the matrix
-    ColFeSpace const& getColFeSpace() const
+    /// Return the col-basis \ref colBasis of the matrix
+    ColBasis const& colBasis() const
     {
-      return colFeSpace;
+      return *colBasis_;
     }
 
     /// 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()
+    BaseMatrix& matrix()
     {
-      return *matrix;
+      return *matrix_;
     }
 
     /// Return the size of the \ref feSpace
-    size_type N() const
-    {
-      return rowFeSpace.size();
-    }
-
-    size_type M() const
+    size_type rows() const
     {
-      return colFeSpace.size();
+      return rowBasis_->size();
     }
 
-    /// Return the \ref name of this vector
-    std::string getName() const
+    size_type cols() const
     {
-      return name;
+      return colBasis_->size();
     }
 
 
     /// Access the entry \p i of the \ref vector with read-access.
-    value_type const& operator()(size_type r, size_type c) const
+    template <class Index>
+    value_type const& operator()(Index row, Index col) const
     {
-      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];
+      size_type r = flatMultiIndex(row), c = flatMultiIndex(col);
+      test_exit_dbg( initialized_, "Occupation pattern not initialized!");
+      test_exit_dbg( r < rows() && c < cols() ,
+          "Indices out of range [0,", rows(), ")x[0,", cols(), ")" );
+      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)
+    template <class Index>
+    value_type& operator()(Index row, Index col)
     {
-      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];
+      size_type r = flatMultiIndex(row), c = flatMultiIndex(col);
+      test_exit_dbg( initialized_, "Occupation pattern not initialized!");
+      test_exit_dbg( r < rows() && c < cols() ,
+          "Indices out of range [0,", rows(), ")x[0,", cols(), ")" );
+      return (*matrix_)[r][c];
     }
 
     /// create occupation pattern and apply it to the matrix
-    void init()
+    void init(bool prepareForInsertion)
     {
-      occupationPattern.resize(rowFeSpace.size(), colFeSpace.size());
-      auto meshView = rowFeSpace.gridView();
+      occupationPattern_.resize(rowBasis_->size(), colBasis_->size());
 
       // A loop over all elements of the grid
-      auto rowLocalView = rowFeSpace.localView();
-      auto colLocalView = colFeSpace.localView();
+      auto rowLocalView = rowBasis_->localView();
+      auto colLocalView = colBasis_->localView();
 
-      for (const auto& element : elements(meshView)) {
+      for (const auto& element : elements(rowBasis_->gridView())) {
         rowLocalView.bind(element);
         colLocalView.bind(element);
 
@@ -122,54 +137,50 @@ namespace AMDiS
           for (std::size_t j = 0; j < colLocalView.size(); ++j) {
             // The global index of the j-th vertex of the element
             auto col = colLocalView.index(j);
-            occupationPattern.add(row, col);
+            occupationPattern_.add(row, col);
           }
         }
       }
-      occupationPattern.exportIdx(*matrix);
+      occupationPattern_.exportIdx(*matrix_);
 
-      initialized = true;
+      initialized_ = true;
     }
 
     void finish()
     {
-      initialized = false;
+      initialized_ = false;
     }
 
-    std::size_t nnz()
+    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
+      std::list<Triplet<value_type>> columns; // symmetric dbc not yet implemented
       return columns;
     }
 
   private:
-    RowFeSpace const&	rowFeSpace;
-    ColFeSpace const&	colFeSpace;
-    std::string	        name;
-
-    ClonablePtr<BaseMatrix> matrix;
-    Dune::MatrixIndexSet    occupationPattern;
+    RowBasis const*	rowBasis_;
+    ColBasis const*	colBasis_;
 
-    bool initialized = false;
+    ClonablePtr<BaseMatrix> matrix_;
+    Dune::MatrixIndexSet occupationPattern_;
 
-    // friend class declarations
-    template <class, class, class> friend class SystemMatrix;
+    bool initialized_ = false;
   };
 
 } // end namespace AMDiS
diff --git a/src/amdis/linear_algebra/istl/DOFVector.hpp b/src/amdis/linear_algebra/istl/DOFVector.hpp
index 63a5aebb..ddcfd151 100644
--- a/src/amdis/linear_algebra/istl/DOFVector.hpp
+++ b/src/amdis/linear_algebra/istl/DOFVector.hpp
@@ -1,124 +1,126 @@
 #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>
+#include <amdis/utility/MultiIndex.hpp>
 
 namespace AMDiS
 {
-    template <class FeSpaceType, class ValueType = Dune::FieldVector<double,1>>
-    class DOFVector
-    {
-        using Self = DOFVector;
+  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 BasisType, class ValueType = double>
+	class DOFVector
+      : public DOFVectorBase<BasisType>
+	{
+	  using Self = DOFVector;
+    using Super = DOFVectorBase<BasisType>;
 
-    public:
-	using FeSpace    = FeSpaceType;
-	using BaseVector = Dune::BlockVector<ValueType>;
+	public:
+    /// The type of the finite element space / basis
+	  using Basis = BasisType;
 
-	using size_type  = typename FeSpace::size_type;
-	using field_type = typename ValueType::field_type;
+    /// The type of the elements of the DOFVector
+	  using value_type = typename BlockVectorType<ValueType>::type;
 
-	using value_type = ValueType;
+    /// The vector type of the underlying base vector
+	  using BaseVector = Dune::BlockVector<value_type>;
 
-	/// 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;
-	}
+    /// The index/size - type
+	  using size_type  = typename Basis::size_type;
 
-	/// Return the data-vector \ref vector
-	BaseVector const& vector() const
-	{
-	    return *vector;
-	}
-
-	/// Return the data-vector \ref vector
-	BaseVector& vector()
-	{
-	    return *vector;
-	}
-
-	/// Return the size of the \ref feSpace
-	size_type getSize() const
-	{
-	    return feSpace.size();
-	}
+    /// Constructor. Constructs new BaseVector.
+    DOFVector(BasisType const& basis)
+      : Super(basis)
+      , vector_(ClonablePtr<BaseVector>::make())
+    {
+      compress();
+    }
 
-	/// Return the \ref name of this vector
-	std::string getName() const
-	{
-	    return name;
-	}
+    /// Constructor. Takes pointer of data-vector.
+    DOFVector(BasisType const& basis, Dune::BlockVector<ValueType>& vector)
+      : Super(basis)
+      , vector_(vector)
+    {}
 
-	/// 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);
-	}
+    /// Resize the \ref vector to the size of the \ref basis.
+    virtual void compress() override
+    {
+      if (vector_->size() != this->size()) {
+        resize(this->size());
+        *vector_ = value_type(0);
+      }
+    }
+
+    template <class SizeInfo>
+    void resize(SizeInfo s)
+    {
+      vector_->resize(size_type(s));
+    }
 
-	/// Calls the copy assignment operator of the BaseVector \ref vector
-	void copy(Self const& that)
-	{
-		*vector = that.vector();
-	}
 
-    private:
-	FeSpace const&	feSpace;
-	std::string	name;
+    /// Access the entry \p i of the \ref vector with read-access.
+    template <class Index>
+    value_type const& operator[](Index idx) const
+    {
+      size_type i = flatMultiIndex(idx);
+      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.
+    template <class Index>
+    value_type& operator[](Index idx)
+    {
+      size_type i = flatMultiIndex(idx);
+      test_exit_dbg(i < vector_->size(),
+        "Index ", i, " out of range [0,", vector_->size(), ")" );
+      return (*vector_)[i];
+    }
+
+    /// 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;
+    }
 
-	ClonablePtr<BaseVector> vector;
+    /// Calls the copy assignment operator of the BaseVector \ref vector
+    void copy(Self const& that)
+    {
+      *vector_ = that.vector();
+    }
 
-    // friend class declarations
-    template <class, class>
-    friend class SystemVector;
-    };
+	private:
+    ClonablePtr<BaseVector> vector_;
+	};
 
 } // 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 00000000..187abadf
--- /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 00000000..e2ad22c2
--- /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 46d7790f..99c4927e 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 750b562b..4a653fa7 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 558677db..e32d52fe 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 7799eaa2..00000000
--- 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 6c331d53..00000000
--- 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 26d4d975..00000000
--- 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 fa3e50b2..00000000
--- 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 fc04f99b..00000000
--- 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 7dfcbb2b..00000000
--- 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/DOFMatrix.hpp b/src/amdis/linear_algebra/mtl/DOFMatrix.hpp
index 7adbf1b8..67c702b3 100644
--- a/src/amdis/linear_algebra/mtl/DOFMatrix.hpp
+++ b/src/amdis/linear_algebra/mtl/DOFMatrix.hpp
@@ -12,21 +12,14 @@
 
 #include <amdis/Output.hpp>
 #include <amdis/common/ClonablePtr.hpp>
+#include <amdis/linear_algebra/DOFMatrixBase.hpp>
 #include <amdis/utility/MultiIndex.hpp>
 
 namespace AMDiS
 {
-  template <class T>
-  struct Triplet
-  {
-    std::size_t row, cols;
-    T value;
-  };
-
   /// \brief The basic container that stores a base matrix and a corresponding
   /// row/column feSpace.
-  template <class RowBasisType,
-            class ColBasisType,
+  template <class RowBasisType, class ColBasisType,
             class ValueType = double>
   class DOFMatrix
   {
@@ -41,7 +34,7 @@ namespace AMDiS
     using BaseMatrix = mtl::compressed2D<ValueType>;
 
     /// The index/size - type
-    using size_type  = typename BaseMatrix::size_type;
+    using size_type = typename BaseMatrix::size_type;
 
     /// The type of the elements of the DOFMatrix
     using value_type = ValueType;
@@ -51,17 +44,14 @@ namespace AMDiS
 
   public:
     /// Constructor. Constructs new BaseMatrix.
-    DOFMatrix(RowBasis const& rowBasis,
-              ColBasis const& colBasis)
+    DOFMatrix(RowBasis const& rowBasis, ColBasis const& colBasis)
       : rowBasis_(&rowBasis)
       , colBasis_(&colBasis)
       , matrix_(ClonablePtr<BaseMatrix>::make())
     {}
 
-    /// Constructor. Takes pointer of data-matrix.
-    DOFMatrix(RowBasis const& rowBasis,
-              ColBasis const& colBasis,
-              BaseMatrix& matrix)
+    /// Constructor. Takes a reference to a base matrix
+    DOFMatrix(RowBasis const& rowBasis, ColBasis const& colBasis, BaseMatrix& matrix)
       : rowBasis_(&rowBasis)
       , colBasis_(&colBasis)
       , matrix_(matrix)
diff --git a/src/amdis/linear_algebra/mtl/DOFVector.hpp b/src/amdis/linear_algebra/mtl/DOFVector.hpp
index f5ff128c..7287b807 100644
--- a/src/amdis/linear_algebra/mtl/DOFVector.hpp
+++ b/src/amdis/linear_algebra/mtl/DOFVector.hpp
@@ -1,59 +1,50 @@
 #pragma once
 
-#include <algorithm>
-#include <memory>
-#include <string>
-
 #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/DOFVectorInterface.hpp>
+#include <amdis/linear_algebra/DOFVectorBase.hpp>
 #include <amdis/utility/MultiIndex.hpp>
 
 namespace AMDiS
 {
   /// The basic container that stores a base vector and a corresponding basis
-  template <class GlobalBasis, class ValueType = double>
+  template <class BasisType, class ValueType = double>
   class DOFVector
-      : public DOFVectorInterface
+      : public DOFVectorBase<BasisType>
   {
     using Self = DOFVector;
+    using Super = DOFVectorBase<BasisType>;
 
   public:
     /// The type of the \ref basis
-    using Basis = GlobalBasis;
+    using Basis = BasisType;
 
     /// The type of the base vector
     using BaseVector = mtl::vec::dense_vector<ValueType>;
 
     /// The index/size - type
-    using size_type  = typename GlobalBasis::size_type;
+    using size_type  = typename BasisType::size_type;
 
     /// The type of the elements of the DOFVector
     using value_type = ValueType;
 
     /// Constructor. Constructs new BaseVector.
-    DOFVector(GlobalBasis const& basis)
-      : basis_(&basis)
+    DOFVector(BasisType const& basis)
+      : Super(basis)
       , vector_(ClonablePtr<BaseVector>::make())
     {
       compress();
     }
 
     /// Constructor. Takes reference to existing BaseVector
-    DOFVector(GlobalBasis const& basis, BaseVector& vector)
-      : basis_(&basis)
+    DOFVector(BasisType const& basis, BaseVector& vector)
+      : Super(basis)
       , vector_(vector)
     {}
 
-    /// Return the basis \ref basis_ of the vector
-    Basis const& basis() const
-    {
-        return *basis_;
-    }
-
     /// Return the data-vector \ref vector_
     BaseVector const& vector() const
     {
@@ -66,17 +57,11 @@ namespace AMDiS
       return *vector_;
     }
 
-    /// Return the size of the \ref basis
-    size_type size() const
-    {
-      return basis_->dimension();
-    }
-
     /// Resize the \ref vector to the size of the \ref basis.
     virtual void compress() override
     {
-      if (num_rows(*vector_) != size()) {
-        resize(size());
+      if (mtl::vec::size(*vector_) != this->size()) {
+        resize(this->size());
         *vector_ = value_type(0);
       }
     }
@@ -93,8 +78,8 @@ namespace AMDiS
     value_type const& operator[](Index idx) const
     {
       size_type i = flatMultiIndex(idx);
-      test_exit_dbg(i < num_rows(*vector_),
-        "Index ", i, " out of range [0,", num_rows(*vector_), ")" );
+      test_exit_dbg(i < mtl::vec::size(*vector_),
+        "Index ", i, " out of range [0,", mtl::vec::size(*vector_), ")" );
       return (*vector_)[i];
     }
 
@@ -103,8 +88,8 @@ namespace AMDiS
     value_type& operator[](Index idx)
     {
       size_type i = flatMultiIndex(idx);
-      test_exit_dbg(i < num_rows(*vector_),
-        "Index ", i, " out of range [0,", num_rows(*vector_), ")" );
+      test_exit_dbg(i < mtl::vec::size(*vector_),
+        "Index ", i, " out of range [0,", mtl::vec::size(*vector_), ")" );
       return (*vector_)[i];
     }
 
@@ -133,36 +118,22 @@ namespace AMDiS
     }
 
   private:
-    /// The finite element space / basis associated with the data vector
-    Basis const* basis_;
-
     /// The data-vector (can hold a new BaseVector or a pointer to external data
     ClonablePtr<BaseVector> vector_;
   };
 
-#if DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
-  // Deduction rules
-  template <class GlobalBasis>
-  DOFVector(GlobalBasis const& basis)
-    -> DOFVector<GlobalBasis, double>;
-
-  template <class GlobalBasis, class ValueType>
-  DOFVector(GlobalBasis const& basis, mtl::vec::dense_vector<ValueType>& coefficients)
-    -> DOFVector<GlobalBasis, ValueType>;
-#endif
-
   /// Constructor a dofvector from given basis and name
-  template <class GlobalBasis, class ValueType = double>
-  DOFVector<GlobalBasis, ValueType>
-  makeDOFVector(GlobalBasis const& basis)
+  template <class Basis, class ValueType = double>
+  DOFVector<Basis, ValueType>
+  makeDOFVector(Basis const& basis)
   {
     return {basis};
   }
 
   /// Constructor a dofvector from given basis, name, and coefficient vector
-  template <class GlobalBasis, class ValueType>
-  DOFVector<GlobalBasis, ValueType>
-  makeDOFVector(GlobalBasis const& basis, mtl::vec::dense_vector<ValueType>& coefficients)
+  template <class Basis, class ValueType>
+  DOFVector<Basis, ValueType>
+  makeDOFVector(Basis const& basis, mtl::vec::dense_vector<ValueType>& coefficients)
   {
     return {basis, coefficients};
   }
diff --git a/src/amdis/linear_algebra/mtl/ITL_Solver.hpp b/src/amdis/linear_algebra/mtl/ITL_Solver.hpp
index 27a76f5c..258e3750 100644
--- a/src/amdis/linear_algebra/mtl/ITL_Solver.hpp
+++ b/src/amdis/linear_algebra/mtl/ITL_Solver.hpp
@@ -16,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>
 
@@ -393,12 +393,12 @@ namespace AMDiS
 
     template <class ITLSolver>
     using SolverCreator
-      = typename LinearSolver<Matrix, Vector,
+      = typename LinearSolver<Matrix, Vector, Vector,
           KrylovRunner<ITLSolver, Matrix, Vector>>::Creator;
 
 #ifdef HAVE_UMFPACK
     using UmfpackSolverCreator
-      = typename LinearSolver<Matrix, Vector,
+      = typename LinearSolver<Matrix, Vector, Vector,
           UmfpackRunner<Matrix, Vector>>::Creator;
 #endif
 
diff --git a/src/amdis/linear_algebra/mtl/Preconditioner.hpp b/src/amdis/linear_algebra/mtl/Preconditioner.hpp
index 6d9922ea..cc610a82 100644
--- a/src/amdis/linear_algebra/mtl/Preconditioner.hpp
+++ b/src/amdis/linear_algebra/mtl/Preconditioner.hpp
@@ -10,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>;
-- 
GitLab