diff --git a/dune/gfe/cosseratenergystiffness.hh b/dune/gfe/cosseratenergystiffness.hh
index ead0fa54cd5816b2e022bc61c48b6be73e4ea2aa..aafdca5a6983154dd90f452eb894f506281dca92 100644
--- a/dune/gfe/cosseratenergystiffness.hh
+++ b/dune/gfe/cosseratenergystiffness.hh
@@ -121,67 +121,6 @@ class CosseratEnergyLocalStiffness
         return result;
     }
 
-public:  // for testing
-    /** \brief Compute the derivative of the rotation (with respect to x), but wrt matrix coordinates
-        \param value Value of the gfe function at a certain point
-        \param derivative First derivative of the gfe function wrt x at that point, in quaternion coordinates
-        \param DR First derivative of the gfe function wrt x at that point, in matrix coordinates
-     */
-    static void computeDR(const RigidBodyMotion<field_type,3>& value,
-                          const Dune::FieldMatrix<field_type,7,gridDim>& derivative,
-                          Tensor3<field_type,3,3,gridDim>& DR)
-    {
-        // The LocalGFEFunction class gives us the derivatives of the orientation variable,
-        // but as a map into quaternion space.  To obtain matrix coordinates we use the
-        // chain rule, which means that we have to multiply the given derivative with
-        // the derivative of the embedding of the unit quaternion into the space of 3x3 matrices.
-        // This second derivative is almost given by the method getFirstDerivativesOfDirectors.
-        // However, since the directors of a given unit quaternion are the _columns_ of the
-        // corresponding orthogonal matrix, we need to invert the i and j indices
-        //
-        // So, if I am not mistaken, DR[i][j][k] contains \partial R_ij / \partial k
-        Tensor3<field_type,3 , 3, 4> dd_dq;
-        value.q.getFirstDerivativesOfDirectors(dd_dq);
-
-        DR = field_type(0);
-        for (int i=0; i<3; i++)
-            for (int j=0; j<3; j++)
-                for (int k=0; k<gridDim; k++)
-                    for (int l=0; l<4; l++)
-                        DR[i][j][k] += dd_dq[j][i][l] * derivative[l+3][k];
-
-    }
-
-    /** \brief Compute the derivative of the rotation (with respect to x), but wrt matrix coordinates
-        \param value Value of the gfe function at a certain point
-        \param derivative First derivative of the gfe function wrt x at that point, in quaternion coordinates
-        \param DR First derivative of the gfe function wrt x at that point, in matrix coordinates
-     */
-    static void computeDR(const Rotation<field_type,3>& value,
-                          const Dune::FieldMatrix<field_type,4,gridDim>& derivative,
-                          Tensor3<field_type,3,3,gridDim>& DR)
-    {
-        // The LocalGFEFunction class gives us the derivatives of the orientation variable,
-        // but as a map into quaternion space.  To obtain matrix coordinates we use the
-        // chain rule, which means that we have to multiply the given derivative with
-        // the derivative of the embedding of the unit quaternion into the space of 3x3 matrices.
-        // This second derivative is almost given by the method getFirstDerivativesOfDirectors.
-        // However, since the directors of a given unit quaternion are the _columns_ of the
-        // corresponding orthogonal matrix, we need to invert the i and j indices
-        //
-        // So, if I am not mistaken, DR[i][j][k] contains \partial R_ij / \partial k
-        Tensor3<field_type,3 , 3, 4> dd_dq;
-        value.getFirstDerivativesOfDirectors(dd_dq);
-
-        DR = field_type(0);
-        for (int i=0; i<3; i++)
-            for (int j=0; j<3; j++)
-                for (int k=0; k<gridDim; k++)
-                    for (int l=0; l<4; l++)
-                        DR[i][j][k] += dd_dq[j][i][l] * derivative[l][k];
-
-    }
-
 public:
 
     /** \brief Constructor with a set of material parameters
@@ -432,8 +371,7 @@ energy(const typename Basis::LocalView& localView,
         //  Note: we need it in matrix coordinates
         //////////////////////////////////////////////////////////
 
-        Tensor3<field_type,3,3,gridDim> DR;
-        computeDR(value, derivative, DR);
+        Tensor3<field_type,3,3,gridDim> DR = value.quaternionTangentToMatrixTangent(derivative);
 
         // Add the local energy density
         if (gridDim==2) {
@@ -598,8 +536,7 @@ energy(const typename Basis::LocalView& localView,
         //  Note: we need it in matrix coordinates
         //////////////////////////////////////////////////////////
 
-        Tensor3<field_type,3,3,gridDim> DR;
-        computeDR(orientationValue, orientationDerivative, DR);
+        Tensor3<field_type,3,3,gridDim> DR = orientationValue.quaternionTangentToMatrixTangent(orientationDerivative);
 
         // Add the local energy density
         if (gridDim==2) {
diff --git a/dune/gfe/nonplanarcosseratshellenergy.hh b/dune/gfe/nonplanarcosseratshellenergy.hh
index c1d098809c9b3faee26622d99d1bb2e768f67899..16c97c4f0cd595ab06f7bd550aa61622a4a02ab4 100644
--- a/dune/gfe/nonplanarcosseratshellenergy.hh
+++ b/dune/gfe/nonplanarcosseratshellenergy.hh
@@ -147,36 +147,6 @@ class NonplanarCosseratShellEnergy
     return result;
   }
 
-
-  /** \brief Compute the derivative of the rotation (with respect to x), but wrt matrix coordinates
-      \param value Value of the gfe function at a certain point
-      \param derivative First derivative of the gfe function wrt x at that point, in quaternion coordinates
-      \param DR First derivative of the gfe function wrt x at that point, in matrix coordinates
-   */
-  static void computeDR(const RigidBodyMotion<field_type,3>& value,
-                        const Dune::FieldMatrix<field_type,7,gridDim>& derivative,
-                        Tensor3<field_type,3,3,gridDim>& DR)
-  {
-    // The LocalGFEFunction class gives us the derivatives of the orientation variable,
-    // but as a map into quaternion space.  To obtain matrix coordinates we use the
-    // chain rule, which means that we have to multiply the given derivative with
-    // the derivative of the embedding of the unit quaternion into the space of 3x3 matrices.
-    // This second derivative is almost given by the method getFirstDerivativesOfDirectors.
-    // However, since the directors of a given unit quaternion are the _columns_ of the
-    // corresponding orthogonal matrix, we need to invert the i and j indices
-    //
-    // So, DR[i][j][k] contains \partial R_ij / \partial k
-    Tensor3<field_type,3 , 3, 4> dd_dq;
-    value.q.getFirstDerivativesOfDirectors(dd_dq);
-
-    DR = field_type(0);
-    for (int i=0; i<3; i++)
-      for (int j=0; j<3; j++)
-        for (int k=0; k<gridDim; k++)
-          for (int l=0; l<4; l++)
-            DR[i][j][k] += dd_dq[j][i][l] * derivative[l+3][k];
-  }
-
 public:
 
   /** \brief Constructor with a set of material parameters
@@ -329,8 +299,7 @@ energy(const typename Basis::LocalView& localView,
     value.q.matrix(R);
     auto RT = transpose(R);
 
-    Tensor3<field_type,3,3,gridDim> DR;
-    computeDR(value, derivative, DR);
+    Tensor3<field_type,3,3,gridDim> DR = value.quaternionTangentToMatrixTangent(derivative);
 
     //////////////////////////////////////////////////////////
     //  Fundamental forms and curvature
diff --git a/dune/gfe/rigidbodymotion.hh b/dune/gfe/rigidbodymotion.hh
index a68e796f2277b2ef07acac1dafb2e55b7ed8edd4..b4541e3e722dac0d7ec67098771043d1e2ee863b 100644
--- a/dune/gfe/rigidbodymotion.hh
+++ b/dune/gfe/rigidbodymotion.hh
@@ -284,6 +284,43 @@ public:
         return result;
     }
 
+        /** \brief Transform tangent vectors from quaternion representation to matrix representation
+     *
+     * This class represents rotations as unit quaternions, and therefore variations of rotations
+     * (i.e., tangent vector) are represented in quaternion space, too.  However, some applications
+     * require the tangent vectors as matrices. To obtain matrix coordinates we use the
+     * chain rule, which means that we have to multiply the given derivative with
+     * the derivative of the embedding of the unit quaternion into the space of 3x3 matrices.
+     * This second derivative is almost given by the method getFirstDerivativesOfDirectors.
+     * However, since the directors of a given unit quaternion are the _columns_ of the
+     * corresponding orthogonal matrix, we need to invert the i and j indices
+     *
+     * As a typical GFE assembler will require this for several tangent vectors at once,
+     * the implementation here is a vector one: It allows to treat several tangent vectors
+     * together, which have to come as the columns of the `derivative` parameter.
+     *
+     * So, if I am not mistaken, result[i][j][k] contains \partial R_ij / \partial k
+     *
+     * \param derivative Tangent vector in quaternion coordinates
+     * \returns DR Tangent vector in matrix coordinates
+     */
+    template <int blocksize>
+    Tensor3<T,3,3,blocksize> quaternionTangentToMatrixTangent(const Dune::FieldMatrix<T,7,blocksize>& derivative) const
+    {
+        Tensor3<T,3,3,blocksize> result = T(0);
+
+        Tensor3<T,3 , 3, 4> dd_dq;
+        q.getFirstDerivativesOfDirectors(dd_dq);
+
+        for (int i=0; i<3; i++)
+            for (int j=0; j<3; j++)
+                for (int k=0; k<blocksize; k++)
+                    for (int l=0; l<4; l++)
+                        result[i][j][k] += dd_dq[j][i][l] * derivative[l+3][k];
+
+        return result;
+    }
+
     /** \brief The Weingarten map */
     EmbeddedTangentVector weingarten(const EmbeddedTangentVector& z, const EmbeddedTangentVector& v) const {
 
diff --git a/dune/gfe/rotation.hh b/dune/gfe/rotation.hh
index e767e14776e49837220842138d81b1cdde1876fd..2ca609ed8c98312c084c5a0345824db4b9323134 100644
--- a/dune/gfe/rotation.hh
+++ b/dune/gfe/rotation.hh
@@ -671,6 +671,43 @@ public:
 
     }
 
