From df5d9b8c123c52516beea6c6a759266dd0a50c2c Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Fri, 14 Feb 2014 09:08:44 +0000
Subject: [PATCH] modify newton_fd

---
 Geo/Geo.cpp                   | 10 ++++---
 Geo/intersectCurveSurface.cpp | 50 +++++++++++++++++++----------------
 Geo/intersectCurveSurface.h   | 29 +++++++++++---------
 Numeric/Numeric.cpp           |  8 +++---
 Numeric/Numeric.h             |  2 +-
 5 files changed, 54 insertions(+), 45 deletions(-)

diff --git a/Geo/Geo.cpp b/Geo/Geo.cpp
index 41e285a3f9..1a766e79bd 100644
--- a/Geo/Geo.cpp
+++ b/Geo/Geo.cpp
@@ -3517,7 +3517,7 @@ struct PointSurface{
   Surface *s;
 };
 
-static void projectPS(fullVector<double> &x, fullVector<double> &res, void *data)
+static bool projectPS(fullVector<double> &x, fullVector<double> &res, void *data)
 {
   PointSurface *ps = (PointSurface*)data;
   Vertex c = InterpolateSurface(ps->s, x(0), x(1), 0, 0);
@@ -3531,6 +3531,7 @@ static void projectPS(fullVector<double> &x, fullVector<double> &res, void *data
     (c.Pos.X - ps->p->Pos.X) * dv.Pos.X +
     (c.Pos.Y - ps->p->Pos.Y) * dv.Pos.Y +
     (c.Pos.Z - ps->p->Pos.Z) * dv.Pos.Z;
+  return true;
 }
 
 bool ProjectPointOnSurface(Surface *s, Vertex &p, double uv[2])
@@ -3725,7 +3726,7 @@ bool SplitCurve(int line_id, List_T *vertices_id, List_T *shapes)
     }
   }
   List_Delete(Surfs);
-  
+
   // replace original curve by the new curves in physical groups
   for(int i = 0; i < List_Nbr(GModel::current()->getGEOInternals()->PhysicalGroups); i++){
     PhysicalGroup *p = *(PhysicalGroup**)List_Pointer
@@ -3742,7 +3743,7 @@ bool SplitCurve(int line_id, List_T *vertices_id, List_T *shapes)
       }
     }
   }
-  
+
   DeleteShape(c->Typ, c->Num);
   List_Delete(new_list);
   List_Delete(rshapes);
@@ -3757,7 +3758,7 @@ struct CurveSurface{
   Surface *s;
 };
 
