diff --git a/src/rodsolver.cc b/src/rodsolver.cc
index 76377e17aff8477852c0d5cfaeff78eaa72007a5..83fd87e1adb920f8205e60e6e34a50993c6736b0 100644
--- a/src/rodsolver.cc
+++ b/src/rodsolver.cc
@@ -2,12 +2,17 @@
 
 #include <dune/istl/io.hh>
 
+#include <dune/disc/functions/p1function.hh>
+#include <dune/disc/miscoperators/laplace.hh>
+#include <dune/disc/operators/p1operator.hh>
+
 #include "../common/trustregiongsstep.hh"
 #include "../contact/src/contactmmgstep.hh"
 
 #include "../solver/iterativesolver.hh"
 
 #include "../common/energynorm.hh"
+#include "../common/h1seminorm.hh"
 
 #include "configuration.hh"
 #include "quaternion.hh"
@@ -52,7 +57,8 @@ void RodSolver<GridType>::setup(const GridType& grid,
                                 int nu1,
                                 int nu2,
                                 int baseIterations,
-                                double baseTolerance)
+                                double baseTolerance,
+                                bool instrumented)
 {
     using namespace Dune;
 
@@ -68,6 +74,7 @@ void RodSolver<GridType>::setup(const GridType& grid,
     nu2_                      = nu2;
     baseIt_                   = baseIterations;
     baseTolerance_            = baseTolerance;
+    instrumented_             = instrumented;
 
     int numLevels = grid_->maxLevel()+1;
 
@@ -117,16 +124,31 @@ void RodSolver<GridType>::setup(const GridType& grid,
     mmgStep->obstacles_         = &trustRegionObstacles_;
     mmgStep->verbosity_         = Solver::FULL;
 
+    // //////////////////////////////////////////////////////////////////////////////////////
+    //   Assemble a Laplace matrix to create a norm that's equivalent to the H1-norm
+    // //////////////////////////////////////////////////////////////////////////////////////
+    LeafP1Function<GridType,double> u(grid),f(grid);
+    LaplaceLocalStiffness<GridType,double> laplaceStiffness;
+    LeafP1OperatorAssembler<GridType,double,1>* A = new LeafP1OperatorAssembler<GridType,double,1>(grid);
+    A->assemble(laplaceStiffness,u,f);
+
+    typedef typename LeafP1OperatorAssembler<GridType,double,1>::RepresentationType LaplaceMatrixType;
 
+    if (h1SemiNorm_)
+        delete h1SemiNorm_;
 
-    EnergyNorm<MatrixType, CorrectionType>* energyNorm = new EnergyNorm<MatrixType, CorrectionType>(*mmgStep);
+    h1SemiNorm_ = new H1SemiNorm<CorrectionType>(**A);
 
     mmgSolver_ = new IterativeSolver<MatrixType, CorrectionType>(mmgStep,
                                                                  multigridIterations_,
                                                                  qpTolerance_,
-                                                                 energyNorm,
+                                                                 h1SemiNorm_,
                                                                  Solver::FULL);
 
+    // Write all intermediate solutions, if requested
+    if (instrumented_)
+        mmgSolver_->historyBuffer_ = "tmp/";
+
     // ////////////////////////////////////////////////////////////
     //    Create Hessian matrix and its occupation structure
     // ////////////////////////////////////////////////////////////
@@ -171,9 +193,22 @@ void RodSolver<GridType>::setup(const GridType& grid,
 template <class GridType>
 void RodSolver<GridType>::solve()
 {
+    using namespace Dune;
+
     double trustRegionRadius = initialTrustRegionRadius_;
 
+    // /////////////////////////////////////////////////////
+    //   Set up the log file, if requested
+    // /////////////////////////////////////////////////////
+    FILE* fp;
+    if (instrumented_) {
+
+        fp = fopen("statistics", "w");
+        if (!fp)
+            DUNE_THROW(IOError, "Couldn't open statistics file for writing!");
     
+    }
+
     // /////////////////////////////////////////////////////
     //   Trust-Region Solver
     // /////////////////////////////////////////////////////
@@ -193,18 +228,35 @@ void RodSolver<GridType>::solve()
         std::cout << "Rod energy: " <<rodAssembler_->computeEnergy(x_) << std::endl;
         rodAssembler_->assembleGradient(x_, rhs);
         rodAssembler_->assembleMatrix(x_, *hessianMatrix_);
-        
+#if 0
+        for (int j=0; j<hessianMatrix_->N(); j++) {
+
+            for (int k=0; k<hessianMatrix_->M(); k++) {
+
+                if (hessianMatrix_->exists(j,k)) {
+                    (*hessianMatrix_)[j][k] = 0;
+
+                    if (j==k)
+                        for (int l=0; l<6; l++)
+                            (*hessianMatrix_)[j][k][l][l] = 1;
+
+                }
+            }
+        }
+#endif   
         rhs *= -1;
 
+        //std::cout << "Gradient:\n" << rhs << std::endl;
+
         // Create trust-region obstacle on maxlevel
         setTrustRegionObstacles(trustRegionRadius,
                                 trustRegionObstacles_[grid_->maxLevel()]);
         
-        dynamic_cast<Dune::MultigridStep<MatrixType,CorrectionType>*>(mmgSolver_->iterationStep_)->setProblem(*hessianMatrix_, corr, rhs, grid_->maxLevel()+1);
+        dynamic_cast<MultigridStep<MatrixType,CorrectionType>*>(mmgSolver_->iterationStep_)->setProblem(*hessianMatrix_, corr, rhs, grid_->maxLevel()+1);
         
         mmgSolver_->preprocess();
         
-        dynamic_cast<Dune::MultigridStep<MatrixType,CorrectionType>*>(mmgSolver_->iterationStep_)->preprocess();
+        dynamic_cast<MultigridStep<MatrixType,CorrectionType>*>(mmgSolver_->iterationStep_)->preprocess();
         
         
         // /////////////////////////////
@@ -212,10 +264,77 @@ void RodSolver<GridType>::solve()
         // /////////////////////////////
         mmgSolver_->solve();
         
-        corr = dynamic_cast<Dune::MultigridStep<MatrixType,CorrectionType>*>(mmgSolver_->iterationStep_)->getSol();
+        corr = dynamic_cast<MultigridStep<MatrixType,CorrectionType>*>(mmgSolver_->iterationStep_)->getSol();
         
-        std::cout << "Correction: " << std::endl << corr << std::endl;
+        //std::cout << "Correction: " << std::endl << corr << std::endl;
+        
+        if (instrumented_) {
+
+            fprintf(fp, "Trust-region step: %d, trust-region radius: %g\n",
+                    i, trustRegionRadius);
+                    
+            // ///////////////////////////////////////////////////////////////
+            //   Compute and measure progress against the exact solution
+            //   for each trust region step
+            // ///////////////////////////////////////////////////////////////
+    
+            CorrectionType exactSolution = corr;
+
+            // Start from 0
+            double oldError = 0;
+            double totalConvRate = 1;
+            double convRate = 1;
+    
+            // Write statistics of the initial solution
+            // Compute the energy norm
+            oldError = h1SemiNorm_->compute(exactSolution);
+    
+            for (int j=0; j<multigridIterations_; j++) {
         
+                // read iteration from file
+                CorrectionType intermediateSol(grid_->size(1));
+                intermediateSol = 0;
+                char iSolFilename[100];
+                sprintf(iSolFilename, "tmp/intermediatesolution_%04d", j);
+                
+                FILE* fpInt = fopen(iSolFilename, "rb");
+                if (!fpInt)
+                    DUNE_THROW(IOError, "Couldn't open intermediate solution");
+                for (int k=0; k<intermediateSol.size(); k++)
+                    for (int l=0; l<blocksize; l++)
+                        fread(&intermediateSol[k][l], sizeof(double), 1, fpInt);
+                
+                fclose(fpInt);
+                //std::cout << "intermediateSol\n" << intermediateSol << std::endl;
+
+                // Compute errors
+                intermediateSol -= exactSolution;
+      
+                //std::cout << "error\n" << intermediateSol << std::endl;
+
+                // Compute the H1 norm
+                double error = h1SemiNorm_->compute(intermediateSol);
+
+                convRate = error / oldError;
+                totalConvRate *= convRate;
+                
+                if (error < 1e-12)
+                    break;
+                
+                printf("Iteration: %d  ", j);
+                printf("Errors:  error %g,  convergence Rate: %g,  total conv rate %g\n", 
+                       error, convRate, pow(totalConvRate, 1/((double)j+1)), 0);
+                fprintf(fp, "%d %g %g %g\n", j+1, error, convRate, pow(totalConvRate, 1/((double)j+1)));
+                
+                
+                oldError = error;
+                
+            }
+            
+            
+        }
+
+
         printf("infinity norm of the correction: %g\n", corr.infinity_norm());
         if (corr.infinity_norm() < 1e-5) {
             std::cout << "CORRECTION IS SMALL ENOUGH" << std::endl;
@@ -236,13 +355,11 @@ void RodSolver<GridType>::solve()
             // Add rotational correction
             Quaternion<double> qCorr = Quaternion<double>::exp(corr[j][3], corr[j][4], corr[j][5]);
             newIterate[j].q = newIterate[j].q.mult(qCorr);
-            //newIterate[j].q = qCorr.mult(newIterate[j].q);
             
         }
         
-        
+#if 0
         std::cout << "newIterate: \n";
-#if 1
         for (int j=0; j<newIterate.size(); j++)
             std::cout << newIterate[j] << std::endl;
 #endif     
@@ -296,5 +413,10 @@ void RodSolver<GridType>::solve()
         //  Write current energy
         std::cout << "--- Current energy: " << energy << " ---" << std::endl;
     }
-    
+
+    // //////////////////////////////////////////////
+    //   Close logfile
+    // //////////////////////////////////////////////
+    if (instrumented_)
+        fclose(fp);
 }
diff --git a/src/rodsolver.hh b/src/rodsolver.hh
index b9835c3ac99b056c6981e0cef977ba9db47d723b..df75c6bf1aee2483c0379177fd9f809ac63a9d29 100644
--- a/src/rodsolver.hh
+++ b/src/rodsolver.hh
@@ -6,6 +6,7 @@
 #include <dune/istl/bvector.hh>
 
 #include "../../common/boxconstraint.hh"
+#include "../common/h1seminorm.hh"
 #include "../../solver/iterativesolver.hh"
 
 #include "rodassembler.hh"
@@ -42,7 +43,8 @@ public:
                int nu1,
                int nu2,
                int baseIterations,
-               double baseTolerance);
+               double baseTolerance,
+               bool instrumented);
 
     void solve();
 
@@ -104,6 +106,13 @@ protected:
 
     /** \brief The Dirichlet nodes on all levels */
     std::vector<Dune::BitField> dirichletNodes_;
+
+    /** \brief The norm used to measure multigrid convergence */
+    H1SemiNorm<CorrectionType>* h1SemiNorm_;
+    
+    /** \brief If set to true we log convergence speed and other stuff */
+    bool instrumented_;
+
 };
 
 #include "rodsolver.cc"