diff --git a/dune/solvers/iterationsteps/mmgstep.cc b/dune/solvers/iterationsteps/mmgstep.cc
index b3faa68148950ad97fcd3db0bd5fd444449b1161..bf7bf050a77bc15935a0e8e47a4f650004813782 100644
--- a/dune/solvers/iterationsteps/mmgstep.cc
+++ b/dune/solvers/iterationsteps/mmgstep.cc
@@ -31,8 +31,19 @@ preprocess()
                 (*hasObstacleHierarchy_[i])[j][0]=false;
     }
 
+    recompute_.resize(this->mgTransfer_.size());
     for (size_t i=0; i<this->mgTransfer_.size(); i++)
-        dynamic_cast<TruncatedMGTransfer<VectorType>*>(this->mgTransfer_[i])->setRecomputeBitField(hasObstacleHierarchy_[i]);
+    {
+        recompute_[i].resize(hasObstacleHierarchy_[i]->size(), false);
+        dynamic_cast<TruncatedMGTransfer<VectorType>*>(this->mgTransfer_[i])->setRecomputeBitField(&recompute_[i]);
+    }
+
+    oldCritical_.resize(this->numLevels());
+    for (size_t i=0; i<this->numLevels(); i++)
+    {
+      oldCritical_[i].resize(hasObstacleHierarchy_[i]->size());
+      oldCritical_[i].unsetAll();
+    }
     
     // /////////////////////////////////////////////
     //   Set up base solver
@@ -183,6 +194,27 @@ void MonotoneMGStep<MatrixType, VectorType>::iterate()
             }
         }
 
+        ///////////////////////////////////////////////////////////////////////////////
+        // Compute the part of the coarse grid matrix that needs to be recomputed.
+        // There are two reasons why a matrix entry may need to be recomputed:
+        // 1) A corresponding fine grid vertex switched from critical to non-critical or vice versa
+        // 2) A corresponding fine grid matrix entry got recomputed
+        ///////////////////////////////////////////////////////////////////////////////
+
+        Dune::BitSetVector<dim> changed(critical.size());
+        for (size_t i=0; i<changed.size(); i++)
+          for (int j=0; j<dim; j++)
+            changed[i][j] = (critical[i][j] != oldCritical_[level][i][j]);
+
+        if (level < this->numLevels()-1 )
+          for (size_t i=0; i<changed.size(); i++)
+            for (int j=0; j<dim; j++)
+              changed[i][j] = (changed[i][j] || recompute_[level][i][j]);
+
+        dynamic_cast<TruncatedMGTransfer<VectorType>*>(this->mgTransfer_[level-1])->restrict(changed, recompute_[level-1]);
+
+        oldCritical_[level] = critical;
+
         // Set bitfield of nodes that will be truncated
         dynamic_cast<TruncatedMGTransfer<VectorType>*>(this->mgTransfer_[level-1])->setCriticalBitField(&critical);
      
diff --git a/dune/solvers/iterationsteps/mmgstep.hh b/dune/solvers/iterationsteps/mmgstep.hh
index cd373fa08a069cc3953054022e31920d0e34b52d..4c0244e990ee269332e557abb39475e70c50edba 100644
--- a/dune/solvers/iterationsteps/mmgstep.hh
+++ b/dune/solvers/iterationsteps/mmgstep.hh
@@ -64,6 +64,12 @@ protected:
     //! Bitfield hierarchy containing the coarse obstacle nodes
     std::vector<Dune::BitSetVector<dim>* > hasObstacleHierarchy_;
 
+    //! For each level specify the matrix lines that need reassembly
+    std::vector<Dune::BitSetVector<dim> > recompute_;
+
+    //! For each level specify dofs that changed status
+    std::vector<Dune::BitSetVector<dim> > oldCritical_;
+
     //! Hierarchy containing the obstacle values of the coarse obstacles
     std::vector<ObstacleVectorType*>  obstacleHierarchy_;
 };