diff --git a/dune/gfe/unitvector.hh b/dune/gfe/unitvector.hh
index 2beb276ad15278b9ae5db7ab66a8318fc2e6389f..202f413792a3f6731b9773d7e2b242a1434d38d2 100644
--- a/dune/gfe/unitvector.hh
+++ b/dune/gfe/unitvector.hh
@@ -233,31 +233,31 @@ public:
 
         double sp = p.data_ * q.data_;
         
-        // The identity matrix
-        Dune::FieldMatrix<double,N,N> identity(0);
-        for (int i=0; i<N; i++)
-            identity[i][i] = 1;
-        
-        // The projection matrix onto the tangent space at b
-        Dune::FieldMatrix<double,N,N> projection;
+        // The projection matrix onto the tangent space at p and q
+        Dune::FieldMatrix<double,N,N> Pp, Pq;
         for (int i=0; i<N; i++)
-            for (int j=0; j<N; j++)
-                projection[i][j] = (i==j) - q.globalCoordinates()[i]*q.globalCoordinates()[j];
+            for (int j=0; j<N; j++) {
+                Pp[i][j] = (i==j) - p.globalCoordinates()[i]*p.globalCoordinates()[j];
+                Pq[i][j] = (i==j) - q.globalCoordinates()[i]*q.globalCoordinates()[j];
+            }
+            
+        Dune::FieldMatrix<double,N,N> PpPq;
+        Dune::FMatrixHelp::multMatrix(Pp,Pq,PpPq);
         
-        // The derivative of the projection matrix at b with respect to b
-        Dune::FieldMatrix<double,N,N> derivativeProjection;
-        for (int i=0; i<N; i++)
-            for (int j=0; j<N; j++)
-                derivativeProjection[i][j] = -sp*(i==j) - q.globalCoordinates()[i]*p.globalCoordinates()[j];
-
         Dune::FieldVector<double,N> pProjected = q.projectOntoTangentSpace(p.globalCoordinates());
+        Dune::FieldVector<double,N> qProjected = p.projectOntoTangentSpace(q.globalCoordinates());
+        
+        Dune::FieldMatrix<double,N,N> Pq_sp = Pq;
+        Pq_sp *= sp;
+        
+        Dune::FieldVector<double,N> PpPqp;
+        PpPq.mv(p.data_,PpPqp);
         
-        result = thirdDerivativeOfArcCosSquared(sp)  * Tensor3<double,N,N,N>::product(q.globalCoordinates(),p.globalCoordinates(),pProjected)
-                + secondDerivativeOfArcCosSquared(sp) * (Tensor3<double,N,N,N>::product(identity,pProjected)
-                                                         + Tensor3<double,N,N,N>::product(p.globalCoordinates(),projection)
-                                                         + Tensor3<double,N,N,N>::product(q.globalCoordinates(),derivativeProjection))
-               - derivativeOfArcCosSquared(sp)       * Tensor3<double,N,N,N>::product(identity,q.globalCoordinates())
-               - derivativeOfArcCosSquared(sp)       * Tensor3<double,N,N,N>::product(q.globalCoordinates(),identity);
+        result = thirdDerivativeOfArcCosSquared(sp)    * Tensor3<double,N,N,N>::product(qProjected,pProjected,pProjected)
+                 + secondDerivativeOfArcCosSquared(sp) * Tensor3<double,N,N,N>::product(PpPq,pProjected)
+                 + secondDerivativeOfArcCosSquared(sp) * Tensor3<double,N,N,N>::product(PpPqp,Pq)
+                 - secondDerivativeOfArcCosSquared(sp) * Tensor3<double,N,N,N>::product(qProjected,Pq_sp)
+                 - derivativeOfArcCosSquared(sp)       * Tensor3<double,N,N,N>::product(PpPq,qProjected);
                
         return result;
     }