From d093bb18bf088faa6fc445a1b8bef8b5ae0cab7a Mon Sep 17 00:00:00 2001
From: Oliver Sander <sander@igpm.rwth-aachen.de>
Date: Sun, 7 Mar 2010 17:55:27 +0000
Subject: [PATCH] factor out derivative of arccos squared into a separate
 method

[[Imported from SVN: r5671]]
---
 src/unitvector.hh | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/src/unitvector.hh b/src/unitvector.hh
index e4e63c08..446a6a30 100644
--- a/src/unitvector.hh
+++ b/src/unitvector.hh
@@ -11,6 +11,17 @@ class UnitVector
         return (x < 1e-4) ? 1 + (x*x/6) : std::sin(x)/x;
     }
 
+    /** \brief Compute the derivative of arccos^2 without getting unstable for x close to 1 */
+    static double derivativeOfArcCosSquared(const double& x) {
+        const double eps = 1e-12;
+        if (x > 1-eps) {  // regular expression is unstable, use the series expansion instead
+            return -2 + 2*(x-1)/3 - 4/15*(x-1)*(x-1) + 4/35*(x-1)*(x-1)*(x-1);
+        } else if (x < -1+eps) {  // The function is not differentiable
+            DUNE_THROW(Dune::Exception, "Distance is not differentiable for conjugate points!");
+        } else
+            return -2*std::acos(x) / std::sqrt(1-x*x);
+    }
+
 public:
 
     /** \brief The type used for coordinates */
@@ -58,17 +69,10 @@ public:
      */
     static EmbeddedTangentVector derivativeOfDistanceSquaredWRTSecondArgument(const UnitVector& a, const UnitVector& b) {
         double x = a.data_ * b.data_;
-        const double eps = 1e-12;
 
         EmbeddedTangentVector result = a.data_;
 
-        if (x > 1-eps) {  // regular expression is unstable, use the series expansion instead
-            result *= -2 + 2*(x-1)/3 - 4/15*(x-1)*(x-1) + 4/35*(x-1)*(x-1)*(x-1);
-        } else if (x < -1+eps) {  // a and b are conjugate.  The function is not differentiable
-            DUNE_THROW(Dune::Exception, "Distance is not differentiable for conjugate points!");
-        } else {
-            result *= -2*std::acos(x) / std::sqrt(1-x*x);
-        }
+        result *= derivativeOfArcCosSquared(x);
 
         // Project gradient onto the tangent plane at b in order to obtain the surface gradient
         result = b.projectOntoTangentSpace(result);
-- 
GitLab