diff --git a/CHANGELOG.md b/CHANGELOG.md
index 87bb694078c4ada30103e76ec4f04a3fd8a74126..8ebe450ad46632a25bf64de707f75679c9ffbb5c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,7 @@
 # Master (will become release 2.8)
 
+- `UMFPackSolver` can now handle matrices and vectors with scalar entries.
+
 - CholmodSolver: Added `errorCode_` member to report errors and warnings during the matrix decomposition
 
 ## Deprecations and removals
diff --git a/dune/solvers/common/defaultbitvector.hh b/dune/solvers/common/defaultbitvector.hh
index c8f301148d7ce8d134929eabccc74d1de80742f8..0b7d7cf3c26c86c4d616b9c559d4a7eac109e671 100644
--- a/dune/solvers/common/defaultbitvector.hh
+++ b/dune/solvers/common/defaultbitvector.hh
@@ -18,11 +18,18 @@ namespace Solvers {
 
 namespace Imp {
 
+/** \brief Construct a bitvector type with a nesting that matches the one of a given vector
+ *
+ * The default implementation implements the case where the vector is a number type
+ * (to end recursion), and returns 'char' in such cases.
+ *
+ * \tparam Vector The vector types whose nesting shall be matched
+ */
 template<class Vector>
 struct DefaultBitVector
 {
-  static_assert(AlwaysFalse<Vector>::value, "No DefaultBitVector known for this type.");
-  using type = void;
+  static_assert(IsNumber<Vector>::value, "No DefaultBitVector known for this type.");
+  using type = char;
 };
 
 template<class T, int i>
diff --git a/dune/solvers/norms/twonorm.hh b/dune/solvers/norms/twonorm.hh
index a62d6586d4bb1bf85da0c58e95500fa4111200be..ad06cde33637aed8cc7dbb7667a7b41db197bc9a 100644
--- a/dune/solvers/norms/twonorm.hh
+++ b/dune/solvers/norms/twonorm.hh
@@ -50,7 +50,7 @@ class TwoNorm : public Norm<V>
                 typename VectorType::block_type block = f1[i];
                 block -= f2[i];
 
-                r += block.two_norm2();
+                r += Dune::Impl::asVector(block).two_norm2();
             }
 
             return std::sqrt(r);
diff --git a/dune/solvers/solvers/umfpacksolver.hh b/dune/solvers/solvers/umfpacksolver.hh
index 6071309190abf86846cadbed76f6013024fbf910..195d632cdca65ef41374d9e7d8ce018db4693d29 100644
--- a/dune/solvers/solvers/umfpacksolver.hh
+++ b/dune/solvers/solvers/umfpacksolver.hh
@@ -88,10 +88,16 @@ public:
       for (size_t i=0; i<matrix_->N(); i++)
       {
         auto const &ignore = this->ignore()[i];
-        if (ignore.none())
-          nonIgnoreRows.insert(i);
-        else if (not ignore.all())
-          DUNE_THROW(Dune::NotImplemented, "Individual blocks must be either ignored completely, or not at all");
+        if constexpr (std::is_convertible<decltype(ignore), bool>::value)
+        {
+          if (!ignore)
+            nonIgnoreRows.insert(i);
+        } else {
+          if (ignore.none())
+            nonIgnoreRows.insert(i);
+          else if (not ignore.all())
+            DUNE_THROW(Dune::NotImplemented, "Individual blocks must be either ignored completely, or not at all");
+        }
       }
 
       // Construct the solver
@@ -111,15 +117,25 @@ public:
       shortRowCount = 0;
       for (size_t i=0; i<matrix_->N(); i++)
       {
-        if (this->ignore()[i].all())
-          continue;
+        if constexpr (std::is_convertible<decltype(this->ignore()[i]), const bool>::value) {
+          if (this->ignore()[i])
+            continue;
+        } else {
+          if (this->ignore()[i].all())
+            continue;
+        }
 
         auto cIt    = (*matrix_)[i].begin();
         auto cEndIt = (*matrix_)[i].end();
 
         for (; cIt!=cEndIt; ++cIt)
-          if (this->ignore()[cIt.index()].all())
-            cIt->mmv((*x_)[cIt.index()], shortRhs[shortRowCount]);
+          if constexpr (std::is_convertible<decltype(this->ignore()[cIt.index()]), const bool>::value) {
+            if (this->ignore()[cIt.index()])
+              Dune::Impl::asMatrix(*cIt).mmv((*x_)[cIt.index()], shortRhs[shortRowCount]);
+          } else {
+            if (this->ignore()[cIt.index()].all())
+              Dune::Impl::asMatrix(*cIt).mmv((*x_)[cIt.index()], shortRhs[shortRowCount]);
+          }
 
         shortRowCount++;
       }
diff --git a/dune/solvers/test/common.hh b/dune/solvers/test/common.hh
index 7015536debd45974e770bb404e2b8fed4f9c5275..62c48754495926ae80e5d78ca825a545336a8914 100644
--- a/dune/solvers/test/common.hh
+++ b/dune/solvers/test/common.hh
@@ -18,7 +18,7 @@
 
 #include <dune/grid/utility/structuredgridfactory.hh>
 
-#if HAVE_UG
+#if HAVE_DUNE_UGGRID
 #include <dune/grid/uggrid.hh>
 #endif
 
@@ -26,6 +26,9 @@
 #include <dune/alugrid/grid.hh>
 #endif
 
+#include <dune/matrix-vector/addtodiagonal.hh>
+
+#include <dune/solvers/common/defaultbitvector.hh>
 #include <dune/solvers/norms/energynorm.hh>
 #include <dune/solvers/norms/twonorm.hh>
 
@@ -64,13 +67,6 @@ void constructPQ1Pattern(const GridView& gridView, Matrix& matrix)
     indices.exportIdx(matrix);
 }
 
