diff --git a/src/quaternion.hh b/src/quaternion.hh
index a09525b711409b88e849d1beccbdac2594832034..1a2294fd625c585190264c15e15f32e6513fc0d4 100644
--- a/src/quaternion.hh
+++ b/src/quaternion.hh
@@ -9,12 +9,6 @@
 template <class T>
 class Quaternion : public Dune::FieldVector<T,4>
 {
-
-    /** \brief Computes sin(x/2) / x without getting unstable for small x */
-    static T sincHalf(const T& x) {
-        return (x < 1e-4) ? 0.5 + (x*x/48) : std::sin(x/2)/x;
-    }
-
 public:
 
     /** \brief Default constructor */
@@ -63,148 +57,6 @@ public:
         return id;
     }
 
-    /** \brief The exponential map from \f$ \mathfrak{so}(3) \f$ to \f$ SO(3) \f$
-     */
-    static Quaternion<T> exp(const Dune::FieldVector<T,3>& v) {
-        return exp(v[0], v[1], v[2]);
-    }
-
-    /** \brief The exponential map from \f$ \mathfrak{so}(3) \f$ to \f$ SO(3) \f$
-     */
-    static Quaternion<T> exp(const T& v0, const T& v1, const T& v2) {
-        Quaternion<T> q;
-
-        T normV = std::sqrt(v0*v0 + v1*v1 + v2*v2);
-
-        // Stabilization for small |v| due to Grassia
-        T sin = sincHalf(normV);
-
-        // if normV == 0 then q = (0,0,0,1)
-        assert(!isnan(sin));
-            
-        q[0] = sin * v0;
-        q[1] = sin * v1;
-        q[2] = sin * v2;
-        q[3] = std::cos(normV/2);
-
-        return q;
-    }
-
-    static Dune::FieldMatrix<T,4,3> Dexp(const Dune::FieldVector<T,3>& v) {
-
-        Dune::FieldMatrix<T,4,3> result(0);
-        T norm = v.two_norm();
-        
-        for (int i=0; i<3; i++) {
-
-            for (int m=0; m<3; m++) {
-                
-                result[m][i] = (norm==0) 
-                    /** \todo Isn't there a better way to implement this stably? */
-                    ? 0.5 * (i==m) 
-                    : 0.5 * std::cos(norm/2) * v[i] * v[m] / (norm*norm) + sincHalf(norm) * ( (i==m) - v[i]*v[m]/(norm*norm));
-
-            }
-
-            result[3][i] = - 0.5 * sincHalf(norm) * v[i];
-
-        }
-        return result;
-    }
-
-    static void DDexp(const Dune::FieldVector<T,3>& v,
-                      Dune::array<Dune::FieldMatrix<T,3,3>, 4>& result) {
-
-        T norm = v.two_norm();
-        if (norm==0) {
-
-            for (int m=0; m<4; m++)
-                result[m] = 0;
-
-            for (int i=0; i<3; i++)
-                result[3][i][i] = -0.25;
-
-
-        } else {
-
-            for (int i=0; i<3; i++) {
-                
-                for (int j=0; j<3; j++) {
-                    
-                    for (int m=0; m<3; m++) {
-                        
-                        result[m][i][j] = -0.25*std::sin(norm/2)*v[i]*v[j]*v[m]/(norm*norm*norm)
-                            + ((i==j)*v[m] + (j==m)*v[i] + (i==m)*v[j] - 3*v[i]*v[j]*v[m]/(norm*norm))
-                            * (0.5*std::cos(norm/2) - sincHalf(norm)) / (norm*norm);
-                        
-
-                    }
-
-                    result[3][i][j] = -0.5/(norm*norm)
-                        * ( 0.5*std::cos(norm/2)*v[i]*v[j] + std::sin(norm/2) * ((i==j)*norm - v[i]*v[j]/norm));
-
-                }
-
-            }
-
-        }
-
-    }
-
-    /** \brief The inverse of the exponential map */
-    static Dune::FieldVector<T,3> expInv(const Quaternion<T>& q) {
-        // Compute v = exp^{-1} q
-        // Due to numerical dirt, q[3] may be larger than 1. 
-        // In that case, use 1 instead of q[3].
-        Dune::FieldVector<T,3> v;
-        if (q[3] > 1.0) {
-
-            v = 0;
-
-        } else {
-            
-            T invSinc = 1/sincHalf(2*std::acos(q[3]));
-            
-            v[0] = q[0] * invSinc;
-            v[1] = q[1] * invSinc;
-            v[2] = q[2] * invSinc;
-
-        }
-        return v;
-    }
-
-    /** \brief The derivative of the inverse of the exponential map, evaluated at q */
-    static Dune::FieldMatrix<T,3,4> DexpInv(const Quaternion<T>& q) {
-        
-        // Compute v = exp^{-1} q
-        Dune::FieldVector<T,3> v = expInv(q);
-
-        // The derivative of exp at v
-        Dune::FieldMatrix<T,4,3> A = Dexp(v);
-
-        // Compute the Moore-Penrose pseudo inverse  A^+ = (A^T A)^{-1} A^T
-        Dune::FieldMatrix<T,3,3> ATA;
-
-        for (int i=0; i<3; i++)
-            for (int j=0; j<3; j++) {
-                ATA[i][j] = 0;
-                for (int k=0; k<4; k++)
-                    ATA[i][j] += A[k][i] * A[k][j];
-            }
-
-        ATA.invert();
-
-        Dune::FieldMatrix<T,3,4> APseudoInv;
-        for (int i=0; i<3; i++)
-            for (int j=0; j<4; j++) {
-                APseudoInv[i][j] = 0;
-                for (int k=0; k<3; k++)
-                    APseudoInv[i][j] += ATA[i][k] * A[j][k];
-            }
-
-        return APseudoInv;
-    }
-
     /** \brief Right quaternion multiplication */
     Quaternion<T> mult(const Quaternion<T>& other) const {
         Quaternion<T> q;
@@ -295,191 +147,6 @@ public:
 
     }
 