+    /** \brief Transform tangent vectors from quaternion representation to matrix representation
+     *
+     * This class represents rotations as unit quaternions, and therefore variations of rotations
+     * (i.e., tangent vector) are represented in quaternion space, too.  However, some applications
+     * require the tangent vectors as matrices. To obtain matrix coordinates we use the
+     * chain rule, which means that we have to multiply the given derivative with
+     * the derivative of the embedding of the unit quaternion into the space of 3x3 matrices.
+     * This second derivative is almost given by the method getFirstDerivativesOfDirectors.
+     * However, since the directors of a given unit quaternion are the _columns_ of the
+     * corresponding orthogonal matrix, we need to invert the i and j indices
+     *
+     * As a typical GFE assembler will require this for several tangent vectors at once,
+     * the implementation here is a vector one: It allows to treat several tangent vectors
+     * together, which have to come as the columns of the `derivative` parameter.
+     *
+     * So, if I am not mistaken, result[i][j][k] contains \partial R_ij / \partial k
+     *
+     * \param derivative Tangent vector in quaternion coordinates
+     * \returns DR Tangent vector in matrix coordinates
+     */
+    template <int blocksize>
+    Tensor3<T,3,3,blocksize> quaternionTangentToMatrixTangent(const Dune::FieldMatrix<T,4,blocksize>& derivative) const
+    {
+        Tensor3<T,3,3,blocksize> result = T(0);
+
+        Tensor3<T,3 , 3, 4> dd_dq;
+        getFirstDerivativesOfDirectors(dd_dq);
+
+        for (int i=0; i<3; i++)
+            for (int j=0; j<3; j++)
+                for (int k=0; k<blocksize; k++)
+                    for (int l=0; l<4; l++)
+                        result[i][j][k] += dd_dq[j][i][l] * derivative[l][k];
+
+        return result;
+    }
+
     /** \brief Compute the derivative of the squared distance function with respect to the second argument
      *
      * The squared distance function is
diff --git a/test/rigidbodymotiontest.cc b/test/rigidbodymotiontest.cc
index 58d9f5c189b6bf19b43953b1a933de822d2b843a..2f39109d96ecc25b3553a176e2334d320b97948c 100644
--- a/test/rigidbodymotiontest.cc
+++ b/test/rigidbodymotiontest.cc
@@ -1,14 +1,14 @@
 #include "config.h"
 
+#include <dune/common/parallel/mpihelper.hh>
+
 #include <dune/geometry/type.hh>
 #include <dune/geometry/quadraturerules.hh>
 
-#include <dune/grid/uggrid.hh>
-
-#include <dune/functions/functionspacebases/lagrangebasis.hh>
+#include <dune/localfunctions/lagrange/pqkfactory.hh>
 
+#include <dune/gfe/localgeodesicfefunction.hh>
 #include <dune/gfe/rigidbodymotion.hh>
-#include <dune/gfe/cosseratenergystiffness.hh>
 
 #include "multiindex.hh"
 #include "valuefactory.hh"
@@ -75,9 +75,7 @@ void testDerivativeOfRotationMatrix(const std::vector<TargetSpace>& corners)
         // evaluate actual derivative
         Dune::FieldMatrix<double, TargetSpace::EmbeddedTangentVector::dimension, domainDim> derivative = f.evaluateDerivative(quadPos);
 
-        Tensor3<double,3,3,domainDim> DR;
-        typedef Dune::Functions::LagrangeBasis<typename UGGrid<domainDim>::LeafGridView,1> FEBasis;
-        CosseratEnergyLocalStiffness<FEBasis,3>::computeDR(f.evaluate(quadPos),derivative, DR);
+        Tensor3<double,3,3,domainDim> DR = f.evaluate(quadPos).quaternionTangentToMatrixTangent(derivative);
 
         // evaluate fd approximation of derivative
         Tensor3<double,3,3,domainDim> DR_fd = evaluateDerivativeFD(f,quadPos);