-template<class T, int n, int m, class F>
-void addToDiagonal(Dune::FieldMatrix<T, n, m>& M, const F& x)
-{
-    for(int i=0; i<n; ++i)
-        M[i][i] += x;
-}
-
 template<class GridView, class Matrix>
 void assemblePQ1Stiffness(const GridView& gridView, Matrix& matrix)
 {
@@ -131,11 +127,11 @@ void assemblePQ1Stiffness(const GridView& gridView, Matrix& matrix)
                     int jGlobal = indexSet.subIndex(element, fe.localCoefficients().localKey(j).subEntity(), dim);
 
                     double zij = (gradients[i] * gradients[j]) * z;
-                    addToDiagonal(matrix[iGlobal][jGlobal], zij);
-                    addToDiagonal(matrix[jGlobal][iGlobal], zij);
+                    Dune::MatrixVector::addToDiagonal(matrix[iGlobal][jGlobal], zij);
+                    Dune::MatrixVector::addToDiagonal(matrix[jGlobal][iGlobal], zij);
                 }
                 double zii = (gradients[i] * gradients[i]) * z;
-                addToDiagonal(matrix[iGlobal][iGlobal], zii);
+                Dune::MatrixVector::addToDiagonal(matrix[iGlobal][iGlobal], zii);
             }
         }
     }
@@ -314,15 +310,19 @@ void markBoundaryDOFs(const GridView& gridView, BitVector& isBoundary)
     }
 }
 