-static void intersectCS(fullVector<double> &uvt, fullVector<double> &res, void *data)
+static bool intersectCS(fullVector<double> &uvt, fullVector<double> &res, void *data)
 {
   CurveSurface *cs = (CurveSurface*)data;
   Vertex vs = InterpolateSurface(cs->s, uvt(0), uvt(1), 0, 0);
@@ -3765,6 +3766,7 @@ static void intersectCS(fullVector<double> &uvt, fullVector<double> &res, void *
   res(0) = vs.Pos.X - vc.Pos.X;
   res(1) = vs.Pos.Y - vc.Pos.Y;
   res(2) = vs.Pos.Z - vc.Pos.Z;
+  return true;
 }
 
 
diff --git a/Geo/intersectCurveSurface.cpp b/Geo/intersectCurveSurface.cpp
index c125bef4ab..0d1ba82405 100644
--- a/Geo/intersectCurveSurface.cpp
+++ b/Geo/intersectCurveSurface.cpp
@@ -1,20 +1,24 @@
+// Gmsh - Copyright (C) 1997-2014 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to the public mailing list <gmsh@geuz.org>.
+
 #include "intersectCurveSurface.h"
 #include "Numeric.h"
 
-static void _kaboom(fullVector<double> &uvt, 
-			    fullVector<double> &res, void *_data);
+static bool _kaboom(fullVector<double> &uvt,
+                    fullVector<double> &res, void *_data);
 
-struct intersectCurveSurfaceData 
+struct intersectCurveSurfaceData
 {
   const curveFunctor &c;
   const surfaceFunctor &s;
   const double epsilon;
-  intersectCurveSurfaceData (const curveFunctor & _c, 
-			     const surfaceFunctor & _s, 
-			     const double &eps) : c(_c),s(_s),epsilon(eps)
-  { }
-
-  bool apply (double newPoint[3]){
+  intersectCurveSurfaceData(const curveFunctor & _c,
+                            const surfaceFunctor & _s,
+                            const double &eps) : c(_c),s(_s),epsilon(eps){}
+  bool apply(double newPoint[3])
+  {
     try {
       fullVector<double> uvt(3);
       uvt(0) = newPoint[0];
@@ -24,8 +28,8 @@ struct intersectCurveSurfaceData
       _kaboom(uvt,res,this);
       //      printf("start with %12.5E\n",res.norm());
       if (res.norm() < epsilon)return true;
-      
-      
+
+
       if(newton_fd(_kaboom, uvt, this)){
 	//      printf("--- CONVERGED -----------\n");
 	newPoint[0] = uvt(0);
@@ -33,31 +37,31 @@ struct intersectCurveSurfaceData
 	newPoint[2] = uvt(2);
 	//	printf("newton done\n");
 	return true;
-      }    
+      }
     }
     catch (...){
-      //      printf("intersect curve surface failed !\n");
+      // printf("intersect curve surface failed !\n");
     }
-    //    printf("newton failsed\n");
+    // printf("newton failed\n");
     return false;
   }
 };
 
-void _kaboom(fullVector<double> &uvt, 
-	     fullVector<double> &res, void *_data){
+static bool _kaboom(fullVector<double> &uvt,
+                    fullVector<double> &res, void *_data)
+{
   intersectCurveSurfaceData *data = (intersectCurveSurfaceData*)_data;
-  //  printf("coucuo1 %g %g\n",uvt(0),uvt(1));
-  SPoint3 s = data->s(uvt(0),uvt(1));
-  //  printf("coucuo1\n");
+  SPoint3 s = data->s(uvt(0), uvt(1));
   SPoint3 c = data->c(uvt(2));
-  //  printf("coucuo1\n");
   res(0) = s.x() - c.x();
   res(1) = s.y() - c.y();
   res(2) = s.z() - c.z();
-  //    printf("%g %g %g vs %g %g %g \n",s.x(),s.y(),s.z(),c.x(),c.y(),c.z());
+  return true;
 }
 
-int intersectCurveSurface (curveFunctor &c, surfaceFunctor & s, double uvt[3], double epsilon){
-  intersectCurveSurfaceData data(c,s,epsilon);
+int intersectCurveSurface(curveFunctor &c, surfaceFunctor & s, double uvt[3],
+                          double epsilon)
+{
+  intersectCurveSurfaceData data(c, s, epsilon);
   return data.apply(uvt);
 }
diff --git a/Geo/intersectCurveSurface.h b/Geo/intersectCurveSurface.h
index c06c10cdf3..2c70b5fb74 100644
--- a/Geo/intersectCurveSurface.h
+++ b/Geo/intersectCurveSurface.h
@@ -8,20 +8,20 @@
 
 // Intersection of a curve and a surface using newton's method
 // FD are used to compute derivatives of the parametrizations
+#include <math.h>
 #include "SPoint3.h"
 #include "SVector3.h"
 #include "GFace.h"
 #include "GEdge.h"
-#include "math.h"
 
-class surfaceFunctor 
+class surfaceFunctor
 {
 public :
   virtual ~surfaceFunctor(){}
   virtual SPoint3 operator () (double u, double v) const = 0;
 };
 
-class curveFunctor 
+class curveFunctor
 {
 public :
   virtual ~curveFunctor(){}
@@ -57,10 +57,11 @@ class curveFunctorCircle : public curveFunctor
   SVector3 middle;
   double d;
 public :
-  curveFunctorCircle(const SVector3 & _n1, const SVector3 & _n2, const SVector3 & _middle, const double & _d) : 
-  n1(_n1),n2(_n2),middle(_middle),d(_d) {
-  }
-  virtual SPoint3 operator () (double t) const {
+  curveFunctorCircle(const SVector3 & _n1, const SVector3 & _n2,
+                     const SVector3 & _middle, const double & _d) :
+    n1(_n1), n2(_n2), middle(_middle), d(_d){}
+  virtual SPoint3 operator () (double t) const
+  {
     SVector3 dir = (n1*cos(t)+n2*sin(t))*d;
     return SPoint3(middle.x() + dir.x(),
 		   middle.y() + dir.y(),
@@ -73,17 +74,21 @@ class surfaceFunctorPlane : public surfaceFunctor
   const SPoint3 p;
   const SVector3 v1,v2;
 public :
-  surfaceFunctorPlane(const SPoint3 &_p, const SVector3 &_v1, const SVector3 &_v2) : p(_p),v1(_v1),v2(_v2) {}
-  virtual SPoint3 operator () (double u, double v) const {
+  surfaceFunctorPlane(const SPoint3 &_p, const SVector3 &_v1, const SVector3 &_v2)
+    : p(_p),v1(_v1),v2(_v2) {}
+  virtual SPoint3 operator () (double u, double v) const
+  {
     return SPoint3 (p.x() + u * v1.x() + v * v2.x(),
-		   p.y() + u * v1.y() + v * v2.y(),
-		   p.z() + u * v1.z() + v * v2.z()) ;
+                    p.y() + u * v1.y() + v * v2.y(),
+                    p.z() + u * v1.z() + v * v2.z()) ;
   }
 };
+
 // intersects the curve and the surface using Newton.
 // the initial guess should be a good guess
 // returns 1 --> OK
 // returns 0 --> NOT CONVERGED
-int intersectCurveSurface (curveFunctor &c, surfaceFunctor & s, double uvt[3], double epsilon);
+int intersectCurveSurface(curveFunctor &c, surfaceFunctor & s, double uvt[3],
+                          double epsilon);
 
 #endif
diff --git a/Numeric/Numeric.cpp b/Numeric/Numeric.cpp
index 5827e151d2..9b26a8a5fb 100644
--- a/Numeric/Numeric.cpp
+++ b/Numeric/Numeric.cpp
@@ -656,7 +656,7 @@ void invert_singular_matrix3x3(double MM[3][3], double II[3][3])
   }
 }
 
-bool newton_fd(void (*func)(fullVector<double> &, fullVector<double> &, void *),
+bool newton_fd(bool (*func)(fullVector<double> &, fullVector<double> &, void *),
                fullVector<double> &x, void *data, double relax, double tolx)
 {
   const int MAXIT = 10;
@@ -667,7 +667,7 @@ bool newton_fd(void (*func)(fullVector<double> &, fullVector<double> &, void *),
   fullVector<double> f(N), feps(N), dx(N);
 
   for (int iter = 0; iter < MAXIT; iter++){
-    func(x, f, data);
+    if(!func(x, f, data)) return false;
 
     bool isZero = false;
     for (int k=0; k<N; k++) {
@@ -681,10 +681,9 @@ bool newton_fd(void (*func)(fullVector<double> &, fullVector<double> &, void *),
       double h = EPS * fabs(x(j));
       if(h == 0.) h = EPS;
       x(j) += h;
-      func(x, feps, data);
+      if(!func(x, feps, data)) return false;
       for (int i = 0; i < N; i++){
         J(i, j) = (feps(i) - f(i)) / h;
-	//	printf("J(%d,%d) = %12.5E \n",i,j,J(i,j));
       }
       x(j) -= h;
     }
@@ -700,7 +699,6 @@ bool newton_fd(void (*func)(fullVector<double> &, fullVector<double> &, void *),
     for (int i = 0; i < N; i++)
       x(i) -= relax * dx(i);
 
-    //    printf("dx = %12.5E\n",dx.norm());
     if(dx.norm() < tolx) return true;
   }
   return false;
diff --git a/Numeric/Numeric.h b/Numeric/Numeric.h
index 3e100539c6..a19affad2e 100644
--- a/Numeric/Numeric.h
+++ b/Numeric/Numeric.h
@@ -106,7 +106,7 @@ void gradSimplex(double *x, double *y, double *z, double *v, double *grad);
 double ComputeVonMises(double *val);
 double ComputeScalarRep(int numComp, double *val);
 void invert_singular_matrix3x3(double MM[3][3], double II[3][3]);
-bool newton_fd(void (*func)(fullVector<double> &, fullVector<double> &, void *),
+bool newton_fd(bool (*func)(fullVector<double> &, fullVector<double> &, void *),
                fullVector<double> &x, void *data, double relax=1., double tolx=1.e-6);
 double minimize_grad_fd(double (*func)(fullVector<double> &, void *),
                         fullVector<double> &x, void *data);
-- 
GitLab