diff --git a/dune/solvers/test/cgsteptest.cc b/dune/solvers/test/cgsteptest.cc
index 6386cfe7fe19fe4d265a36e8c15fe844e3bf9f00..792fe56ceffaeaa446b30b2a3fb1caed2c357e68 100644
--- a/dune/solvers/test/cgsteptest.cc
+++ b/dune/solvers/test/cgsteptest.cc
@@ -61,52 +61,24 @@ struct CGTestSuite
 
         bool passed = true;
 
-        typedef typename Dune::FieldMatrix<double, 1, 1> MatrixBlock;
-        typedef typename Dune::FieldVector<double, 1> VectorBlock;
-        typedef typename Dune::BCRSMatrix<MatrixBlock> Matrix;
-        typedef typename Dune::BlockVector<VectorBlock> Vector;
-        typedef typename Dune::BitSetVector<1> BitVector;
-
-        typedef typename GridType::LevelGridView GridView;
-
-        const GridView gridView = grid.levelGridView(grid.maxLevel());
-
-        Matrix A;
-        constructPQ1Pattern(gridView, A);
-        A=0.0;
-        assemblePQ1Stiffness(gridView, A);
-        EnergyNorm<Matrix, Vector> energyNorm(A);
-
-        Vector u(A.N()), u_sol(A.N());
-        u = 0;
-        for (size_t i=0; i<u.size(); ++i)
-            u_sol[i] = (1.0*rand())/RAND_MAX;
-
-        Vector rhs(A.N());
-        A.mv(u_sol, rhs);
-
-        BitVector ignore(A.N());
-        ignore.unsetAll();
-        markBoundaryDOFs(gridView, ignore);
-
-        // set Dirichlet values
-        for (size_t i=0; i<u.size(); ++i)
-            if (ignore[i][0])
-                u[i] = u_sol[i];
+        using Problem =
+            SymmetricSampleProblem<1, typename GridType::LevelGridView>;
+        Problem p(grid.levelGridView(grid.maxLevel()));
 
         const auto verbosity = Solver::REDUCED;
         const bool relativeErrors = false;
 