-    static Dune::FieldVector<T,3> difference(const Quaternion<T>& a, const Quaternion<T>& b) {
-
-        Quaternion<T> diff = a;
-        diff.invert();
-        diff = diff.mult(b);
-
-        // Compute the geodesical distance between a and b on SO(3)
-        // Due to numerical dirt, diff[3] may be larger than 1. 
-        // In that case, use 1 instead of diff[3].
-        Dune::FieldVector<T,3> v;
-        if (diff[3] > 1.0) {
-
-            v = 0;
-
-        } else {
-            
-            T dist = 2*std::acos( std::min(diff[3],1.0) );
-            
-            T invSinc = 1/sincHalf(dist);
-            
-            // Compute difference on T_a SO(3)
-            v[0] = diff[0] * invSinc;
-            v[1] = diff[1] * invSinc;
-            v[2] = diff[2] * invSinc;
-
-        }
-
-        return v;
-    }
-
-    /** \brief Interpolate between two rotations */
-    static Quaternion<T> interpolate(const Quaternion<T>& a, const Quaternion<T>& b, double omega) {
-
-        // Compute difference on T_a SO(3)
-        Dune::FieldVector<T,3> v = difference(a,b);
-
-        v *= omega;
-
-        return a.mult(exp(v[0], v[1], v[2]));
-    }
-
-    /** \brief Interpolate between two rotations 
-        \param omega must be between 0 and 1
-        \todo I'd say this method is incorrect and is other one is correct.
-        The solver works much better with this one, though.   I don't get it.
-    */
-    static Quaternion<T> interpolateDerivative(const Quaternion<T>& a, const Quaternion<T>& b, 
-                                               double omega) {
-        Quaternion<T> result(0);
-
-        // Compute difference on T_a SO(3)
-        Dune::FieldVector<double,3> xi = difference(a,b);
-
-        Dune::FieldVector<double,3> v = xi;
-        v *= omega;
-        
-        // //////////////////////////////////////////////////////////////
-        //   v now contains the derivative at 'a'.  The derivative at
-        //   the requested site is v pushed forward by Dexp.
-        // /////////////////////////////////////////////////////////////
-
-        Dune::FieldMatrix<double,4,3> diffExp = Quaternion<double>::Dexp(v);
-
-        diffExp.umv(xi,result);
-
-        return a.mult(result);
-    }
-
-    /** \brief Interpolate between two rotations 
-        \param omega must be between 0 and 1
-    */
-    static Quaternion<T> interpolateDerivative(const Quaternion<T>& a, const Quaternion<T>& b, 
-                                               double omega, double intervalLength) {
-        Quaternion<T> result(0);
-
-        // Compute difference on T_a SO(3)
-        Dune::FieldVector<double,3> xi = difference(a,b);
-
-        xi /= intervalLength;
-
-        Dune::FieldVector<double,3> v = xi;
-        v *= omega;
-        
-        // //////////////////////////////////////////////////////////////
-        //   v now contains the derivative at 'a'.  The derivative at
-        //   the requested site is v pushed forward by Dexp.
-        // /////////////////////////////////////////////////////////////
-
-        Dune::FieldMatrix<double,4,3> diffExp = Quaternion<double>::Dexp(v);
-
-        diffExp.umv(xi,result);
-
-        return a.mult(result);
-    }
-
-    /** \brief Return the corresponding orthogonal matrix */
-    void matrix(Dune::FieldMatrix<T,3,3>& m) const {
-
-        m[0][0] = (*this)[0]*(*this)[0] - (*this)[1]*(*this)[1] - (*this)[2]*(*this)[2] + (*this)[3]*(*this)[3];
-        m[0][1] = 2 * ( (*this)[0]*(*this)[1] - (*this)[2]*(*this)[3] );
-        m[0][2] = 2 * ( (*this)[0]*(*this)[2] + (*this)[1]*(*this)[3] );
-
-        m[1][0] = 2 * ( (*this)[0]*(*this)[1] + (*this)[2]*(*this)[3] );
-        m[1][1] = - (*this)[0]*(*this)[0] + (*this)[1]*(*this)[1] - (*this)[2]*(*this)[2] + (*this)[3]*(*this)[3];
-        m[1][2] = 2 * ( -(*this)[0]*(*this)[3] + (*this)[1]*(*this)[2] );
-
-        m[2][0] = 2 * ( (*this)[0]*(*this)[2] - (*this)[1]*(*this)[3] );
-        m[2][1] = 2 * ( (*this)[0]*(*this)[3] + (*this)[1]*(*this)[2] );
-        m[2][2] = - (*this)[0]*(*this)[0] - (*this)[1]*(*this)[1] + (*this)[2]*(*this)[2] + (*this)[3]*(*this)[3];
-
-    }
-
-    /** \brief Set unit quaternion from orthogonal matrix 
-
-    We tacitly assume that the matrix really is orthogonal */
-    void set(const Dune::FieldMatrix<T,3,3>& m) {
-
-        // Easier writing
-        Dune::FieldVector<T,4>& p = (*this);
-        // The following equations for the derivation of a unit quaternion from a rotation
-        // matrix comes from 'E. Salamin, Application of Quaternions to Computation with
-        // Rotations, Technical Report, Stanford, 1974'
-
-        p[0] = (1 + m[0][0] - m[1][1] - m[2][2]) / 4;
-        p[1] = (1 - m[0][0] + m[1][1] - m[2][2]) / 4;
-        p[2] = (1 - m[0][0] - m[1][1] + m[2][2]) / 4;
-        p[3] = (1 + m[0][0] + m[1][1] + m[2][2]) / 4;
-
-        // avoid rounding problems
-        if (p[0] >= p[1] && p[0] >= p[2] && p[0] >= p[3]) {
-
-            p[0] = std::sqrt(p[0]);
-
-            // r_x r_y = (R_12 + R_21) / 4
-            p[1] = (m[0][1] + m[1][0]) / 4 / p[0];
-
-            // r_x r_z = (R_13 + R_31) / 4
-            p[2] = (m[0][2] + m[2][0]) / 4 / p[0];
-
-            // r_0 r_x = (R_32 - R_23) / 4
-            p[3] = (m[2][1] - m[1][2]) / 4 / p[0]; 
-
-        } else if (p[1] >= p[0] && p[1] >= p[2] && p[1] >= p[3]) {
-
-            p[1] = std::sqrt(p[1]);
-
-            // r_x r_y = (R_12 + R_21) / 4
-            p[0] = (m[0][1] + m[1][0]) / 4 / p[1];
-
-            // r_y r_z = (R_23 + R_32) / 4
-            p[2] = (m[1][2] + m[2][1]) / 4 / p[1];
-
-            // r_0 r_y = (R_13 - R_31) / 4
-            p[3] = (m[0][2] - m[2][0]) / 4 / p[1]; 
-
-        } else if (p[2] >= p[0] && p[2] >= p[1] && p[2] >= p[3]) {
-
-            p[2] = std::sqrt(p[2]);
-
-            // r_x r_z = (R_13 + R_31) / 4
-            p[0] = (m[0][2] + m[2][0]) / 4 / p[2];
-
-            // r_y r_z = (R_23 + R_32) / 4
-            p[1] = (m[1][2] + m[2][1]) / 4 / p[2];
-
-            // r_0 r_z = (R_21 - R_12) / 4
-            p[3] = (m[1][0] - m[0][1]) / 4 / p[2]; 
-
-        } else {
-
-            p[3] = std::sqrt(p[3]);
-
-            // r_0 r_x = (R_32 - R_23) / 4
-            p[0] = (m[2][1] - m[1][2]) / 4 / p[3];
-
-            // r_0 r_y = (R_13 - R_31) / 4
-            p[1] = (m[0][2] - m[2][0]) / 4 / p[3];
-
-            // r_0 r_z = (R_21 - R_12) / 4
-            p[2] = (m[1][0] - m[0][1]) / 4 / p[3]; 
-
-        }
-
-    }
-
     /** \brief Create three vectors which form an orthonormal basis of \mathbb{H} together
         with this one.
 
@@ -509,6 +176,8 @@ public:
 
         return r;
     }
+    
+
 };
 
 #endif
diff --git a/src/rodassembler.cc b/src/rodassembler.cc
index 491141c2f441d60ead7f409443a0bbebfddabc34..cfd9d5fda026db13c83bd710bf92fd44392d6e76 100644
--- a/src/rodassembler.cc
+++ b/src/rodassembler.cc
@@ -73,7 +73,7 @@ energy(const Entity& element,
 
 template <class GridType, class RT>
 void RodLocalStiffness<GridType, RT>::
-interpolationDerivative(const Quaternion<RT>& q0, const Quaternion<RT>& q1, double s,
+interpolationDerivative(const Rotation<3,RT>& q0, const Rotation<3,RT>& q1, double s,
                         Dune::array<Quaternion<double>,6>& grad)
 {
     // Clear output array
@@ -83,18 +83,18 @@ interpolationDerivative(const Quaternion<RT>& q0, const Quaternion<RT>& q1, doub
     // The derivatives with respect to w^1
 
     // Compute q_1^{-1}q_0
-    Quaternion<RT> q1InvQ0 = q1;
+    Rotation<3,RT> q1InvQ0 = q1;
     q1InvQ0.invert();
     q1InvQ0 = q1InvQ0.mult(q0);
 
     {
     // Compute v = (1-s) \exp^{-1} ( q_1^{-1} q_0)
-    Dune::FieldVector<RT,3> v = Quaternion<RT>::expInv(q1InvQ0);
+        Dune::FieldVector<RT,3> v = Rotation<3,RT>::expInv(q1InvQ0);
     v *= (1-s);
 
-    Dune::FieldMatrix<RT,4,3> dExp_v = Quaternion<RT>::Dexp(v);
+    Dune::FieldMatrix<RT,4,3> dExp_v = Rotation<3,RT>::Dexp(v);
 
-    Dune::FieldMatrix<RT,3,4> dExpInv = Quaternion<RT>::DexpInv(q1InvQ0);
+    Dune::FieldMatrix<RT,3,4> dExpInv = Rotation<3,RT>::DexpInv(q1InvQ0);
 
     Dune::FieldMatrix<RT,4,4> mat(0);
     for (int i=0; i<4; i++)
@@ -120,18 +120,18 @@ interpolationDerivative(const Quaternion<RT>& q0, const Quaternion<RT>& q1, doub
     // The derivatives with respect to w^1
 
     // Compute q_0^{-1}
-    Quaternion<RT> q0InvQ1 = q0;
+    Rotation<3,RT> q0InvQ1 = q0;
     q0InvQ1.invert();
     q0InvQ1 = q0InvQ1.mult(q1);
 
     {
     // Compute v = s \exp^{-1} ( q_0^{-1} q_1)
-    Dune::FieldVector<RT,3> v = Quaternion<RT>::expInv(q0InvQ1);
+        Dune::FieldVector<RT,3> v = Rotation<3,RT>::expInv(q0InvQ1);
     v *= s;
 
-    Dune::FieldMatrix<RT,4,3> dExp_v = Quaternion<RT>::Dexp(v);
+    Dune::FieldMatrix<RT,4,3> dExp_v = Rotation<3,RT>::Dexp(v);
 
-    Dune::FieldMatrix<RT,3,4> dExpInv = Quaternion<RT>::DexpInv(q0InvQ1);
+    Dune::FieldMatrix<RT,3,4> dExpInv = Rotation<3,RT>::DexpInv(q0InvQ1);
 
     Dune::FieldMatrix<RT,4,4> mat(0);
     for (int i=0; i<4; i++)
@@ -158,7 +158,7 @@ interpolationDerivative(const Quaternion<RT>& q0, const Quaternion<RT>& q1, doub
 
 template <class GridType, class RT>
 void RodLocalStiffness<GridType, RT>::
-interpolationVelocityDerivative(const Quaternion<RT>& q0, const Quaternion<RT>& q1, double s,
+interpolationVelocityDerivative(const Rotation<3,RT>& q0, const Rotation<3,RT>& q1, double s,
                                 double intervalLength, Dune::array<Quaternion<double>,6>& grad)
 {
     // Clear output array
@@ -166,20 +166,20 @@ interpolationVelocityDerivative(const Quaternion<RT>& q0, const Quaternion<RT>&
         grad[i] = 0;
 
     // Compute q_0^{-1}
-    Quaternion<RT> q0Inv = q0;
+    Rotation<3,RT> q0Inv = q0;
     q0Inv.invert();
 
 
     // Compute v = s \exp^{-1} ( q_0^{-1} q_1)
-    Dune::FieldVector<RT,3> v = Quaternion<RT>::expInv(q0Inv.mult(q1));
+    Dune::FieldVector<RT,3> v = Rotation<3,RT>::expInv(q0Inv.mult(q1));
     v *= s/intervalLength;
 
-    Dune::FieldMatrix<RT,4,3> dExp_v = Quaternion<RT>::Dexp(v);
+    Dune::FieldMatrix<RT,4,3> dExp_v = Rotation<3,RT>::Dexp(v);
 
     Dune::array<Dune::FieldMatrix<RT,3,3>, 4> ddExp;
-    Quaternion<RT>::DDexp(v, ddExp);
+    Rotation<3,RT>::DDexp(v, ddExp);
 
-    Dune::FieldMatrix<RT,3,4> dExpInv = Quaternion<RT>::DexpInv(q0Inv.mult(q1));
+    Dune::FieldMatrix<RT,3,4> dExpInv = Rotation<3,RT>::DexpInv(q0Inv.mult(q1));
 
     Dune::FieldMatrix<RT,4,4> mat(0);
     for (int i=0; i<4; i++)
@@ -199,7 +199,7 @@ interpolationVelocityDerivative(const Quaternion<RT>& q0, const Quaternion<RT>&
             dw[j] = 0.5*(i==j);  // dExp_v_0[j][i];
 
         // \xi = \exp^{-1} q_0^{-1} q_1
-        Dune::FieldVector<RT,3> xi = Quaternion<RT>::expInv(q0Inv.mult(q1));
+        Dune::FieldVector<RT,3> xi = Rotation<3,RT>::expInv(q0Inv.mult(q1));
 
         Quaternion<RT> addend0;
         addend0 = 0;
@@ -214,7 +214,7 @@ interpolationVelocityDerivative(const Quaternion<RT>& q0, const Quaternion<RT>&
         dwConj = dwConj.mult(q0Inv.mult(q1));
 
         Dune::FieldVector<RT,3> dxi(0);
-        Quaternion<RT>::DexpInv(q0Inv.mult(q1)).umv(dwConj, dxi);
+        Rotation<3,RT>::DexpInv(q0Inv.mult(q1)).umv(dwConj, dxi);
 
         Quaternion<RT> vHv;
         for (int j=0; j<4; j++) {
@@ -249,7 +249,7 @@ interpolationVelocityDerivative(const Quaternion<RT>& q0, const Quaternion<RT>&
             dw[j] = 0.5 * ((i-3)==j);  // dw[j] = dExp_v_0[j][i-3];
 
         // \xi = \exp^{-1} q_0^{-1} q_1
-        Dune::FieldVector<RT,3> xi = Quaternion<RT>::expInv(q0Inv.mult(q1));
+        Dune::FieldVector<RT,3> xi = Rotation<3,RT>::expInv(q0Inv.mult(q1));
 
         //  \parder{\xi}{w^1_j} = ...
         Dune::FieldVector<RT,3> dxi(0);
@@ -329,10 +329,10 @@ getStrain(const Dune::array<Configuration,2>& localSolution,
         r_s[i] = localSolution[0].r[i]*shapeGrad[0][0] + localSolution[1].r[i]*shapeGrad[1][0];
         
     // Interpolate the rotation at the quadrature point
-    Quaternion<double> q = Quaternion<double>::interpolate(localSolution[0].q, localSolution[1].q, pos);
+    Rotation<3,double> q = Rotation<3,double>::interpolate(localSolution[0].q, localSolution[1].q, pos);
         
     // Get the derivative of the rotation at the quadrature point by interpolating in $H$
-    Quaternion<double> q_s = Quaternion<double>::interpolateDerivative(localSolution[0].q, localSolution[1].q,
+    Quaternion<double> q_s = Rotation<3,double>::interpolateDerivative(localSolution[0].q, localSolution[1].q,
                                                                        pos);
     // Transformation from the reference element
     q_s *= inv[0][0];
@@ -421,7 +421,7 @@ assembleGradient(const Entity& element,
             r_s[i] = solution[0].r[i]*shapeGrad[0] + solution[1].r[i]*shapeGrad[1];
         
         // Interpolate current rotation at this quadrature point
-        Quaternion<double> q = Quaternion<double>::interpolate(solution[0].q, solution[1].q,quadPos[0]);
+        Rotation<3,double> q = Rotation<3,double>::interpolate(solution[0].q, solution[1].q,quadPos[0]);
         
         // The current strain
         FieldVector<double,blocksize> strain = getStrain(solution, element, quadPos);
@@ -490,10 +490,10 @@ assembleGradient(const Entity& element,
         double weight = bendingQuad[pt].weight() * integrationElement;
         
         // Interpolate current rotation at this quadrature point
-        Quaternion<double> q = Quaternion<double>::interpolate(solution[0].q, solution[1].q,quadPos[0]);
+        Rotation<3,double> q = Rotation<3,double>::interpolate(solution[0].q, solution[1].q,quadPos[0]);
         
         // Get the derivative of the rotation at the quadrature point by interpolating in $H$
-        Quaternion<double> q_s = Quaternion<double>::interpolateDerivative(solution[0].q, solution[1].q,
+        Quaternion<double> q_s = Rotation<3,double>::interpolateDerivative(solution[0].q, solution[1].q,
                                                                            quadPos);
         // Transformation from the reference element
         q_s *= inv[0][0];
@@ -529,6 +529,8 @@ assembleGradient(const Entity& element,
                 for (int m=0; m<3; m++) {
                     
                     // Compute derivative of the strain
+                    /** \todo Is this formula correct?  It seems strange to call
+                        B(m) for a _derivative_ of a rotation */
                     double du_dvij_m = 2 * (dq_dwij[i*3+j].B(m) * q_s)
                         + 2* ( q.B(m) * dq_ds_dwij[i*3+j]);
                     
