diff --git a/dune/gfe/localgeodesicfefunction.hh b/dune/gfe/localgeodesicfefunction.hh
index 59f503adae592a10eb9310e7aa401a9183046a6c..3cbdc37024806f8218d9f0f7cdb2aec30845ac68 100644
--- a/dune/gfe/localgeodesicfefunction.hh
+++ b/dune/gfe/localgeodesicfefunction.hh
@@ -271,34 +271,18 @@ evaluateDerivative(const Dune::FieldVector<ctype, dim>& local, const TargetSpace
 
     AverageDistanceAssembler<TargetSpace> assembler(coefficients_, w);
 
-    Dune::FieldMatrix<RT,embeddedDim,embeddedDim> dFdq(0);
+    Dune::SymmetricMatrix<RT,embeddedDim> dFdq;
     assembler.assembleEmbeddedHessian(q,dFdq);
 
-    // ////////////////////////////////////
-    //   solve the system
-    //
     // We want to solve
     //     dFdq * x = rhs
-    // However as dFdq is defined in the embedding space it has a positive rank.
-    // Hence we use the orthonormal frame at q to get rid of its kernel.
-    // That means we instead solve
-    // O dFdq O^T O x = O rhs
-    // ////////////////////////////////////
+    // We use the Gram-Schmidt solver because we know that dFdq is rank-deficient.
 
     const int shortDim = TargetSpace::TangentVector::dimension;
 
     // the orthonormal frame
-    Dune::FieldMatrix<RT,shortDim,embeddedDim> O = q.orthonormalFrame();
-
-    // compute A = O dFDq O^T
-    Dune::FieldMatrix<RT,shortDim,shortDim> A;
-    for (int i=0; i<shortDim; i++)
-        for (int j=0; j<shortDim; j++) {
-            A[i][j] = 0;
-            for (int k=0; k<embeddedDim; k++)
-                for (int l=0; l<embeddedDim; l++)
-                    A[i][j] += O[i][k]*dFdq[k][l]*O[j][l];
-        }
+    Dune::FieldMatrix<RT,shortDim,embeddedDim> basis = q.orthonormalFrame();
+    GramSchmidtSolver<RT,shortDim,embeddedDim> gramSchmidtSolver(dFdq, basis);
 
     for (int i=0; i<dim; i++) {
 
@@ -306,14 +290,8 @@ evaluateDerivative(const Dune::FieldVector<ctype, dim>& local, const TargetSpace
         for (int j=0; j<embeddedDim; j++)
             rhs[j] = RHS[j][i];
 
-        Dune::FieldVector<RT,shortDim> shortRhs;
-        O.mv(rhs,shortRhs);
-
-        Dune::FieldVector<RT,shortDim> shortX;
-        A.solve(shortX,shortRhs);
-
         Dune::FieldVector<RT,embeddedDim> x;
-        O.mtv(shortX,x);
+        gramSchmidtSolver.solve(x, rhs);
 
         for (int j=0; j<embeddedDim; j++)
             result[j][i] = x[j];