diff --git a/dune/gfe/hyperbolichalfspacepoint.hh b/dune/gfe/hyperbolichalfspacepoint.hh
index 99afcc46c02c367f09f40ce7f52e4b600bb4ecb2..f217e13991a3014825d2236b398f56f7ed4c3d04 100644
--- a/dune/gfe/hyperbolichalfspacepoint.hh
+++ b/dune/gfe/hyperbolichalfspacepoint.hh
@@ -450,41 +450,155 @@ public:
     }    
         
     /** \brief Compute the mixed third derivative \partial d^3 / \partial da db^2
-
-    Unlike the distance itself the squared distance is differentiable at zero
      */
-    static Tensor3<T,N,N,N> thirdDerivativeOfDistanceSquaredWRTFirst1AndSecond2Argument(const HyperbolicHalfspacePoint& p, const HyperbolicHalfspacePoint& q) {
-
+    static Tensor3<T,N,N,N> thirdDerivativeOfDistanceSquaredWRTFirst1AndSecond2Argument(const HyperbolicHalfspacePoint& a, const HyperbolicHalfspacePoint& b)
+    {
         Tensor3<T,N,N,N> result;
 
-        T sp = p.data_ * q.data_;
+        // abbreviate notation
+        const Dune::FieldVector<T,N>& p = a.data_;
+        const Dune::FieldVector<T,N>& q = b.data_;
         
-        // The projection matrix onto the tangent space at p and q
-        Dune::FieldMatrix<T,N,N> Pp, Pq;
-        for (int i=0; i<N; i++)
-            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];
+        T diffNormSquared = (p-q).two_norm2();
+
+        // Compute first derivatives of F with respect to p and q
+        Dune::FieldVector<T,N> dFdp;
+        for (size_t i=0; i<N-1; i++)
+            dFdp[i] = ( p[i] - q[i] ) / (p[N-1] * q[N-1]);
+        
+        dFdp[N-1] = - diffNormSquared / (2*p[N-1]*q[N-1]*q[N-1]) - (p[N-1] - q[N-1]) / (p[N-1]*q[N-1]);
+
+        Dune::FieldVector<T,N> dFdq;
+        for (size_t i=0; i<N-1; i++)
+            dFdq[i] = ( b.data_[i] - a.data_[i] ) / (a.data_[N-1] * b.data_[N-1]);
+        
+        dFdq[N-1] = - diffNormSquared / (2*a.data_[N-1]*b.data_[N-1]*b.data_[N-1]) - (a.data_[N-1] - b.data_[N-1]) / (a.data_[N-1]*b.data_[N-1]);
+
+        // Compute second derivatives of F
+        Dune::FieldMatrix<T,N,N> dFdqdq;
+       
+        for (size_t i=0; i<N; i++) {
+            
+            for (size_t j=0; j<N; j++) {
+
+                if (i!=N-1 and j!=N-1) {
+                    
+                    dFdqdq[i][j] = (i==j) / (p[N-1]*q[N-1]);
+                    
+                } else if (i!=N-1 and j==N-1) {
+                    
+                    dFdqdq[i][j] = (p[i] - q[i]) / (p[N-1]*q[N-1]*q[N-1]);
+                    
+                } else if (i!=N-1 and j==N-1) {
+                    
+                    dFdqdq[i][j] = (p[j] - q[j]) / (p[N-1]*q[N-1]*q[N-1]);
+                    
+                } else if (i==N-1 and j==N-1) {
+                    
+                    dFdqdq[i][j] = 1/(q[N-1]*q[N-1]) + (p[N-1]-q[N-1]) / (p[N-1]*q[N-1]*q[N-1]) + diffNormSquared / (p[N-1]*q[N-1]*q[N-1]*q[N-1]);
+                
+                }
+                
             }
             
-        Dune::FieldVector<T,N> pProjected = q.projectOntoTangentSpace(p.globalCoordinates());
-        Dune::FieldVector<T,N> qProjected = p.projectOntoTangentSpace(q.globalCoordinates());
-        
-        Tensor3<T,N,N,N> derivativeOfPqOTimesPq;
-        for (int i=0; i<N; i++)
-            for (int j=0; j<N; j++)
-                for (int k=0; k<N; k++) {
-                    derivativeOfPqOTimesPq[i][j][k] = 0;
-                    for (int l=0; l<N; l++)
-                        derivativeOfPqOTimesPq[i][j][k] += Pp[i][l] * (Pq[j][l]*pProjected[k] + pProjected[j]*Pq[k][l]);
+        }
+
+        Dune::FieldMatrix<T,N,N> dFdpdq;
+       
+        for (size_t i=0; i<N; i++) {
+            
+            for (size_t j=0; j<N; j++) {
+
+                if (i!=N-1 and j!=N-1) {
+                    
+                    dFdpdq[i][j] = -(i==j) / (p[N-1]*q[N-1]);
+                    
+                } else if (i!=N-1 and j==N-1) {
+                    
+                    dFdpdq[i][j] = -(p[i] - q[i]) / (p[N-1]*q[N-1]*q[N-1]);
+                    
+                } else if (i!=N-1 and j==N-1) {
+                    
+                    dFdpdq[i][j] = (p[j] - q[j]) / (p[N-1]*p[N-1]*q[N-1]);
+                    
+                } else if (i==N-1 and j==N-1) {
+                    
+                    dFdpdq[i][j] = -1/(p[N-1]*p[N-1]*q[N-1]) - (p[N-1]-q[N-1]) / (p[N-1]*q[N-1]*q[N-1]) + diffNormSquared / (p[N-1]*p[N-1]*q[N-1]*q[N-1]);
+                
                 }
                 
-        result = thirdDerivativeOfArcCosSquared(sp)         * Tensor3<T,N,N,N>::product(qProjected,pProjected,pProjected)
-                 + secondDerivativeOfArcCosSquared(sp)      * derivativeOfPqOTimesPq
-                 - secondDerivativeOfArcCosSquared(sp) * sp * Tensor3<T,N,N,N>::product(qProjected,Pq)
-                 - derivativeOfArcCosSquared(sp)            * Tensor3<T,N,N,N>::product(qProjected,Pq);
-               
+            }
+            
+        }
+
+        // Compute third derivatives of F
+        Tensor3<T,N,N,N> dFdpdqdq;
+       
+        for (size_t i=0; i<N; i++) {
+            
+            for (size_t j=0; j<N; j++) {
+
+                for (size_t k=0; k<N; k++) {
+                    
+                    if (i!=N-1 and j!=N-1 and k!=N-1) {
+                    
+                        dFdpdqdq[i][j][k] = 0;
+                    
+                    } else if (i!=N-1 and j!=N-1 and k==N-1) {
+                    
+                        dFdpdqdq[i][j][k] = (i==j) / (p[N-1]*q[N-1]*q[N-1]);
+                    
+                    } else if (i!=N-1 and j==N-1 and k!=N-1) {
+                    
+                        dFdpdqdq[i][j][k] = (i==k) / (p[N-1]*q[N-1]*q[N-1]);
+                    
+                    } else if (i!=N-1 and j==N-1 and k==N-1) {
+                    
+                        dFdpdqdq[i][j][k] = 2*(p[i] - q[i]) / (p[N-1]*Dune::Power<3>::eval(q[N-1]));
+                    
+                    } else if (i==N-1 and j!=N-1 and k!=N-1) {
+                    
+                        dFdpdqdq[i][j][k] = (j==k) / (p[N-1]*q[N-1]*q[N-1]);
+                    
+                    } else if (i==N-1 and j!=N-1 and k==N-1) {
+                    
+                        dFdpdqdq[i][j][k] = 2*(p[j] - q[j]) / (p[N-1]*Dune::Power<3>::eval(q[N-1]));
+                    
+                    } else if (i==N-1 and j==N-1 and k!=N-1) {
+                    
+                        dFdpdqdq[i][j][k] = 2*(p[k] - q[k]) / (p[N-1]*Dune::Power<3>::eval(q[N-1]));
+                
+                    } else if (i==N-1 and j==N-1 and k==N-1) {
+                    
+                        dFdpdqdq[i][j][k] = 1.0/(p[N-1]*p[N-1]*q[N-1]*q[N-1]) + 1.0/(p[N-1]*q[N-1]*q[N-1])
+                                          + 2*(p[N-1]-q[N-1])/(p[N-1]*Dune::Power<3>::eval(q[N-1]))
+                                          + 2*(p[N-1]-q[N-1])/(p[N-1]*p[N-1]*q[N-1])
+                                          - diffNormSquared / (p[N-1]*p[N-1]*q[N-1]*q[N-1]);
+                
+                    }
+                    
+                }
+                
+            }
+            
+        }
+
+        //
+        T x = 1 + diffNormSquared/ (2*p[N-1]*q[N-1]);
+        T alphaPrime           = derivativeOfArcCosHSquared(x);
+        T alphaPrimePrime      = secondDerivativeOfArcCosHSquared(x);
+        T alphaPrimePrimePrime = thirdDerivativeOfArcCosHSquared(x);
+
+        // Sum it all together
+        for (size_t i=0; i<N; i++)
+            for (size_t j=0; j<N; j++)
+                for (size_t k=0; k<N; k++)
+                    result[i][j][k] = alphaPrimePrimePrime * dFdp[i] * dFdq[j] * dFdq[k]
+                                    + alphaPrimePrime * (dFdpdq[i][j] * dFdq[k] + dFdpdq[i][k] * dFdq[j] + dFdqdq[j][k] * dFdq[i])
+                                    + alphaPrime * dFdpdqdq[i][j][k];
+
         return result;
+
     }