diff --git a/dune/solvers/solvers/umfpacksolver.hh b/dune/solvers/solvers/umfpacksolver.hh
index d98a7dac89e38b31d2ea5139e4d20351028b1c4d..1c1becd675286229ae372210b6c83ce5069f472c 100644
--- a/dune/solvers/solvers/umfpacksolver.hh
+++ b/dune/solvers/solvers/umfpacksolver.hh
@@ -68,7 +68,7 @@ public:
   virtual void solve()
   {
     // We may use the original rhs, but ISTL modifies it, so we need a non-const type here
-    VectorType modifiedRhs = *rhs_;
+    VectorType mutableRhs = *rhs_;
 
     if (not this->ignoreNodes_)
     {
@@ -78,49 +78,67 @@ public:
       Dune::InverseOperatorResult statistics;
       Dune::UMFPack<MatrixType> solver(*matrix_);
       solver.setOption(UMFPACK_PRL, 0);   // no output at all
-      solver.apply(*x_, modifiedRhs, statistics);
+      solver.apply(*x_, mutableRhs, statistics);
 
     }
     else
     {
-      MatrixType modifiedStiffness = *matrix_;
-      //Dune::printmatrix(std::cout, modifiedStiffness, "mod stiffness", "--");
-
-      ///////////////////////////////////////////
-      //   Modify Dirichlet rows
-      ///////////////////////////////////////////
+      ///////////////////////////////////////////////////////////////////////////////////////////
+      //  Extract the set of matrix rows that do not correspond to ignored degrees of freedom.
+      //  Unfortunately, not all cases are handled by the ISTL UMFPack solver.  Currently,
+      //  you can only remove complete block rows.  If a block is only partially ignored,
+      //  the dune-istl UMFPack solver cannot do it, and the code here will throw an exception.
+      //  All this can be fixed, but it needs going into the istl UMFPack code.
+      ///////////////////////////////////////////////////////////////////////////////////////////
+      std::set<std::size_t> nonIgnoreRows;
+      for (size_t i=0; i<matrix_->N(); i++)
+      {
+        auto ignoreCount = (*this->ignoreNodes_)[i].count();
+        if (ignoreCount==0)
+          nonIgnoreRows.insert(i);
+        else if (ignoreCount!=blocksize)
+          DUNE_THROW(Dune::NotImplemented, "Individual blocks must be either ignored completely, or not at all");
+      }
 
-      for (size_t j=0; j<modifiedStiffness.N(); j++)
+      // Construct the solver
+      Dune::InverseOperatorResult statistics;
+      Dune::UMFPack<MatrixType> solver;
+      solver.setOption(UMFPACK_PRL, 0);   // no output at all
+      // We eliminate all rows and columns(!) from the matrix that correspond to ignored degrees of freedom.
+      // Here is where the sparse LU decomposition is happenening.
+      solver.setSubMatrix(*matrix_,nonIgnoreRows);
+
+      // We need to modify the rhs vector by static condensation.
+      VectorType shortRhs(nonIgnoreRows.size());
+      int shortRowCount=0;
+      for (auto it = nonIgnoreRows.begin(); it!=nonIgnoreRows.end(); ++shortRowCount, ++it)
+        shortRhs[shortRowCount] = mutableRhs[*it];
+
+      shortRowCount = 0;
+      for (size_t i=0; i<matrix_->N(); i++)
       {
-        auto cIt    = modifiedStiffness[j].begin();
-        auto cEndIt = modifiedStiffness[j].end();
+        if ((*this->ignoreNodes_)[i][0])
+          continue;
+
+        auto cIt    = (*matrix_)[i].begin();
+        auto cEndIt = (*matrix_)[i].end();
 
         for (; cIt!=cEndIt; ++cIt)
-        {
-          for (int k=0; k<blocksize; k++)
-            if ((*this->ignoreNodes_)[j][k])
-            {
-              (*cIt)[k] = 0;
-              if (cIt.index()==j)
-                (*cIt)[k][k] = 1.0;
-            }
-
-        }
-
-        for (int k=0; k<blocksize; k++)
-          if ((*this->ignoreNodes_)[j][k])
-            modifiedRhs[j][k] = (*x_)[j][k];
+          if ((*this->ignoreNodes_)[cIt.index()][0])
+            cIt->mmv((*x_)[cIt.index()], shortRhs[shortRowCount]);
+
+        shortRowCount++;
       }
 
-      //Dune::printmatrix(std::cout, modifiedStiffness, "mod stiffness", "--");
+      // Solve the reduced system
+      VectorType shortX(nonIgnoreRows.size());
+      solver.apply(shortX, shortRhs, statistics);
+
+      // Blow up the solution vector
+      shortRowCount=0;
+      for (auto it = nonIgnoreRows.begin(); it!=nonIgnoreRows.end(); ++shortRowCount, ++it)
+        (*x_)[*it] = shortX[shortRowCount];
 
-      /////////////////////////////////////////////////////////////////
-      //  Solve the system
-      /////////////////////////////////////////////////////////////////
-      Dune::InverseOperatorResult statistics;
-      Dune::UMFPack<MatrixType> solver(modifiedStiffness);
-      solver.setOption(UMFPACK_PRL, 0);   // no output at all
-      solver.apply(*x_, modifiedRhs, statistics);
     }
   }