+/**
+ *
+ * \tparam blocksize If this is zero, then double will be used instead of FieldVector/FieldMatrix
+ */
 template <size_t blocksize, class GridView, bool trivialDirichletOnly = true,
           bool makePositiveDefinitive = not trivialDirichletOnly>
 class SymmetricSampleProblem {
 public:
-  typedef typename Dune::FieldMatrix<double, blocksize, blocksize> MatrixBlock;
-  typedef typename Dune::FieldVector<double, blocksize> VectorBlock;
+  using MatrixBlock = std::conditional_t<blocksize==0, double, Dune::FieldMatrix<double, blocksize, blocksize> >;
+  using VectorBlock = std::conditional_t<blocksize==0, double, Dune::FieldVector<double, blocksize> >;
   typedef typename Dune::BCRSMatrix<MatrixBlock> Matrix;
   typedef typename Dune::BlockVector<VectorBlock> Vector;
-  typedef typename Dune::BitSetVector<blocksize> BitVector;
+  using BitVector = Dune::Solvers::DefaultBitVector_t<Vector>;
   typedef EnergyNorm<Matrix, Vector> Norm;
 
   SymmetricSampleProblem(GridView const& gridView) {
@@ -333,15 +333,21 @@ public:
     energyNorm.setMatrix(&A);
 
     ignore.resize(A.N());
-    ignore.unsetAll();
+    if constexpr (std::is_same_v<decltype(ignore),Dune::BitSetVector<blocksize> >)
+      ignore.unsetAll();
+    else
+      std::fill(ignore.begin(), ignore.end(), false);
     if (trivialDirichletOnly)
         markBoundaryDOFs(gridView, ignore);
     else {
         // Mark the first component only
-        Dune::BitSetVector<blocksize> boundaryNodes(A.N(), false);
+        BitVector boundaryNodes(A.N(), false);
         markBoundaryDOFs(gridView, boundaryNodes);
         for (size_t i=0; i < boundaryNodes.size(); ++i)
-            ignore[i][0] = boundaryNodes[i][0];
+            if constexpr (std::is_same_v<decltype(ignore),Dune::BitSetVector<blocksize> >)
+                ignore[i][0] = boundaryNodes[i][0];
+            else
+                ignore[i] = boundaryNodes[i];
     }
 
     u.resize(A.N());
@@ -357,10 +363,17 @@ public:
     // Set up a random 'solution'
     u = 0;
     for (size_t i = 0; i < u.size(); ++i)
-      for (size_t j = 0; j < blocksize; ++j) {
+      if constexpr (blocksize==0)
+      {
         if (makePositiveDefinitive)
-          A[i][i][j][j] += 0.5*std::abs(A[0][0][0][0]);
-        u_ex[i][j] = distribution(generator);
+          A[i][i] += 0.5*std::abs(A[0][0]);
+        u_ex[i] = distribution(generator);
+      } else {
+        for (size_t j = 0; j < blocksize; ++j) {
+          if (makePositiveDefinitive)
+            A[i][i][j][j] += 0.5*std::abs(A[0][0][0][0]);
+          u_ex[i][j] = distribution(generator);
+        }
       }
 
     // Construct right hand side corresponding to the 'solution'
@@ -368,9 +381,15 @@ public:
 
     // 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];
+      if constexpr (blocksize==0)
+      {
+        if (ignore[i])
+          u[i] = u_ex[i];
+      } else {
+        for (size_t j = 0; j < blocksize; ++j)
+          if (ignore[i][j])
+            u[i][j] = u_ex[i][j];
+      }
   }
 
   Matrix A;
diff --git a/dune/solvers/test/gssteptest.cc b/dune/solvers/test/gssteptest.cc
index 424ea189a240bf2e010a980a122aaa220fb285b4..9867e06525fe4c078e73d1e414fcaa7ce0423aba 100644
--- a/dune/solvers/test/gssteptest.cc
+++ b/dune/solvers/test/gssteptest.cc
@@ -250,7 +250,7 @@ bool checkWithSmallGrids(TestSuite& suite)
     passed = passed and checkWithGrid<Dune::YaspGrid<2, Dune::EquidistantOffsetCoordinates<double,2> > >(suite, 3);
     passed = passed and checkWithGrid<Dune::YaspGrid<3, Dune::EquidistantOffsetCoordinates<double,3> > >(suite, 1);
 
-#if HAVE_UG
+#if HAVE_DUNE_UGGRID
     passed = passed and checkWithGrid<Dune::UGGrid<2> >(suite, 2);
     passed = passed and checkWithGrid<Dune::UGGrid<3> >(suite, 1);
 #endif
diff --git a/dune/solvers/test/umfpacksolvertest.cc b/dune/solvers/test/umfpacksolvertest.cc
index 545170c12951d75ecc147b95b3e04ea3027d8cc5..c396b26aa60dd68fc6ffeb903b364e387dd767e1 100644
--- a/dune/solvers/test/umfpacksolvertest.cc
+++ b/dune/solvers/test/umfpacksolvertest.cc
@@ -68,8 +68,10 @@ int main(int argc, char** argv)
 
     bool passed = true;
 
+    UMFPackSolverTestSuite<0> testsuite0;
     UMFPackSolverTestSuite<1> testsuite1;
     UMFPackSolverTestSuite<2> testsuite2;
+    passed = checkWithStandardGrids(testsuite0);
     passed = checkWithStandardGrids(testsuite1);
     passed = checkWithStandardGrids(testsuite2);