diff --git a/src/rodassembler.hh b/src/rodassembler.hh
index 403000616b62c5fca72a3f17c31f4f044ccdb7b8..04f47bb56cade4ee96d54a758ec11ecdb7b92734 100644
--- a/src/rodassembler.hh
+++ b/src/rodassembler.hh
@@ -98,10 +98,10 @@ public:
                const Dune::array<Configuration,2>& localReferenceConfiguration,
                int k=1);
 
-    static void interpolationDerivative(const Quaternion<RT>& q0, const Quaternion<RT>& q1, double s,
+    static void interpolationDerivative(const Rotation<3,RT>& q0, const Rotation<3,RT>& q1, double s,
                                         Dune::array<Quaternion<double>,6>& grad);
 
-    static void interpolationVelocityDerivative(const Quaternion<RT>& q0, const Quaternion<RT>& q1, double s,
+    static void interpolationVelocityDerivative(const Rotation<3,RT>& q0, const Rotation<3,RT>& q1, double s,
                                                 double intervalLength, Dune::array<Quaternion<double>,6>& grad);
 
     Dune::FieldVector<double, 6> getStrain(const Dune::array<Configuration,2>& localSolution,
@@ -115,7 +115,7 @@ public:
                           Dune::array<Dune::FieldVector<double,6>, 2>& gradient) const;
     
     template <class T>
-    static Dune::FieldVector<T,3> darboux(const Quaternion<T>& q, const Dune::FieldVector<T,4>& q_s) 
+    static Dune::FieldVector<T,3> darboux(const Rotation<3,T>& q, const Dune::FieldVector<T,4>& q_s) 
     {
         Dune::FieldVector<double,3> u;  // The Darboux vector
         
diff --git a/src/roddifference.hh b/src/roddifference.hh
index ab32cb6facdf63c39c5de2804df64e4108e8f4c6..5cd16ebdb3f0864d71cbbed5883c2001d3e0e358 100644
--- a/src/roddifference.hh
+++ b/src/roddifference.hh
@@ -16,7 +16,7 @@ Dune::BlockVector<Dune::FieldVector<double,6> > computeRodDifference(const std::
             result[i][j] = a[i].r[j] - b[i].r[j];
         
         // Subtract orientations on the tangent space of 'a'
-        Dune::FieldVector<double,3> v = Quaternion<double>::difference(a[i].q, b[i].q);
+        Dune::FieldVector<double,3> v = Rotation<3,double>::difference(a[i].q, b[i].q);
 
         // Compute difference on T_a SO(3)
         for (int j=0; j<3; j++)
diff --git a/src/rodrefine.hh b/src/rodrefine.hh
index fd78d913200e26bbeb01d23191477027c2056957..fa8b8fa04cc4bbcbdb304a2f5b468f07e686c6f8 100644
--- a/src/rodrefine.hh
+++ b/src/rodrefine.hh
@@ -61,7 +61,7 @@ void globalRodRefine(GridType& grid, std::vector<Configuration>& x)
                 x[indexSet.template subIndex<1>(*eIt,i)].r = (p0.r + p1.r);
                 x[indexSet.template subIndex<1>(*eIt,i)].r *= 0.5;
                 x[indexSet.template subIndex<1>(*eIt,i)].q
-                    = Quaternion<double>::interpolate(p0.q, p1.q, 0.5);
+                    = Rotation<3,double>::interpolate(p0.q, p1.q, 0.5);
 
             }
 
diff --git a/src/rotation.hh b/src/rotation.hh
index b9293cd9902f8574a1638ba8f86fe97b57ba8baf..c632da95d2f4439a3a6e25562a120b62afa91333 100644
--- a/src/rotation.hh
+++ b/src/rotation.hh
@@ -72,6 +72,24 @@ public:
         return q;
     }
 
+    /** \brief Right multiplication with a quaternion
+        \todo do we really need this?*/
+    Rotation<3,T> mult(const Quaternion<T>& other) const {
+        Rotation<3,T> q;
+        q[0] =   (*this)[3]*other[0] - (*this)[2]*other[1] + (*this)[1]*other[2] + (*this)[0]*other[3];
+        q[1] =   (*this)[2]*other[0] + (*this)[3]*other[1] - (*this)[0]*other[2] + (*this)[1]*other[3];
+        q[2] = - (*this)[1]*other[0] + (*this)[0]*other[1] + (*this)[3]*other[2] + (*this)[2]*other[3];
+        q[3] = - (*this)[0]*other[0] - (*this)[1]*other[1] - (*this)[2]*other[2] + (*this)[3]*other[3];
+
+        return q;
+    }
+
+    /** \brief The exponential map from \f$ \mathfrak{so}(3) \f$ to \f$ SO(3) \f$
+     */
+    static Quaternion<T> exp(const Dune::FieldVector<T,3>& v) {
+        return exp(v[0], v[1], v[2]);
+    }
+
     /** \brief The exponential map from \f$ \mathfrak{so}(3) \f$ to \f$ SO(3) \f$
      */
     static Rotation<3,T> exp(const T& v0, const T& v1, const T& v2) {
@@ -92,6 +110,340 @@ public:
 
         return q;
     }
+
+    static Dune::FieldMatrix<T,4,3> Dexp(const Dune::FieldVector<T,3>& v) {
+
+        Dune::FieldMatrix<T,4,3> result(0);
+        T norm = v.two_norm();
+        
+        for (int i=0; i<3; i++) {
+
+            for (int m=0; m<3; m++) {
+                
+                result[m][i] = (norm==0) 
+                    /** \todo Isn't there a better way to implement this stably? */
+                    ? 0.5 * (i==m) 
+                    : 0.5 * std::cos(norm/2) * v[i] * v[m] / (norm*norm) + sincHalf(norm) * ( (i==m) - v[i]*v[m]/(norm*norm));
+
+            }
+
+            result[3][i] = - 0.5 * sincHalf(norm) * v[i];
+
+        }
+        return result;
+    }
+
+    static void DDexp(const Dune::FieldVector<T,3>& v,
+                      Dune::array<Dune::FieldMatrix<T,3,3>, 4>& result) {
+
+        T norm = v.two_norm();
+        if (norm==0) {
+
+            for (int m=0; m<4; m++)
+                result[m] = 0;
+
+            for (int i=0; i<3; i++)
+                result[3][i][i] = -0.25;
+
+
+        } else {
+
+            for (int i=0; i<3; i++) {
+                
+                for (int j=0; j<3; j++) {
+                    
+                    for (int m=0; m<3; m++) {
+                        
+                        result[m][i][j] = -0.25*std::sin(norm/2)*v[i]*v[j]*v[m]/(norm*norm*norm)
+                            + ((i==j)*v[m] + (j==m)*v[i] + (i==m)*v[j] - 3*v[i]*v[j]*v[m]/(norm*norm))
+                            * (0.5*std::cos(norm/2) - sincHalf(norm)) / (norm*norm);
+                        
+
+                    }
+
+                    result[3][i][j] = -0.5/(norm*norm)
+                        * ( 0.5*std::cos(norm/2)*v[i]*v[j] + std::sin(norm/2) * ((i==j)*norm - v[i]*v[j]/norm));
+
+                }
+
+            }
+
+        }
+
+    }
+
+    /** \brief The inverse of the exponential map */
+    static Dune::FieldVector<T,3> expInv(const Rotation<3,T>& q) {
+        // Compute v = exp^{-1} q
+        // Due to numerical dirt, q[3] may be larger than 1. 
+        // In that case, use 1 instead of q[3].
+        Dune::FieldVector<T,3> v;
+        if (q[3] > 1.0) {
+
+            v = 0;
+
+        } else {
+            
+            T invSinc = 1/sincHalf(2*std::acos(q[3]));
+            
+            v[0] = q[0] * invSinc;
+            v[1] = q[1] * invSinc;
+            v[2] = q[2] * invSinc;
+
+        }
+        return v;
+    }
+
+    /** \brief The derivative of the inverse of the exponential map, evaluated at q */
+    static Dune::FieldMatrix<T,3,4> DexpInv(const Rotation<3,T>& q) {
+        
+        // Compute v = exp^{-1} q
+        Dune::FieldVector<T,3> v = expInv(q);
+
+        // The derivative of exp at v
+        Dune::FieldMatrix<T,4,3> A = Dexp(v);
+
+        // Compute the Moore-Penrose pseudo inverse  A^+ = (A^T A)^{-1} A^T
+        Dune::FieldMatrix<T,3,3> ATA;
+
+        for (int i=0; i<3; i++)
+            for (int j=0; j<3; j++) {
+                ATA[i][j] = 0;
+                for (int k=0; k<4; k++)
+                    ATA[i][j] += A[k][i] * A[k][j];
+            }
+
+        ATA.invert();
+
+        Dune::FieldMatrix<T,3,4> APseudoInv;
+        for (int i=0; i<3; i++)
+            for (int j=0; j<4; j++) {
+                APseudoInv[i][j] = 0;
+                for (int k=0; k<3; k++)
+                    APseudoInv[i][j] += ATA[i][k] * A[j][k];
+            }
+
+        return APseudoInv;
+    }
+
+
+    /** \brief Compute the vector in T_aSO(3) that is mapped by the exponential map
+        to the geodesic from a to b
+    */
+    static Dune::FieldVector<T,3> difference(const Rotation<3,T>& a, const Rotation<3,T>& b) {
+
+        Quaternion<T> diff = a;
+        diff.invert();
+        diff = diff.mult(b);
+
+        // Compute the geodesical distance between a and b on SO(3)
+        // Due to numerical dirt, diff[3] may be larger than 1. 
+        // In that case, use 1 instead of diff[3].
+        Dune::FieldVector<T,3> v;
+        if (diff[3] > 1.0) {
+
+            v = 0;
+
+        } else {
+            
+            T dist = 2*std::acos( std::min(diff[3],1.0) );
+            
+            T invSinc = 1/sincHalf(dist);
+            
+            // Compute difference on T_a SO(3)
+            v[0] = diff[0] * invSinc;
+            v[1] = diff[1] * invSinc;
+            v[2] = diff[2] * invSinc;
+
+        }
+
+        return v;
+    }
+
+    /** \brief Interpolate between two rotations */
+    static Rotation<3,T> interpolate(const Rotation<3,T>& a, const Rotation<3,T>& b, double omega) {
+
+        // Compute difference on T_a SO(3)
+        Dune::FieldVector<T,3> v = difference(a,b);
+
+        v *= omega;
+
+        return a.mult(exp(v[0], v[1], v[2]));
+    }
+
+    /** \brief Interpolate between two rotations 
+        \param omega must be between 0 and 1
+        \todo I'd say this method is incorrect and is other one is correct.
+        The solver works much better with this one, though.   I don't get it.
+    */
+    static Quaternion<T> interpolateDerivative(const Rotation<3,T>& a, const Rotation<3,T>& b, 
+                                               double omega) {
+        Quaternion<T> result(0);
+
+        // Compute difference on T_a SO(3)
+        Dune::FieldVector<double,3> xi = difference(a,b);
+
+        Dune::FieldVector<double,3> v = xi;
+        v *= omega;
+        
+        // //////////////////////////////////////////////////////////////
+        //   v now contains the derivative at 'a'.  The derivative at
+        //   the requested site is v pushed forward by Dexp.
+        // /////////////////////////////////////////////////////////////
+
+        Dune::FieldMatrix<double,4,3> diffExp = Dexp(v);
+
+        diffExp.umv(xi,result);
+
+        return a.Quaternion<T>::mult(result);
+    }
+
+    /** \brief Interpolate between two rotations 
+        \param omega must be between 0 and 1
+    */
+    static Quaternion<T> interpolateDerivative(const Quaternion<T>& a, const Quaternion<T>& b, 
+                                               double omega, double intervalLength) {
+        Quaternion<T> result(0);
+
+        // Compute difference on T_a SO(3)
+        Dune::FieldVector<double,3> xi = difference(a,b);
+
+        xi /= intervalLength;
+
+        Dune::FieldVector<double,3> v = xi;
+        v *= omega;
+        
+        // //////////////////////////////////////////////////////////////
+        //   v now contains the derivative at 'a'.  The derivative at
+        //   the requested site is v pushed forward by Dexp.
+        // /////////////////////////////////////////////////////////////
+
+        Dune::FieldMatrix<double,4,3> diffExp = Dexp(v);
+
+        diffExp.umv(xi,result);
+
+        return a.mult(result);
+    }
+
+    /** \brief Return the corresponding orthogonal matrix */
+    void matrix(Dune::FieldMatrix<T,3,3>& m) const {
+
+        m[0][0] = (*this)[0]*(*this)[0] - (*this)[1]*(*this)[1] - (*this)[2]*(*this)[2] + (*this)[3]*(*this)[3];
+        m[0][1] = 2 * ( (*this)[0]*(*this)[1] - (*this)[2]*(*this)[3] );
+        m[0][2] = 2 * ( (*this)[0]*(*this)[2] + (*this)[1]*(*this)[3] );
+
+        m[1][0] = 2 * ( (*this)[0]*(*this)[1] + (*this)[2]*(*this)[3] );
+        m[1][1] = - (*this)[0]*(*this)[0] + (*this)[1]*(*this)[1] - (*this)[2]*(*this)[2] + (*this)[3]*(*this)[3];
+        m[1][2] = 2 * ( -(*this)[0]*(*this)[3] + (*this)[1]*(*this)[2] );
+
+        m[2][0] = 2 * ( (*this)[0]*(*this)[2] - (*this)[1]*(*this)[3] );
+        m[2][1] = 2 * ( (*this)[0]*(*this)[3] + (*this)[1]*(*this)[2] );
+        m[2][2] = - (*this)[0]*(*this)[0] - (*this)[1]*(*this)[1] + (*this)[2]*(*this)[2] + (*this)[3]*(*this)[3];
+
+    }
+
+    /** \brief Set rotation from orthogonal matrix 
+
+    We tacitly assume that the matrix really is orthogonal */
+    void set(const Dune::FieldMatrix<T,3,3>& m) {
+
+        // Easier writing
+        Dune::FieldVector<T,4>& p = (*this);
+        // The following equations for the derivation of a unit quaternion from a rotation
+        // matrix comes from 'E. Salamin, Application of Quaternions to Computation with
+        // Rotations, Technical Report, Stanford, 1974'
+
+        p[0] = (1 + m[0][0] - m[1][1] - m[2][2]) / 4;
+        p[1] = (1 - m[0][0] + m[1][1] - m[2][2]) / 4;
+        p[2] = (1 - m[0][0] - m[1][1] + m[2][2]) / 4;
+        p[3] = (1 + m[0][0] + m[1][1] + m[2][2]) / 4;
+
+        // avoid rounding problems
+        if (p[0] >= p[1] && p[0] >= p[2] && p[0] >= p[3]) {
+
+            p[0] = std::sqrt(p[0]);
+
+            // r_x r_y = (R_12 + R_21) / 4
+            p[1] = (m[0][1] + m[1][0]) / 4 / p[0];
+
+            // r_x r_z = (R_13 + R_31) / 4
+            p[2] = (m[0][2] + m[2][0]) / 4 / p[0];
+
+            // r_0 r_x = (R_32 - R_23) / 4
+            p[3] = (m[2][1] - m[1][2]) / 4 / p[0]; 
+
+        } else if (p[1] >= p[0] && p[1] >= p[2] && p[1] >= p[3]) {
+
+            p[1] = std::sqrt(p[1]);
+
+            // r_x r_y = (R_12 + R_21) / 4
+            p[0] = (m[0][1] + m[1][0]) / 4 / p[1];
+
+            // r_y r_z = (R_23 + R_32) / 4
+            p[2] = (m[1][2] + m[2][1]) / 4 / p[1];
+
+            // r_0 r_y = (R_13 - R_31) / 4
+            p[3] = (m[0][2] - m[2][0]) / 4 / p[1]; 
+
+        } else if (p[2] >= p[0] && p[2] >= p[1] && p[2] >= p[3]) {
+
+            p[2] = std::sqrt(p[2]);
+
+            // r_x r_z = (R_13 + R_31) / 4
+            p[0] = (m[0][2] + m[2][0]) / 4 / p[2];
+
+            // r_y r_z = (R_23 + R_32) / 4
+            p[1] = (m[1][2] + m[2][1]) / 4 / p[2];
+
+            // r_0 r_z = (R_21 - R_12) / 4
+            p[3] = (m[1][0] - m[0][1]) / 4 / p[2]; 
+
+        } else {
+
+            p[3] = std::sqrt(p[3]);
+
+            // r_0 r_x = (R_32 - R_23) / 4
+            p[0] = (m[2][1] - m[1][2]) / 4 / p[3];
+
+            // r_0 r_y = (R_13 - R_31) / 4
+            p[1] = (m[0][2] - m[2][0]) / 4 / p[3];
+
+            // r_0 r_z = (R_21 - R_12) / 4
+            p[2] = (m[1][0] - m[0][1]) / 4 / p[3]; 
+
+        }
+
+    }
+
+    /** \brief Create three vectors which form an orthonormal basis of \mathbb{H} together
+        with this one.
+
+        This is used to compute the strain in rod problems.  
+        See: Dichmann, Li, Maddocks, 'Hamiltonian Formulations and Symmetries in
+        Rod Mechanics', page 83 
+    */
+    Quaternion<T> B(int m) const {
+        assert(m>=0 && m<3);
+        Quaternion<T> r;
+        if (m==0) {
+            r[0] =  (*this)[3];
+            r[1] =  (*this)[2];
+            r[2] = -(*this)[1];
+            r[3] = -(*this)[0];
+        } else if (m==1) {
+            r[0] = -(*this)[2];
+            r[1] =  (*this)[3];
+            r[2] =  (*this)[0];
+            r[3] = -(*this)[1];
+        } else {
+            r[0] =  (*this)[1];
+            r[1] = -(*this)[0];
+            r[2] =  (*this)[3];
+            r[3] = -(*this)[2];
+        } 
+
+        return r;
+    }
     
 };