-        Analyser<Vector> analyser(u_sol, energyNorm, solveTol);
+        Analyser<typename Problem::Vector> analyser(p.u_ex, p.energyNorm,
+                                                    solveTol);
         {
             std::string const testCase = "CGSolver                             ";
 
-            Vector u_copy = u;
-            Vector rhs_copy = rhs;
+            typename Problem::Vector u_copy = p.u;
+            typename Problem::Vector rhs_copy = p.rhs;
 
-            CGSolver<Matrix,Vector> solver(&A, &u_copy, &rhs_copy, nullptr,
-                                           maxIterations, stepTol, &energyNorm,
-                                           verbosity, relativeErrors);
+            CGSolver<typename Problem::Matrix, typename Problem::Vector> solver(
+                &p.A, &u_copy, &rhs_copy, nullptr, maxIterations, stepTol,
+                &p.energyNorm, verbosity, relativeErrors);
             solver.check();
             solver.preprocess();
             solver.solve();
@@ -116,16 +88,19 @@ struct CGTestSuite
         {
             std::string const testCase = "CGSolver, preconditioned             ";
 
-            Vector u_copy = u;
-            Vector rhs_copy = rhs;
+            typename Problem::Vector u_copy = p.u;
+            typename Problem::Vector rhs_copy = p.rhs;
 
-            using BGS = BlockGSStep<Matrix,Vector,BitVector>;
+            using BGS =
+                BlockGSStep<typename Problem::Matrix, typename Problem::Vector,
+                            typename Problem::BitVector>;
             BGS blockgs(BGS::Direction::SYMMETRIC);
-            blockgs.ignoreNodes_ = new BitVector(u.size(), false);
+            blockgs.ignoreNodes_ =
+                new typename Problem::BitVector(p.u.size(), false);
 
-            CGSolver<Matrix,Vector> solver(&A, &u_copy, &rhs_copy, &blockgs,
-                                           maxIterations, stepTol, &energyNorm,
-                                           verbosity, relativeErrors);
+            CGSolver<typename Problem::Matrix, typename Problem::Vector> solver(
+                &p.A, &u_copy, &rhs_copy, &blockgs, maxIterations, stepTol,
+                &p.energyNorm, verbosity, relativeErrors);
             solver.check();
             solver.preprocess();
             solver.solve();
@@ -135,12 +110,15 @@ struct CGTestSuite
         {
             std::string const testCase = "Dune::Solvers::CGStep                ";
 
-            Vector u_copy = u;
-            Vector rhs_copy = rhs;
+            typename Problem::Vector u_copy = p.u;
+            typename Problem::Vector rhs_copy = p.rhs;
 
-            Dune::Solvers::CGStep<Matrix,Vector> cgStep(A, u_copy, rhs_copy);
-            ::LoopSolver<Vector> solver(&cgStep, maxIterations, stepTol, &energyNorm,
-                                        verbosity, relativeErrors);
+            Dune::Solvers::CGStep<typename Problem::Matrix,
+                                  typename Problem::Vector> cgStep(p.A, u_copy,
+                                                                   rhs_copy);
+            ::LoopSolver<typename Problem::Vector> solver(
+                &cgStep, maxIterations, stepTol, &p.energyNorm, verbosity,
+                relativeErrors);
             solver.check();
             solver.preprocess();
             solver.solve();
@@ -150,16 +128,23 @@ struct CGTestSuite
         {
             std::string const testCase = "Dune::Solvers::CGStep, preconditioned";
 
-            Vector u_copy = u;
-            Vector rhs_copy = rhs;
+            typename Problem::Vector u_copy = p.u;
+            typename Problem::Vector rhs_copy = p.rhs;
 
-            using BGS = BlockGSStep<Matrix,Vector,BitVector>;
+            using BGS =
+                BlockGSStep<typename Problem::Matrix, typename Problem::Vector,
+                            typename Problem::BitVector>;
             BGS blockgs(BGS::Direction::SYMMETRIC);
-            blockgs.ignoreNodes_ = new BitVector(u.size(), false);
-
-            Dune::Solvers::CGStep<Matrix,Vector> cgStep(A, u_copy, rhs_copy, blockgs);
-            ::LoopSolver<Vector> solver(&cgStep, maxIterations, stepTol, &energyNorm,
-                                        verbosity, relativeErrors);
+            blockgs.ignoreNodes_ =
+                new typename Problem::BitVector(p.u.size(), false);
+
+            Dune::Solvers::CGStep<typename Problem::Matrix,
+                                  typename Problem::Vector> cgStep(p.A, u_copy,
+                                                                   rhs_copy,
+                                                                   blockgs);
+            ::LoopSolver<typename Problem::Vector> solver(
+                &cgStep, maxIterations, stepTol, &p.energyNorm, verbosity,
+                relativeErrors);
             solver.check();
             solver.preprocess();
             solver.solve();
diff --git a/dune/solvers/test/common.hh b/dune/solvers/test/common.hh
index 7c7b6badeb13dc50046288cec3a4b7dbf1d9da80..1c585060b19fb0117c8a65b643d92cceb8b85fbe 100644
--- a/dune/solvers/test/common.hh
+++ b/dune/solvers/test/common.hh
@@ -348,6 +348,61 @@ void markBoundaryDOFs(const GridView& gridView, BitVector& isBoundary)
     }
 }
 
+template <size_t blocksize, class GridView>
+class SymmetricSampleProblem {
+public:
+  typedef typename Dune::FieldMatrix<double, blocksize, blocksize> MatrixBlock;
+  typedef typename Dune::FieldVector<double, blocksize> VectorBlock;
+  typedef typename Dune::BCRSMatrix<MatrixBlock> Matrix;
+  typedef typename Dune::BlockVector<VectorBlock> Vector;
+  typedef typename Dune::BitSetVector<blocksize> BitVector;
+  typedef EnergyNorm<Matrix, Vector> Norm;
+
+  SymmetricSampleProblem(GridView const& gridView) {
+    constructPQ1Pattern(gridView, A);
+    A = 0.0;
+    assemblePQ1Stiffness(gridView, A);
+
+    energyNorm.setMatrix(&A);
+
+    ignore.resize(A.N());
+    ignore.unsetAll();
+    markBoundaryDOFs(gridView, ignore);
+
+    u.resize(A.N());
+    u_ex.resize(A.N());
+    rhs.resize(A.N());
+    randomize();
+  }
+
+  void randomize() {
+    // Set up a random 'solution'
+    u = 0;
+    for (size_t i = 0; i < u.size(); ++i)
+      for (size_t j = 0; j < blocksize; ++j) {
+        // in case of no dirichlet values you can make the
+        // matrix pd hereby
+        // A[i][i][j][j] += 0.5*std::abs(A[0][0][0][0]);
+        u_ex[i][j] = (1.0 * rand()) / RAND_MAX;
+      }
+
+    // Construct right hand side corresponding to the 'solution'
+    A.mv(u_ex, rhs);
+
+    // set dirichlet values
+    for (size_t i = 0; i < u.size(); ++i)
+      for (size_t j = 0; j < blocksize; ++j)
+        if (ignore[i][j])
+          u[i][j] = u_ex[i][j];
+  }
+
+  Matrix A;
+  Vector u;
+  Vector u_ex;
+  Vector rhs;
+  BitVector ignore;
+  Norm energyNorm;
+};
 
 template<class GridType, class TestSuite>
 bool checkWithGrid(TestSuite& suite, int uniformRefinements)
diff --git a/dune/solvers/test/multigridtest.cc b/dune/solvers/test/multigridtest.cc
index 86c8e71fb096af17d597f857f1ad36a2c5d0ce59..4529b250b7284941dc1df10c894918cb045b2fc9 100644
--- a/dune/solvers/test/multigridtest.cc
+++ b/dune/solvers/test/multigridtest.cc
@@ -43,45 +43,13 @@ struct MultigridTestSuite
 
         bool passed = true;
 
-        typedef typename Dune::FieldMatrix<double, blocksize, blocksize> MatrixBlock;
-        typedef typename Dune::FieldVector<double, blocksize> VectorBlock;
-        typedef typename Dune::BCRSMatrix<MatrixBlock> Matrix;
-        typedef typename Dune::BlockVector<VectorBlock> Vector;
-        typedef typename Dune::BitSetVector<blocksize> BitVector;
+        using Problem =
+            SymmetricSampleProblem<1, typename GridType::LevelGridView>;
+        Problem p(grid.levelGridView(grid.maxLevel()));
 
-        typedef typename GridType::LevelGridView GridView;
-
-
-        const GridView gridView = grid.levelGridView(grid.maxLevel());
-
-        Matrix A;
-        constructPQ1Pattern(gridView, A);
-        A=0.0;
-        assemblePQ1Stiffness(gridView, A);
-
-        Vector u(A.N()), u_ex(A.N());
-        u = 0;
-        for (size_t i=0; i<u.size(); ++i)
-            for (size_t j=0; j<blocksize; ++j)
-            {
-                u_ex[i][j] = (1.0*rand())/RAND_MAX;
-//                A[i][i][j][j] += 0.5*std::abs(A[0][0][0][0]); // in case of no dirichlet values you can make the matrix pd hereby
-            }
-
-        Vector rhs(A.N());
-        A.mv(u_ex, rhs);
-
-        BitVector ignore(A.N());
-        ignore.unsetAll();
-        markBoundaryDOFs(gridView, ignore);
-
-        // set dirichlet values
-        for (size_t i=0; i<u.size(); ++i)
-            for (size_t j=0; j<blocksize; ++j)
-                if (ignore[i][j])
-                    u[i][j] = u_ex[i][j];
-
-        typedef EnergyNorm<Matrix, Vector> Norm;
+        typedef typename Problem::Vector Vector;
+        typedef typename Problem::Matrix Matrix;
+        typedef typename Problem::BitVector BitVector;
         typedef ::LoopSolver<Vector> Solver;
         typedef MultigridStep<Matrix, Vector, BitVector> MGStep;
         typedef MultigridTransfer<Vector, BitVector, Matrix> Transfer;
@@ -98,71 +66,51 @@ struct MultigridTestSuite
             transfer[i] = t;
         }
 
-        // we want to control errors with respect to the energy norm induced by the matrix
-        Norm energynorm(A);
-
         // set up smoothers and basesolver
         Smoother smoother, basesolver_step;
 
-        Norm basenorm(basesolver_step);
+        typename Problem::Norm basenorm(basesolver_step);
 
         Solver basesolver(&basesolver_step, 1, 1e-10, &basenorm, Solver::QUIET);
 
         // create iteration step and set all kinds of data
         MGStep mgStep;
         mgStep.setTransferOperators(transfer);
-        mgStep.setProblem(A,u,rhs);
+        mgStep.setProblem(p.A,p.u,p.rhs);
         mgStep.setSmoother(&smoother);
         mgStep.setMGType(1,3,3);
-        mgStep.ignoreNodes_ = &ignore;
+        mgStep.ignoreNodes_ = &p.ignore;
         mgStep.basesolver_  = &basesolver;
 
         // create loop solver
-        Solver solver(&mgStep, maxIterations, tol, &energynorm, Solver::FULL);
+        Solver solver(&mgStep, maxIterations, tol, &p.energyNorm, Solver::FULL);
 
         // solve problem
         solver.preprocess();
         solver.solve();
 
-        u = mgStep.getSol();
+        p.u = mgStep.getSol();
 
-        if (energynorm.diff(u,u_ex)>tol*10)
+        if (p.energyNorm.diff(p.u,p.u_ex)>tol*10)
         {
-            std::cout << "The MultigridStep did not produce a satisfactory result. ||u-u_ex||=" << energynorm.diff(u,u_ex) << std::endl;
-            std::cout << "||u_ex||=" << energynorm(u_ex) << std::endl;
+            std::cout << "The MultigridStep did not produce a satisfactory result. ||u-u_ex||=" << p.energyNorm.diff(p.u,p.u_ex) << std::endl;
+            std::cout << "||u_ex||=" << p.energyNorm(p.u_ex) << std::endl;
             passed = false;
         }
 
-
-        // now solve with the same operator but different rhs (and dirichlet values)
-
-        // create new exact solution
-        for (size_t i=0; i<u.size(); ++i)
-            for (size_t j=0; j<blocksize; ++j)
-                u_ex[i][j] = (1.0*rand())/RAND_MAX;
-
-        // ... and its corresponding rhs
-        A.mv(u_ex, rhs);
-
-        // set initial iterate (remember that the iterationStep member points to u)
-        u = 0.0;
-        // set dirichlet values
-        for (size_t i=0; i<u.size(); ++i)
-            for (size_t j=0; j<blocksize; ++j)
-                if (ignore[i][j])
-                    u[i][j] = u_ex[i][j];
+        p.randomize();
 
         // reset rhs in mgStep without calling preprocess subsequently
-        mgStep.setRhs(rhs);
+        mgStep.setRhs(p.rhs);
 
         solver.solve();
 
-        u = mgStep.getSol();
+        p.u = mgStep.getSol();
 
-        if (energynorm.diff(u,u_ex)>tol*10)
+        if (p.energyNorm.diff(p.u,p.u_ex)>tol*10)
         {
-            std::cout << "The MultigridStep did not produce a satisfactory result after calling setRhs(). ||u-u_ex||=" << energynorm.diff(u,u_ex) << std::endl;
-            std::cout << "||u_ex||=" << energynorm(u_ex) << std::endl;
+            std::cout << "The MultigridStep did not produce a satisfactory result after calling setRhs(). ||u-u_ex||=" << p.energyNorm.diff(p.u,p.u_ex) << std::endl;
+            std::cout << "||u_ex||=" << p.energyNorm(p.u_ex) << std::endl;
             passed = false;
         }
 
diff --git a/dune/solvers/test/umfpacksolvertest.cc b/dune/solvers/test/umfpacksolvertest.cc
index 6b4722308b2ee7993f883ed21f1de9daa7d1dc99..e70a37bbcf7dd52e1b12a739c533e1174f941ef5 100644
--- a/dune/solvers/test/umfpacksolvertest.cc
+++ b/dune/solvers/test/umfpacksolvertest.cc
@@ -34,52 +34,14 @@ struct UMFPackSolverTestSuite
 
     bool passed = true;
 
-    typedef typename Dune::FieldMatrix<double, blocksize, blocksize> MatrixBlock;
-    typedef typename Dune::FieldVector<double, blocksize> VectorBlock;
-    typedef typename Dune::BCRSMatrix<MatrixBlock> Matrix;
-    typedef typename Dune::BlockVector<VectorBlock> Vector;
-    typedef typename Dune::BitSetVector<blocksize> BitVector;
-    typedef EnergyNorm<Matrix, Vector> Norm;
-
-    const auto gridView = grid.leafGridView();
-
-    Matrix A;
-    constructPQ1Pattern(gridView, A);
-    A=0.0;
-    assemblePQ1Stiffness(gridView, A);
-
-    // Set up a random 'solution'
-    Vector u(A.N()), u_ex(A.N());
-    u = 0;
-    for (size_t i=0; i<u.size(); ++i)
-      for (size_t j=0; j<blocksize; ++j)
-      {
-        u_ex[i][j] = (1.0*rand())/RAND_MAX;
-//                A[i][i][j][j] += 0.5*std::abs(A[0][0][0][0]); // in case of no dirichlet values you can make the matrix pd hereby
-      }
-
-    // Construct right hand side corresponding to the 'solution'
-    Vector rhs(A.N());
-    A.mv(u_ex, rhs);
-
-    BitVector ignore(A.N());
-    ignore.unsetAll();
-    markBoundaryDOFs(gridView, ignore);
-
-    // set dirichlet values
-    for (size_t i=0; i<u.size(); ++i)
-      for (size_t j=0; j<blocksize; ++j)
-        if (ignore[i][j])
-          u[i][j] = u_ex[i][j];
-
-    // we want to control errors with respect to the energy norm induced by the matrix
-    Norm energynorm(A);
-
-    typedef Solvers::UMFPackSolver<Matrix,Vector> Solver;
-
-    // create loop solver
-    Solver solver(A,u,rhs);
-    solver.ignoreNodes_ = &ignore;
+    using Problem =
+        SymmetricSampleProblem<blocksize, typename GridType::LeafGridView>;
+    Problem p(grid.leafGridView());
+
+    typedef Solvers::UMFPackSolver<typename Problem::Matrix,
+                                   typename Problem::Vector> Solver;
+    Solver solver(p.A,p.u,p.rhs);
+    solver.ignoreNodes_ = &p.ignore;
 
     // solve problem
     solver.preprocess();
@@ -87,10 +49,10 @@ struct UMFPackSolverTestSuite
 
     //std::cout << u_ex << std::endl;
 
-    if (energynorm.diff(u,u_ex)>tol*10)
+    if (p.energyNorm.diff(p.u,p.u_ex)>tol*10)
     {
-      std::cout << "The UMFPackSolver did not produce a satisfactory result. ||u-u_ex||=" << energynorm.diff(u,u_ex) << std::endl;
-      std::cout << "||u_ex||=" << energynorm(u_ex) << std::endl;
+      std::cout << "The UMFPackSolver did not produce a satisfactory result. ||u-u_ex||=" << p.energyNorm.diff(p.u,p.u_ex) << std::endl;
+      std::cout << "||u_ex||=" << p.energyNorm(p.u_ex) << std::endl;
       passed = false;
     }