diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000000000000000000000000000000000000..b7a71f58d5c52cc4112fddb1bc74a5f80b2965f9
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,18 @@
+# Master
+
+- Fix bug in the `RealTuple::log` method: Calling `log(a,b)`returned `a-b`
+  instead of `b-a`.
+
+- Fix the return value of `ProductManifold::log`: It was `TangentVector`,
+  but now it is `EmbeddedTangentVector`.
+
+- The `RigidBodyMotion` class has a `log` method now.
+
+- The method `Rotation<3>::log` now returns an `EmbeddedTangentVector`
+  instead of a `SkewMatrix`.  This is consistent with the other manifold
+  implementations.
+
+- Deprecate the method `RigidBodyMotion::difference`; the method
+  `RigidBodyMotion::log`.  Watch out: The `difference` method was buggy!
+  See https://gitlab.mn.tu-dresden.de/osander/dune-gfe/-/merge_requests/2
+  for details.
diff --git a/dune/gfe/polardecomposition.hh b/dune/gfe/polardecomposition.hh
index 6f3ecb862113d5e241bc267d0bdd701ec3e43406..7d48b9bee1698cecd6d67a064ce71d87ad8112f0 100644
--- a/dune/gfe/polardecomposition.hh
+++ b/dune/gfe/polardecomposition.hh
@@ -25,7 +25,7 @@ namespace Dune::GFE {
         template <class field_type>
         FieldMatrix<field_type,3,3> operator() (const FieldMatrix<field_type,3,3>& matrix, double tol = 0.001) const
         {
-            int maxIterations = 100;
+            size_t maxIterations = 100;
             // Use Higham's method
             auto polar = matrix;
             for (size_t i=0; i<maxIterations; i++)
@@ -244,13 +244,13 @@ namespace Dune::GFE {
                     mini = i;
 
             Pleft[3][mini]  = 1;
-            Pright[mini][3] = 1;      // Smalest element to the last position
+            Pright[mini][3] = 1;      // Smallest element to the last position
 
 
             for (int i = 0; i < 4; ++i) {
-                if ( i != maxi & i != mini ) {
+                if ( i != maxi && i != mini ) {
                     for (int j = 0; j < 4; ++j) {
-                        if ( j != maxi & j != mini & j != i  ) {
+                        if ( j != maxi && j != mini && j != i  ) {
                             if ( Bdiag[i] < Bdiag[j] ) {
                                 Pleft[1][j]  = 1;   // Second largest element at the second position
                                 Pright[j][1] = 1;
@@ -323,4 +323,4 @@ namespace Dune::GFE {
     };
 }
 
-#endif
\ No newline at end of file
+#endif
diff --git a/dune/gfe/productmanifold.hh b/dune/gfe/productmanifold.hh
index 48e86df8a9d44ce355f9ab6715a91b9c8b5f8d3f..ebecd8d414115f266ea05b71792e999a6293f00c 100644
--- a/dune/gfe/productmanifold.hh
+++ b/dune/gfe/productmanifold.hh
@@ -161,9 +161,9 @@ namespace Dune::GFE
     }
 
     /** \brief Compute difference vector from a to b on the tangent space of a */
-    static TangentVector log(const ProductManifold<TS,TargetSpaces...>& a, const ProductManifold<TS,TargetSpaces...>& b)
+    static EmbeddedTangentVector log(const ProductManifold<TS,TargetSpaces...>& a, const ProductManifold<TS,TargetSpaces...>& b)
     {
-      TangentVector diff;
+      EmbeddedTangentVector diff;
       auto logFunctor =[] (auto& argsTuple, std::array<std::size_t,2>& posHelper, const auto& manifoldInt)
       {
           auto& res     = std::get<0>(argsTuple);
@@ -172,7 +172,7 @@ namespace Dune::GFE
           using Manifold = std::remove_const_t<typename std::remove_reference_t<decltype(a)> >;
           const auto diffLoc =  Manifold::log(a,b);
           std::copy(diffLoc.begin(),diffLoc.end(),res.begin()+posHelper[0]);
-          posHelper[0] += Manifold::dim;
+          posHelper[0] += Manifold::embeddedDim;
       };
       foreachManifold(logFunctor,diff,a, b);
       return diff;
diff --git a/dune/gfe/realtuple.hh b/dune/gfe/realtuple.hh
index e4bc4df8561ab9c5fff83bd529b29c7ffe97f61d..7f28cc851254a8ec6981ffda2d3ebbcf067ebb50 100644
--- a/dune/gfe/realtuple.hh
+++ b/dune/gfe/realtuple.hh
@@ -110,10 +110,11 @@ public:
     }
 
     /** \brief The logarithmic map
-     * Simply the difference vector for RealTuple
+     *
+     * \result A vector in the tangent space of a, viz: b-a
      * */
     static auto log(const RealTuple& a, const RealTuple& b) {
-        return a.data_ - b.data_;
+        return b.data_ - a.data_;
     }
 
 #if ADOLC_ADOUBLE_H
diff --git a/dune/gfe/rigidbodymotion.hh b/dune/gfe/rigidbodymotion.hh
index b4541e3e722dac0d7ec67098771043d1e2ee863b..4a4704ff7bd9072981eeaf6535dda7eb477422ab 100644
--- a/dune/gfe/rigidbodymotion.hh
+++ b/dune/gfe/rigidbodymotion.hh
@@ -99,6 +99,26 @@ public:
         return result;
     }
 
+    /** \brief Compute difference vector from a to b on the tangent space of a */
+    static EmbeddedTangentVector log(const RigidBodyMotion<ctype,N>& a,
+                                     const RigidBodyMotion<ctype,N>& b)
+    {
+        EmbeddedTangentVector result;
+
+        // Usual linear difference
+        for (int i=0; i<N; i++)
+            result[i] = b.r[i] - a.r[i];
+
+        // Subtract orientations on the tangent space of 'a'
+        typename Rotation<ctype,N>::EmbeddedTangentVector v = Rotation<ctype,N>::log(a.q, b.q);
+
+        // Compute difference on T_a SO(3)
+        for (int i=0; i<Rotation<ctype,N>::EmbeddedTangentVector::dimension; i++)
+            result[i+N] = v[i];
+
+        return result;
+    }
+
     /** \brief Compute geodesic distance from a to b */
     static T distance(const RigidBodyMotion<ctype,N>& a, const RigidBodyMotion<ctype,N>& b) {
 
@@ -109,7 +129,12 @@ public:
         return std::sqrt(euclideanDistanceSquared + rotationDistance*rotationDistance);
     }
 
-    /** \brief Compute difference vector from a to b on the tangent space of a */
+    /** \brief Compute difference vector from a to b on the tangent space of a
+
+     * \warning The method is buggy!  See https://gitlab.mn.tu-dresden.de/osander/dune-gfe/-/merge_requests/2
+     * \deprecated Use the log method instead!
+     */
+    [[deprecated("Use RigidBodyMotion::log instead of RigidBodyMotion::difference!")]]
     static TangentVector difference(const RigidBodyMotion<ctype,N>& a,
                                     const RigidBodyMotion<ctype,N>& b) {
 
@@ -145,22 +170,26 @@ public:
     }
 
     /** \brief Compute the Hessian of the squared distance function keeping the first argument fixed */
-    static Dune::FieldMatrix<T,embeddedDim,embeddedDim> secondDerivativeOfDistanceSquaredWRTSecondArgument(const RigidBodyMotion<ctype,N> & p, const RigidBodyMotion<ctype,N> & q)
+    static Dune::SymmetricMatrix<T,embeddedDim> secondDerivativeOfDistanceSquaredWRTSecondArgument(const RigidBodyMotion<ctype,N> & p, const RigidBodyMotion<ctype,N> & q)
     {
-        Dune::FieldMatrix<T,embeddedDim,embeddedDim> result(0);
+        Dune::SymmetricMatrix<T,embeddedDim> result;
 
         // The linear part
-        Dune::FieldMatrix<T,N,N> linearPart = RealTuple<T,N>::secondDerivativeOfDistanceSquaredWRTSecondArgument(p.r,q.r);
+        Dune::SymmetricMatrix<T,N> linearPart = RealTuple<T,N>::secondDerivativeOfDistanceSquaredWRTSecondArgument(p.r,q.r);
         for (int i=0; i<N; i++)
-            for (int j=0; j<N; j++)
-                result[i][j] = linearPart[i][j];
+            for (int j=0; j<=i; j++)
+                result(i,j) = linearPart(i,j);
 
         // The rotation part
-        Dune::FieldMatrix<T,Rotation<T,N>::embeddedDim,Rotation<T,N>::embeddedDim> rotationPart
+        Dune::SymmetricMatrix<T,Rotation<T,N>::embeddedDim> rotationPart
                 = Rotation<ctype,N>::secondDerivativeOfDistanceSquaredWRTSecondArgument(p.q,q.q);
         for (int i=0; i<Rotation<T,N>::embeddedDim; i++)
-            for (int j=0; j<Rotation<T,N>::embeddedDim; j++)
-                result[N+i][N+j] = rotationPart[i][j];
+        {
+            for (int j=0; j<N; j++)
+                result(N+i,j) = 0;
+            for (int j=0; j<=i; j++)
+                result(N+i,N+j) = rotationPart(i,j);
+        }
 
         return result;
     }
diff --git a/dune/gfe/rotation.hh b/dune/gfe/rotation.hh
index 6a1cc01a69ab3be0d888c0981fbdf0c28ac2d0c3..139a30344bb755601c479688ccdce6b43233434d 100644
--- a/dune/gfe/rotation.hh
+++ b/dune/gfe/rotation.hh
@@ -305,7 +305,10 @@ public:
     }
 
 
-    /** \brief The exponential map from a given point $p \in SO(3)$. */
+    /** \brief The exponential map from a given point $p \in SO(3)$.
+
+     * \param v A tangent vector *at the identity*!
+     */
     static Rotation<T,3> exp(const Rotation<T,3>& p, const SkewMatrix<T,3>& v) {
         Rotation<T,3> corr = exp(v);
         return p.mult(corr);
@@ -403,6 +406,12 @@ public:
         return skew;
     }
 
+    /** \brief Derivative of the exponential map at the identity
+     *
+     * The exponential map at the identity is a map from a neighborhood of zero to the neighborhood of the identity rotation.
+     *
+     * \param v Where to evaluate the derivative of the (exponential map at the identity)
+     */
     static Dune::FieldMatrix<T,4,3> Dexp(const SkewMatrix<T,3>& v) {
 
         using std::cos;
@@ -613,7 +622,10 @@ public:
     /** \brief Compute the vector in T_aSO(3) that is mapped by the exponential map
         to the geodesic from a to b
     */
-    static SkewMatrix<T,3> log(const Rotation<T,3>& a, const Rotation<T,3>& b) {
+    static EmbeddedTangentVector log(const Rotation<T,3>& a, const Rotation<T,3>& b) {
+
+        // embedded tangent vector at identity
+        Quaternion<T> v;
 
         Quaternion<T> diff = a;
         diff.invert();
@@ -622,7 +634,6 @@ public:
         // 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;
@@ -645,13 +656,14 @@ public:
             T invSinc = 1/sincHalf(dist);
 
             // Compute log on T_a SO(3)
-            v[0] = diff[0] * invSinc;
-            v[1] = diff[1] * invSinc;
-            v[2] = diff[2] * invSinc;
-
+            v[0] = 0.5 * diff[0] * invSinc;
+            v[1] = 0.5 * diff[1] * invSinc;
+            v[2] = 0.5 * diff[2] * invSinc;
+            v[3] = 0;
         }
 
-        return SkewMatrix<T,3>(v);
+        // multiply with base point to get real embedded tangent vector
+        return ((Quaternion<T>) a).mult(v);
     }
 
     /** \brief Compute the derivatives of the director vectors with respect to the quaternion coordinates
@@ -917,11 +929,8 @@ public:
     static Rotation<T,3> interpolate(const Rotation<T,3>& a, const Rotation<T,3>& b, T omega) {
 
         // Compute log on T_a SO(3)
-        SkewMatrix<T,3> v = log(a,b);
-
-        v *= omega;
-
-        return a.mult(exp(v));
+        EmbeddedTangentVector v = log(a,b);
+        return exp(a, omega*v);
     }
 
     /** \brief Interpolate between two rotations
diff --git a/dune/gfe/unitvector.hh b/dune/gfe/unitvector.hh
index 7122d1cda48f90638b8072f0211a6f1482a40baf..7a41e8435a4711db222ed55705e2cd4a57ff3717 100644
--- a/dune/gfe/unitvector.hh
+++ b/dune/gfe/unitvector.hh
@@ -219,6 +219,10 @@ public:
         return result;
     }
 
+    /** \brief The inverse of the exponential map
+     *
+     * \results A vector in the tangent space of p
+     */
     static EmbeddedTangentVector log(const UnitVector& p, const UnitVector& q)
     {
       EmbeddedTangentVector result = p.projectOntoTangentSpace(q.data_-p.data_);
diff --git a/test/cosseratenergytest.cc b/test/cosseratenergytest.cc
index cdfc0f38c9d95afdf49e1aadd9cb380d69296214..9f4b5bc40e667f1355bf4531f6c25b5d889ecd44 100644
--- a/test/cosseratenergytest.cc
+++ b/test/cosseratenergytest.cc
@@ -7,8 +7,6 @@
 
 #include <dune/functions/functionspacebases/lagrangebasis.hh>
 
-#include <dune/fufem/functions/constantfunction.hh>
-
 #include <dune/gfe/rigidbodymotion.hh>
 #include <dune/gfe/cosseratenergystiffness.hh>
 
@@ -44,7 +42,7 @@ std::unique_ptr<GridType> makeSingleSimplexGrid()
         v[i] = i;
     factory.insertElement(GeometryTypes::simplex(domainDim), v);
 
-    return std::unique_ptr<GridType>(factory.createGrid());
+    return factory.createGrid();
 }
 
 
diff --git a/test/cosseratrodenergytest.cc b/test/cosseratrodenergytest.cc
index ff65271b6c6ed816cded185956c0158e4b1a1fd9..6a485ac5704538ca516071b8111c21702b149d0d 100644
--- a/test/cosseratrodenergytest.cc
+++ b/test/cosseratrodenergytest.cc
@@ -80,7 +80,7 @@ int main (int argc, char *argv[]) try
 
     std::vector<RigidBodyMotion<double,3> > referenceConfiguration(gridView.size(1));
 
-    for (const auto vertex : vertices(gridView))
+    for (const auto& vertex : vertices(gridView))
     {
         auto idx = gridView.indexSet().index(vertex);
 
diff --git a/test/polardecompositiontest.cc b/test/polardecompositiontest.cc
index cc10676d24424d59fc4316dace27efa2a9fb9720..779d929c07a21faa610704e10dab8f52b73abc02 100644
--- a/test/polardecompositiontest.cc
+++ b/test/polardecompositiontest.cc
@@ -168,7 +168,6 @@ static bool test4dDeterminant() {
 
 static bool testdominantEVNewton() {
     field_type detB = 0.992928;
-    field_type detM = 0.000620104;
     FieldVector<field_type,3>  minpol = {0, -1.99999, -0.00496083};
     double correctDominantEV = 1.05397;
 
diff --git a/test/surfacecosseratstressassemblertest.cc b/test/surfacecosseratstressassemblertest.cc
index 66cbddd561d31042533a57896b35b9730d5481e3..9e2ea9609c73b85646a9be8032e827ab63ab3754 100644
--- a/test/surfacecosseratstressassemblertest.cc
+++ b/test/surfacecosseratstressassemblertest.cc
@@ -92,7 +92,7 @@ static bool symmetryTest(std::unordered_map<std::string, FieldVector<double,d>>
 
 int main (int argc, char *argv[])
 {
-  MPIHelper& mpiHelper = MPIHelper::instance(argc, argv);
+  MPIHelper::instance(argc, argv);
 
   /////////////////////////////////////////////////////////////
   //                      CREATE THE GRID
@@ -186,7 +186,7 @@ int main (int argc, char *argv[])
   Functions::interpolate(basisOrderD, x, [](FieldVector<double,dim> x){ return x; });
   Functions::interpolate(basisOrderD, xInitial, [](FieldVector<double,dim> x){ return x; });
 
-  for (int i = 0; i < basisOrderD.size(); i++) {
+  for (std::size_t i = 0; i < basisOrderD.size(); i++) {
     std::stringstream stream;
     stream << x[i];
     //Look up the displacement for this vertex in the deformationMap
@@ -201,7 +201,7 @@ int main (int argc, char *argv[])
   DisplacementVector xOrderR;
   xOrderR.resize(basisOrderR.size());
   Functions::interpolate(basisOrderR, xOrderR, [](FieldVector<double,dim> x){ return x; });
-  for (int i = 0; i < basisOrderR.size(); i++) {
+  for (std::size_t i = 0; i < basisOrderR.size(); i++) {
     std::stringstream stream;
     stream << xOrderR[i];
     Rotation<double,dim> rotation(rotationMap.at(stream.str()));
diff --git a/test/targetspacetest.cc b/test/targetspacetest.cc
index b5e1c650bf1e91361fb1bf8fd7111ac40414bff8..cea7382c03b2361660487a408401ba17e9c755b5 100644
--- a/test/targetspacetest.cc
+++ b/test/targetspacetest.cc
@@ -29,23 +29,33 @@ double diameter(const std::vector<TargetSpace>& v)
 const double eps = 1e-4;
 
 template <class TargetSpace>
-double energy(const TargetSpace& a, const TargetSpace& b)
+void testExpLog(const TargetSpace& a, const TargetSpace& b)
 {
-    return TargetSpace::distance(a,b) * TargetSpace::distance(a,b);
+    // Check whether exp and log are mutually inverse
+    typename TargetSpace::EmbeddedTangentVector logarithm = TargetSpace::log(a,b);
+    TargetSpace exponential = TargetSpace::exp(a, logarithm);
+
+    if (TargetSpace::distance(b, exponential) > eps)
+    {
+        std::cout << className(a) << ": Exp and log are not mutually inverse." << std::endl;
+        std::cout << "exp(a,log(a,b)): " << exponential << std::endl;
+        std::cout << "b              : " << b << std::endl;
+        assert(false);
+    }
 }
 
-template <class TargetSpace, int dim>
-double energy(const TargetSpace& a, const FieldVector<double,dim>& b)
+template <class TargetSpace>
+double distanceSquared(const TargetSpace& a, const TargetSpace& b)
 {
-#warning Cast where there should not be one
-    return TargetSpace::distance(a,TargetSpace(b)) * TargetSpace::distance(a,TargetSpace(b));
+    return Dune::power(TargetSpace::distance(a,b), 2);
 }
 
+// Squared distance between two points slightly off the manifold.
+// This is required for finite difference approximations.
 template <class TargetSpace, int dim>
-double energy(const FieldVector<double,dim>& a, const FieldVector<double,dim>& b)
+double distanceSquared(const FieldVector<double,dim>& a, const FieldVector<double,dim>& b)
 {
-#warning Cast where there should not be one
-    return TargetSpace::distance(TargetSpace(a),TargetSpace(b)) * TargetSpace::distance(TargetSpace(a),TargetSpace(b));
+    return Dune::power(TargetSpace::distance(TargetSpace(a),TargetSpace(b)), 2);
 }
 
 /** \brief Compute the Riemannian Hessian of the squared distance function in global coordinates
@@ -67,15 +77,15 @@ FieldMatrix<double,worldDim,worldDim> getSecondDerivativeOfSecondArgumentFD(cons
     for (size_t i=0; i<spaceDim; i++) {
         for (size_t j=0; j<spaceDim; j++) {
 
-            FieldVector<double,worldDim> epsXi = B[i];    epsXi *= eps;
-            FieldVector<double,worldDim> epsEta = B[j];   epsEta *= eps;
+            FieldVector<double,worldDim> epsXi  = eps * B[i];
+            FieldVector<double,worldDim> epsEta = eps * B[j];
             
-            FieldVector<double,worldDim> minusEpsXi  = epsXi;   minusEpsXi  *= -1;
-            FieldVector<double,worldDim> minusEpsEta = epsEta;  minusEpsEta *= -1;
+            FieldVector<double,worldDim> minusEpsXi  = -1 * epsXi;
+            FieldVector<double,worldDim> minusEpsEta = -1 * epsEta;
             
-            double forwardValue  = energy(a,TargetSpace::exp(b,epsXi+epsEta)) - energy(a, TargetSpace::exp(b,epsXi)) - energy(a,TargetSpace::exp(b,epsEta));
-            double centerValue   = energy(a,b)                   - energy(a,b)              - energy(a,b);
-            double backwardValue = energy(a,TargetSpace::exp(b,minusEpsXi + minusEpsEta)) - energy(a, TargetSpace::exp(b,minusEpsXi)) - energy(a,TargetSpace::exp(b,minusEpsEta));
+            double forwardValue  = distanceSquared(a,TargetSpace::exp(b,epsXi+epsEta)) - distanceSquared(a, TargetSpace::exp(b,epsXi)) - distanceSquared(a,TargetSpace::exp(b,epsEta));
+            double centerValue   = distanceSquared(a,b) - distanceSquared(a,b) - distanceSquared(a,b);
+            double backwardValue = distanceSquared(a,TargetSpace::exp(b,minusEpsXi + minusEpsEta)) - distanceSquared(a, TargetSpace::exp(b,minusEpsXi)) - distanceSquared(a,TargetSpace::exp(b,minusEpsEta));
             
             d2d2_fd[i][j] = 0.5 * (forwardValue - 2*centerValue + backwardValue) / (eps*eps);
             
@@ -111,7 +121,7 @@ void testOrthonormalFrame(const TargetSpace& a)
 }
 
 template <class TargetSpace>
-void testDerivativeOfSquaredDistance(const TargetSpace& a, const TargetSpace& b)
+void testDerivativeOfDistanceSquared(const TargetSpace& a, const TargetSpace& b)
 {
     static const size_t embeddedDim = TargetSpace::embeddedDim;
     
@@ -126,14 +136,12 @@ void testDerivativeOfSquaredDistance(const TargetSpace& a, const TargetSpace& b)
     typename TargetSpace::TangentVector d2_fd;
     for (size_t i=0; i<TargetSpace::TangentVector::dimension; i++) {
         
-        typename TargetSpace::EmbeddedTangentVector fwVariation = B[i];
-        typename TargetSpace::EmbeddedTangentVector bwVariation = B[i];
-        fwVariation *= eps;
-        bwVariation *= -eps;
+        typename TargetSpace::EmbeddedTangentVector fwVariation =  eps * B[i];
+        typename TargetSpace::EmbeddedTangentVector bwVariation = -eps * B[i];
         TargetSpace bPlus  = TargetSpace::exp(b,fwVariation);
         TargetSpace bMinus = TargetSpace::exp(b,bwVariation);
 
-        d2_fd[i] = (energy(a,bPlus) - energy(a,bMinus)) / (2*eps);
+        d2_fd[i] = (distanceSquared(a,bPlus) - distanceSquared(a,bMinus)) / (2*eps);
     }
 
     // transform into embedded coordinates
@@ -150,7 +158,7 @@ void testDerivativeOfSquaredDistance(const TargetSpace& a, const TargetSpace& b)
 }
 
 template <class TargetSpace>
-void testHessianOfSquaredDistance(const TargetSpace& a, const TargetSpace& b)
+void testHessianOfDistanceSquared(const TargetSpace& a, const TargetSpace& b)
 {
     static const int embeddedDim = TargetSpace::embeddedDim;
     
@@ -162,9 +170,7 @@ void testHessianOfSquaredDistance(const TargetSpace& a, const TargetSpace& b)
     // finite-difference approximation
     FieldMatrix<double,embeddedDim,embeddedDim> d2d2_fd = getSecondDerivativeOfSecondArgumentFD<TargetSpace,embeddedDim>(a,b);
     
-    FieldMatrix<double,embeddedDim,embeddedDim> d2d2_diff = d2d2;
-    d2d2_diff -= d2d2_fd;
-    if ( (d2d2_diff).infinity_norm() > 200*eps) {
+    if ( (d2d2 - d2d2_fd).infinity_norm() > 200*eps) {
         std::cout << className(a) << ": Analytical second derivative does not match fd approximation." << std::endl;
         std::cout << "d2d2 Analytical:" << std::endl << d2d2 << std::endl;
         std::cout << "d2d2 FD        :" << std::endl << d2d2_fd << std::endl;
@@ -174,7 +180,7 @@ void testHessianOfSquaredDistance(const TargetSpace& a, const TargetSpace& b)
 }
 
 template <class TargetSpace>
-void testMixedDerivativesOfSquaredDistance(const TargetSpace& a, const TargetSpace& b)
+void testMixedDerivativesOfDistanceSquared(const TargetSpace& a, const TargetSpace& b)
 {
     static const size_t embeddedDim = TargetSpace::embeddedDim;
     
@@ -200,16 +206,13 @@ void testMixedDerivativesOfSquaredDistance(const TargetSpace& a, const TargetSpa
             bPlus[j]  += eps;
             bMinus[j] -= eps;
                 
-            d1d2_fd[i][j] = (energy<TargetSpace>(aPlus,bPlus) + energy<TargetSpace>(aMinus,bMinus)
-                            - energy<TargetSpace>(aPlus,bMinus) - energy<TargetSpace>(aMinus,bPlus)) / (4*eps*eps);
+            d1d2_fd[i][j] = (distanceSquared<TargetSpace>(aPlus,bPlus) + distanceSquared<TargetSpace>(aMinus,bMinus)
+                            - distanceSquared<TargetSpace>(aPlus,bMinus) - distanceSquared<TargetSpace>(aMinus,bPlus)) / (4*eps*eps);
 
         }
     }
     
-    FieldMatrix<double,embeddedDim,embeddedDim> d1d2_diff = d1d2;
-    d1d2_diff -= d1d2_fd;
-
-    if ( (d1d2_diff).infinity_norm() > 200*eps ) {
+    if ( (d1d2 - d1d2_fd).infinity_norm() > 200*eps ) {
         std::cout << className(a) << ": Analytical mixed second derivative does not match fd approximation." << std::endl;
         std::cout << "d1d2 Analytical:" << std::endl << d1d2 << std::endl;
         std::cout << "d1d2 FD        :" << std::endl << d1d2_fd << std::endl;
@@ -220,7 +223,7 @@ void testMixedDerivativesOfSquaredDistance(const TargetSpace& a, const TargetSpa
 
 
 template <class TargetSpace>
-void testDerivativeOfHessianOfSquaredDistance(const TargetSpace& a, const TargetSpace& b)
+void testDerivativeOfHessianOfDistanceSquared(const TargetSpace& a, const TargetSpace& b)
 {
     static const size_t embeddedDim = TargetSpace::embeddedDim;
     
@@ -259,7 +262,7 @@ void testDerivativeOfHessianOfSquaredDistance(const TargetSpace& a, const Target
 
 
 template <class TargetSpace>
-void testMixedDerivativeOfHessianOfSquaredDistance(const TargetSpace& a, const TargetSpace& b)
+void testMixedDerivativeOfHessianOfDistanceSquared(const TargetSpace& a, const TargetSpace& b)
 {
     static const size_t embeddedDim = TargetSpace::embeddedDim;
     
@@ -298,38 +301,38 @@ void testMixedDerivativeOfHessianOfSquaredDistance(const TargetSpace& a, const T
 
 
 template <class TargetSpace>
-void testDerivativesOfSquaredDistance(const TargetSpace& a, const TargetSpace& b)
+void testDerivativesOfDistanceSquared(const TargetSpace& a, const TargetSpace& b)
 {
     
     ///////////////////////////////////////////////////////////////////
     //  Test derivative with respect to second argument
     ///////////////////////////////////////////////////////////////////
     
-    testDerivativeOfSquaredDistance<TargetSpace>(a,b);
+    testDerivativeOfDistanceSquared<TargetSpace>(a,b);
     
     ///////////////////////////////////////////////////////////////////
     //  Test second derivative with respect to second argument
     ///////////////////////////////////////////////////////////////////
 
-    testHessianOfSquaredDistance<TargetSpace>(a,b);
+    testHessianOfDistanceSquared<TargetSpace>(a,b);
 
     //////////////////////////////////////////////////////////////////////////////
     //  Test mixed second derivative with respect to first and second argument
     //////////////////////////////////////////////////////////////////////////////
 
-    testMixedDerivativesOfSquaredDistance<TargetSpace>(a,b);
+    testMixedDerivativesOfDistanceSquared<TargetSpace>(a,b);
     
     /////////////////////////////////////////////////////////////////////////////////////////////
     //  Test third derivative with respect to second argument
     /////////////////////////////////////////////////////////////////////////////////////////////
     
-    testDerivativeOfHessianOfSquaredDistance<TargetSpace>(a,b);
+    testDerivativeOfHessianOfDistanceSquared<TargetSpace>(a,b);
 
     /////////////////////////////////////////////////////////////////////////////////////////////
     //  Test mixed third derivative with respect to first (once) and second (twice) argument
     /////////////////////////////////////////////////////////////////////////////////////////////
     
-    testMixedDerivativeOfHessianOfSquaredDistance<TargetSpace>(a,b);
+    testMixedDerivativeOfHessianOfDistanceSquared<TargetSpace>(a,b);
 
 }
 
@@ -357,12 +360,11 @@ void test()
             if (diameter(testPointPair) > TargetSpace::convexityRadius)
                 continue;
 
-            TargetSpace p = testPointPair[0];
-            TargetSpace q = testPointPair[1];
-            std::cout << "p: " << testPointPair[0] << ",   q: " << testPointPair[1] << std::endl;
-            std::cout << TargetSpace::exp(p, TargetSpace::log(p,q)) << std::endl;
-            
-            testDerivativesOfSquaredDistance<TargetSpace>(testPoints[i], testPoints[j]);
+            // Test the exponential map and the logarithm
+            testExpLog(testPoints[i], testPoints[j]);
+
+            // Test the various derivatives of the squared distance
+            testDerivativesOfDistanceSquared<TargetSpace>(testPoints[i], testPoints[j]);
             
         }
         
@@ -373,25 +375,30 @@ void test()
 
 int main() try
 {
-//     test<RealTuple<double,1> >();
-//     test<RealTuple<double,3> >();
+    // Test the RealTuple class
+    test<RealTuple<double,1> >();
+    test<RealTuple<double,3> >();
     
+    // Test the UnitVector class
     test<UnitVector<double,2> >();
     test<UnitVector<double,3> >();
     test<UnitVector<double,4> >();
 
+    // Test the rotation class
+    test<Rotation<double,3> >();
+
+    // Test the ProductManifold class
     test<Dune::GFE::ProductManifold<RealTuple<double,1>,Rotation<double,3>,UnitVector<double,2>>>();
     test<Dune::GFE::ProductManifold<Rotation<double,3>,UnitVector<double,5>>>();
 
-//     test<Rotation<double,3> >();
-//
-//     test<RigidBodyMotion<double,3> >();
+    // Test the RigidBodyMotion class
+    test<RigidBodyMotion<double,3> >();
 //
 //     test<HyperbolicHalfspacePoint<double,2> >();
 
 } catch (Exception& e) {
 
-    std::cout << e << std::endl;
+    std::cout << e.what() << std::endl;
 
 }