From 36f1e7d39d9ab3b4670ba106d55060060691db53 Mon Sep 17 00:00:00 2001
From: Jean-Francois Remacle <jean-francois.remacle@uclouvain.be>
Date: Fri, 20 Jun 2008 12:15:44 +0000
Subject: [PATCH] High order meshes improved

---
 Geo/Geo.cpp             |  17 +++++-
 Geo/MElement.cpp        | 120 ++++++++++++++++++------------------
 Geo/MElement.h          |  40 ++++++------
 Geo/gmshFace.cpp        |   6 +-
 Mesh/HighOrder.cpp      | 131 +++++++++++++++++++++++++++++++++++++---
 Mesh/meshGRegion.cpp    |   7 +--
 Numeric/FunctionSpace.h |   2 +-
 Numeric/gsl_newt.cpp    |   8 +--
 8 files changed, 228 insertions(+), 103 deletions(-)

diff --git a/Geo/Geo.cpp b/Geo/Geo.cpp
index ff8ac7b3e3..933434a1a1 100644
--- a/Geo/Geo.cpp
+++ b/Geo/Geo.cpp
@@ -1,4 +1,4 @@
-// $Id: Geo.cpp,v 1.115 2008-06-20 05:51:36 geuzaine Exp $
+// $Id: Geo.cpp,v 1.116 2008-06-20 12:15:44 remacle Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -2963,6 +2963,7 @@ bool ProjectPointOnCurve(Curve *c, Vertex *v, Vertex *RES, Vertex *DER)
 bool ProjectPointOnSurface(Surface *s, Vertex &p, double u[2])
 {
   double x[3] = { 0.5, u[0], u[1] };
+  double res[3];
   Vertex vv;
   int check;
   SURFACE = s;
@@ -2971,6 +2972,14 @@ bool ProjectPointOnSurface(Surface *s, Vertex &p, double u[2])
   double UMAX = 1.;
   double VMIN = 0.;
   double VMAX = 1.;
+
+  newt(x, 2, &check, projectPS);
+  vv = InterpolateSurface(s, x[1], x[2], 0, 0);
+  projectPS(2,  x, res);
+
+  double resid = sqrt (res[1]*res[1]+res[2]*res[2]);
+  /*
+
   double eps = 1.e-6;
   int nn = 0;
   while(++nn < 20) {
@@ -2981,13 +2990,15 @@ bool ProjectPointOnSurface(Surface *s, Vertex &p, double u[2])
     x[1] = UMIN + (UMAX - UMIN) * ((rand() % 10000) / 10000.);
     x[2] = VMIN + (VMAX - VMIN) * ((rand() % 10000) / 10000.);
   }
+  */
   p.Pos.X = vv.Pos.X;
   p.Pos.Y = vv.Pos.Y;
   p.Pos.Z = vv.Pos.Z;
   u[0] = x[1];
   u[1] = x[2];
-  if(!check) {
-    return false;
+  if (resid > 1.e-6){
+    //    printf("error %12.5E\n",resid);
+    return false;  
   }
   return true;
 }
diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp
index a39f774418..659348380a 100644
--- a/Geo/MElement.cpp
+++ b/Geo/MElement.cpp
@@ -1,4 +1,4 @@
-// $Id: MElement.cpp,v 1.72 2008-06-10 12:59:12 remacle Exp $
+// $Id: MElement.cpp,v 1.73 2008-06-20 12:15:44 remacle Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -633,7 +633,7 @@ void MElement::writeBDF(FILE *fp, int format, int elementary)
   }
 }
 
-void MTriangle::jac(int ord, MVertex *vs[], double uu, double vv, double j[2][3])
+void MTriangle::jac(int ord, MVertex *vs[], double uu, double vv, double ww, double j[2][3])
 {
 #if defined(HAVE_GMSH_EMBEDDED)
   return;
@@ -643,21 +643,21 @@ void MTriangle::jac(int ord, MVertex *vs[], double uu, double vv, double j[2][3]
 
   if (!nf){
     switch(ord){
-    case 1: gmshFunctionSpaces::find(MSH_TRI_3).df(uu, vv, grads); break;
-    case 2: gmshFunctionSpaces::find(MSH_TRI_6).df(uu, vv, grads); break;
-    case 3: gmshFunctionSpaces::find(MSH_TRI_9).df(uu, vv, grads); break;
-    case 4: gmshFunctionSpaces::find(MSH_TRI_12).df(uu, vv, grads); break;
-    case 5: gmshFunctionSpaces::find(MSH_TRI_15I).df(uu, vv, grads); break;
+    case 1: gmshFunctionSpaces::find(MSH_TRI_3).df(uu, vv, ww, grads); break;
+    case 2: gmshFunctionSpaces::find(MSH_TRI_6).df(uu, vv, ww, grads); break;
+    case 3: gmshFunctionSpaces::find(MSH_TRI_9).df(uu, vv, ww, grads); break;
+    case 4: gmshFunctionSpaces::find(MSH_TRI_12).df(uu, vv, ww, grads); break;
+    case 5: gmshFunctionSpaces::find(MSH_TRI_15I).df(uu, vv,ww, grads); break;
     default: throw;
     }
   }
   else{
     switch(ord){
-    case 1: gmshFunctionSpaces::find(MSH_TRI_3).df(uu, vv, grads); break;
-    case 2: gmshFunctionSpaces::find(MSH_TRI_6).df(uu, vv, grads); break;
-    case 3: gmshFunctionSpaces::find(MSH_TRI_10).df(uu, vv, grads); break;
-    case 4: gmshFunctionSpaces::find(MSH_TRI_15).df(uu, vv, grads); break;
-    case 5: gmshFunctionSpaces::find(MSH_TRI_21).df(uu, vv, grads); break;
+    case 1: gmshFunctionSpaces::find(MSH_TRI_3).df(uu, vv, ww,grads); break;
+    case 2: gmshFunctionSpaces::find(MSH_TRI_6).df(uu, vv, ww,grads); break;
+    case 3: gmshFunctionSpaces::find(MSH_TRI_10).df(uu, vv, ww,grads); break;
+    case 4: gmshFunctionSpaces::find(MSH_TRI_15).df(uu, vv, ww,grads); break;
+    case 5: gmshFunctionSpaces::find(MSH_TRI_21).df(uu, vv, ww,grads); break;
     default: throw;
     }
   }
@@ -679,7 +679,7 @@ void MTriangle::jac(int ord, MVertex *vs[], double uu, double vv, double j[2][3]
 #endif
 }
 
-void MTriangle::pnt(int ord, MVertex *vs[], double uu, double vv, SPoint3 &p)
+void MTriangle::pnt(int ord, MVertex *vs[], double uu, double vv, double ww, SPoint3 &p)
 {
 #if !defined(HAVE_GMSH_EMBEDDED)
   double sf[256];
@@ -687,21 +687,21 @@ void MTriangle::pnt(int ord, MVertex *vs[], double uu, double vv, SPoint3 &p)
 
   if (!nf){
     switch(ord){
-    case 1: gmshFunctionSpaces::find(MSH_TRI_3).f(uu, vv, sf); break;
-    case 2: gmshFunctionSpaces::find(MSH_TRI_6).f(uu, vv, sf); break;
-    case 3: gmshFunctionSpaces::find(MSH_TRI_9).f(uu, vv, sf); break;
-    case 4: gmshFunctionSpaces::find(MSH_TRI_12).f(uu, vv, sf); break;
-    case 5: gmshFunctionSpaces::find(MSH_TRI_15I).f(uu, vv, sf); break;
+    case 1: gmshFunctionSpaces::find(MSH_TRI_3).f(uu, vv, ww,sf); break;
+    case 2: gmshFunctionSpaces::find(MSH_TRI_6).f(uu, vv, ww,sf); break;
+    case 3: gmshFunctionSpaces::find(MSH_TRI_9).f(uu, vv, ww,sf); break;
+    case 4: gmshFunctionSpaces::find(MSH_TRI_12).f(uu, vv, ww,sf); break;
+    case 5: gmshFunctionSpaces::find(MSH_TRI_15I).f(uu, vv, ww,sf); break;
     default: throw;
     }
   }
   else{
     switch(ord){
-    case 1: gmshFunctionSpaces::find(MSH_TRI_3).f(uu, vv, sf); break;
-    case 2: gmshFunctionSpaces::find(MSH_TRI_6).f(uu, vv, sf); break;
-    case 3: gmshFunctionSpaces::find(MSH_TRI_10).f(uu, vv, sf); break;
-    case 4: gmshFunctionSpaces::find(MSH_TRI_15).f(uu, vv, sf); break;
-    case 5: gmshFunctionSpaces::find(MSH_TRI_21).f(uu, vv, sf); break;
+    case 1: gmshFunctionSpaces::find(MSH_TRI_3).f(uu, vv, ww,sf); break;
+    case 2: gmshFunctionSpaces::find(MSH_TRI_6).f(uu, vv, ww,sf); break;
+    case 3: gmshFunctionSpaces::find(MSH_TRI_10).f(uu, vv, ww,sf); break;
+    case 4: gmshFunctionSpaces::find(MSH_TRI_15).f(uu, vv, ww,sf); break;
+    case 5: gmshFunctionSpaces::find(MSH_TRI_21).f(uu, vv, ww,sf); break;
     default: throw;
     }
   }
@@ -718,16 +718,16 @@ void MTriangle::pnt(int ord, MVertex *vs[], double uu, double vv, SPoint3 &p)
 #endif
 }
 
-void MTetrahedron::pnt(int ord, MVertex *vs[], double uu, double vv, SPoint3 &p)
+void MTetrahedron::pnt(int ord, MVertex *vs[], double uu, double vv, double ww,SPoint3 &p)
 {
 #if !defined(HAVE_GMSH_EMBEDDED)
   double sf[256];
   switch(ord){
-  case 1: gmshFunctionSpaces::find(MSH_TET_4).f(uu, vv, sf); break;
-  case 2: gmshFunctionSpaces::find(MSH_TET_10).f(uu, vv, sf); break;
-  case 3: gmshFunctionSpaces::find(MSH_TET_20).f(uu, vv, sf); break;
-  case 4: gmshFunctionSpaces::find(MSH_TET_35).f(uu, vv, sf); break;
-  case 5: gmshFunctionSpaces::find(MSH_TET_56).f(uu, vv, sf); break;
+  case 1: gmshFunctionSpaces::find(MSH_TET_4).f(uu, vv, ww,sf); break;
+  case 2: gmshFunctionSpaces::find(MSH_TET_10).f(uu, vv, ww,sf); break;
+  case 3: gmshFunctionSpaces::find(MSH_TET_20).f(uu, vv, ww,sf); break;
+  case 4: gmshFunctionSpaces::find(MSH_TET_35).f(uu, vv, ww,sf); break;
+  case 5: gmshFunctionSpaces::find(MSH_TET_56).f(uu, vv, ww,sf); break;
   default : throw;
   }
     
@@ -745,18 +745,18 @@ void MTetrahedron::pnt(int ord, MVertex *vs[], double uu, double vv, SPoint3 &p)
 #endif
 }
 
-void MTetrahedron::jac(int ord, MVertex *vs[], double uu, double vv, double j[3][3])
+void MTetrahedron::jac(int ord, MVertex *vs[], double uu, double vv, double ww, double j[3][3])
 {
 #if defined(HAVE_GMSH_EMBEDDED)
   return;
 #else
   double grads[256][2];
   switch(ord){
-  case 1: gmshFunctionSpaces::find(MSH_TET_4).df(uu, vv, grads); break;
-  case 2: gmshFunctionSpaces::find(MSH_TET_10).df(uu, vv, grads); break;
-  case 3: gmshFunctionSpaces::find(MSH_TET_20).df(uu, vv, grads); break;
-  case 4: gmshFunctionSpaces::find(MSH_TET_35).df(uu, vv, grads); break;
-  case 5: gmshFunctionSpaces::find(MSH_TET_56).df(uu, vv, grads); break;
+  case 1: gmshFunctionSpaces::find(MSH_TET_4).df(uu, vv, ww,grads); break;
+  case 2: gmshFunctionSpaces::find(MSH_TET_10).df(uu, vv, ww, grads); break;
+  case 3: gmshFunctionSpaces::find(MSH_TET_20).df(uu, vv, ww, grads); break;
+  case 4: gmshFunctionSpaces::find(MSH_TET_35).df(uu, vv, ww, grads); break;
+  case 5: gmshFunctionSpaces::find(MSH_TET_56).df(uu, vv, ww, grads); break;
   default: throw;
   }
  
@@ -798,8 +798,8 @@ void MTriangle6::getEdgeRep(int num, double *x, double *y, double *z, SVector3 *
   int N = getNumEdgesRep() / 3;
   if (num < N){
     SPoint3 pnt1, pnt2;
-    pnt((double)num / N, 0., pnt1);
-    pnt((double)(num + 1) / N, 0., pnt2);
+    pnt((double)num / N, 0., 0,pnt1);
+    pnt((double)(num + 1) / N, 0., 0,pnt2);
     x[0] = pnt1.x(); x[1] = pnt2.x();
     y[0] = pnt1.y(); y[1] = pnt2.y();
     z[0] = pnt1.z(); z[1] = pnt2.z();
@@ -808,8 +808,8 @@ void MTriangle6::getEdgeRep(int num, double *x, double *y, double *z, SVector3 *
   if (num < 2 * N){
     SPoint3 pnt1, pnt2;
     num -= N;
-    pnt(1. - (double)num / N, (double)num / N, pnt1);
-    pnt(1. - (double)(num + 1) / N, (double)(num + 1) / N, pnt2);
+    pnt(1. - (double)num / N, (double)num / N, 0,pnt1);
+    pnt(1. - (double)(num + 1) / N, (double)(num + 1) / N, 0,pnt2);
     x[0] = pnt1.x(); x[1] = pnt2.x();
     y[0] = pnt1.y(); y[1] = pnt2.y();
     z[0] = pnt1.z(); z[1] = pnt2.z();
@@ -818,15 +818,15 @@ void MTriangle6::getEdgeRep(int num, double *x, double *y, double *z, SVector3 *
   {
     SPoint3 pnt1, pnt2;
     num -= 2 * N;
-    pnt(0, (double)num / N, pnt1);
-    pnt(0, (double)(num + 1) / N, pnt2);
+    pnt(0, (double)num / N, 0,pnt1);
+    pnt(0, (double)(num + 1) / N, 0,pnt2);
     x[0] = pnt1.x(); x[1] = pnt2.x();
     y[0] = pnt1.y(); y[1] = pnt2.y();
     z[0] = pnt1.z(); z[1] = pnt2.z();
   }
 }
 
-const int numSubEdges = 6;
+const int numSubEdges = 12;
 
 int MTriangleN::getNumFacesRep(){ return numSubEdges * numSubEdges; }
 
@@ -853,20 +853,20 @@ void MTriangleN::getFaceRep(int num, double *x, double *y, double *z, SVector3 *
   SPoint3 pnt1, pnt2, pnt3;
   double J1[2][3],J2[2][3],J3[2][3];
   if (ix %2 == 0){
-    pnt(ix/2*d, iy*d, pnt1);
-    pnt((ix/2+1)*d, iy*d, pnt2);
-    pnt(ix/2*d, (iy+1)*d, pnt3);
-    jac(ix/2*d, iy*d, J1);
-    jac((ix/2+1)*d, iy*d, J2);
-    jac(ix/2*d, (iy+1)*d, J3);
+    pnt(ix/2*d, iy*d, 0,pnt1);
+    pnt((ix/2+1)*d, iy*d, 0,pnt2);
+    pnt(ix/2*d, (iy+1)*d, 0,pnt3);
+    jac(ix/2*d, iy*d, 0,J1);
+    jac((ix/2+1)*d, iy*d, 0,J2);
+    jac(ix/2*d, (iy+1)*d, 0,J3);
   }
   else{
-    pnt((ix/2+1)*d, iy*d, pnt1);
-    pnt((ix/2+1)*d, (iy+1)*d, pnt2);
-    pnt(ix/2*d, (iy+1)*d, pnt3);
-    jac((ix/2+1)*d, iy*d, J1);
-    jac((ix/2+1)*d, (iy+1)*d, J2);
-    jac(ix/2*d, (iy+1)*d, J3);
+    pnt((ix/2+1)*d, iy*d, 0,pnt1);
+    pnt((ix/2+1)*d, (iy+1)*d, 0,pnt2);
+    pnt(ix/2*d, (iy+1)*d, 0,pnt3);
+    jac((ix/2+1)*d, iy*d, 0,J1);
+    jac((ix/2+1)*d, (iy+1)*d, 0,J2);
+    jac(ix/2*d, (iy+1)*d, 0,J3);
   }
   {
     SVector3 d1 (J1[0][0],J1[0][1],J1[0][2]);
@@ -901,8 +901,8 @@ void MTriangleN::getEdgeRep(int num, double *x, double *y, double *z, SVector3 *
   int N = getNumEdgesRep() / 3;
   if (num < N){
     SPoint3 pnt1, pnt2;
-    pnt((double)num / N, 0., pnt1);
-    pnt((double)(num + 1) / N, 0., pnt2);
+    pnt((double)num / N, 0., 0,pnt1);
+    pnt((double)(num + 1) / N, 0., 0,pnt2);
     x[0] = pnt1.x(); x[1] = pnt2.x();
     y[0] = pnt1.y(); y[1] = pnt2.y();
     z[0] = pnt1.z(); z[1] = pnt2.z();
@@ -911,8 +911,8 @@ void MTriangleN::getEdgeRep(int num, double *x, double *y, double *z, SVector3 *
   if (num < 2 * N){
     SPoint3 pnt1, pnt2;
     num -= N;
-    pnt(1. - (double)num / N, (double)num / N, pnt1);
-    pnt(1. - (double)(num + 1) / N, (double)(num + 1) / N, pnt2);
+    pnt(1. - (double)num / N, (double)num / N, 0,pnt1);
+    pnt(1. - (double)(num + 1) / N, (double)(num + 1) / N, 0,pnt2);
     x[0] = pnt1.x(); x[1] = pnt2.x();
     y[0] = pnt1.y(); y[1] = pnt2.y();
     z[0] = pnt1.z(); z[1] = pnt2.z();
@@ -921,8 +921,8 @@ void MTriangleN::getEdgeRep(int num, double *x, double *y, double *z, SVector3 *
   {
     SPoint3 pnt1, pnt2;
     num -= 2 * N;
-    pnt(0, (double)num / N, pnt1);
-    pnt(0, (double)(num + 1) / N, pnt2);
+    pnt(0, (double)num / N, 0,pnt1);
+    pnt(0, (double)(num + 1) / N, 0,pnt2);
     x[0] = pnt1.x(); x[1] = pnt2.x();
     y[0] = pnt1.y(); y[1] = pnt2.y();
     z[0] = pnt1.z(); z[1] = pnt2.z();
diff --git a/Geo/MElement.h b/Geo/MElement.h
index e25d730ff5..707c9ab7c6 100644
--- a/Geo/MElement.h
+++ b/Geo/MElement.h
@@ -444,15 +444,15 @@ class MTriangle : public MElement {
   {
     MVertex *tmp = _v[1]; _v[1] = _v[2]; _v[2] = tmp;
   }
-  virtual void jac(int order, MVertex *verts[], double u, double v, double jac[2][3]);
-  virtual void jac(double u, double v, double j[2][3])
+  virtual void jac(int order, MVertex *verts[], double u, double v, double w, double jac[2][3]);
+  virtual void jac(double u, double v, double w, double j[2][3])
   {
-    jac(1, 0, u, v, j);
+    jac(1, 0, u, v, w, j);
   }
-  virtual void pnt(int order, MVertex *verts[], double u, double v, SPoint3 &);
-  virtual void pnt(double u, double v, SPoint3 &p)
+  virtual void pnt(int order, MVertex *verts[], double u, double v, double w, SPoint3 &);
+  virtual void pnt(double u, double v, double w, SPoint3 &p)
   {
-    pnt(1, 0, u, v, p);
+    pnt(1, 0, u, v, w, p);
   }
   virtual void getShapeFunction(int num, double u, double v, double w, double &s) 
   {
@@ -543,13 +543,13 @@ class MTriangle6 : public MTriangle {
     tmp = _v[1]; _v[1] = _v[2]; _v[2] = tmp;
     tmp = _vs[0]; _vs[0] = _vs[2]; _vs[2] = tmp;
   }
-  virtual void jac(double u, double v, double j[2][3])
+  virtual void jac(double u, double v, double w, double j[2][3])
   {
-    MTriangle::jac(2, _vs, u, v, j);
+    MTriangle::jac(2, _vs, u, v, w, j);
   }
-  virtual void pnt(double u, double v, SPoint3 &p)
+  virtual void pnt(double u, double v, double w, SPoint3 &p)
   {
-    MTriangle::pnt(2, _vs, u, v, p);
+    MTriangle::pnt(2, _vs, u, v, w, p);
   }
 };
 
@@ -616,13 +616,13 @@ class MTriangleN : public MTriangle {
     inv.insert(inv.begin(), _vs.rbegin(), _vs.rend());
     _vs = inv;
   }
-  virtual void jac(double u, double v, double j[2][3])
+  virtual void jac(double u, double v, double w, double j[2][3])
   {
-    MTriangle::jac(_order, &(*(_vs.begin())), u, v, j);
+    MTriangle::jac(_order, &(*(_vs.begin())), u, v, w, j);
   }
-  virtual void pnt(double u, double v, SPoint3 &p)
+  virtual void pnt(double u, double v, double w, SPoint3 &p)
   {
-    MTriangle::pnt(_order, &(*(_vs.begin())), u, v, p);
+    MTriangle::pnt(_order, &(*(_vs.begin())), u, v, w, p);
   }
 };
 
@@ -933,8 +933,8 @@ class MTetrahedron : public MElement {
     default : s = 0.; break;
     }
   }
-  virtual void jac(int order, MVertex *verts[], double u, double v, double jac[3][3]);
-  virtual void pnt(int order, MVertex *verts[], double u, double v, SPoint3 &);
+  virtual void jac(int order, MVertex *verts[], double u, double v, double w, double jac[3][3]);
+  virtual void pnt(int order, MVertex *verts[], double u, double v, double w, SPoint3 &);
   virtual void getGradShapeFunction(int num, double u, double v, double w, double s[3]) 
   {
     switch(num) {
@@ -1081,13 +1081,13 @@ class MTetrahedronN : public MTetrahedron {
     inv.insert(inv.begin(), _vs.rbegin(), _vs.rend());
     _vs = inv;
   }
-  virtual void jac(double u, double v, double j[3][3])
+  virtual void jac(double u, double v, double w, double j[3][3])
   {
-    MTetrahedron::jac(_order, &(*(_vs.begin())), u, v, j);
+    MTetrahedron::jac(_order, &(*(_vs.begin())), u, v, w, j);
   }
-  virtual void pnt(double u, double v, SPoint3 &p)
+  virtual void pnt(double u, double v, double w, SPoint3 &p)
   {
-    MTetrahedron::pnt(_order, &(*(_vs.begin())), u, v, p);
+    MTetrahedron::pnt(_order, &(*(_vs.begin())), u, v, w, p);
   }
 };
 
diff --git a/Geo/gmshFace.cpp b/Geo/gmshFace.cpp
index 9897d25ba6..4c0f220c05 100644
--- a/Geo/gmshFace.cpp
+++ b/Geo/gmshFace.cpp
@@ -1,4 +1,4 @@
-// $Id: gmshFace.cpp,v 1.62 2008-06-20 11:50:00 geuzaine Exp $
+// $Id: gmshFace.cpp,v 1.63 2008-06-20 12:15:44 remacle Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -207,7 +207,9 @@ GPoint gmshFace::closestPoint(const SPoint3 & qp, const double initialGuess[2])
   v.Pos.X = qp.x();
   v.Pos.Y = qp.y();
   v.Pos.Z = qp.z();
-  ProjectPointOnSurface(s, v, u);
+  bool result = ProjectPointOnSurface(s, v, u);
+  if (!result)
+    printf("Project Point on surface %d \n",result);
   return GPoint(v.Pos.X, v.Pos.Y, v.Pos.Z, this, u);
 }
 
diff --git a/Mesh/HighOrder.cpp b/Mesh/HighOrder.cpp
index 70eb301412..5d5096205b 100644
--- a/Mesh/HighOrder.cpp
+++ b/Mesh/HighOrder.cpp
@@ -1,4 +1,4 @@
-// $Id: HighOrder.cpp,v 1.30 2008-06-10 08:37:34 remacle Exp $
+// $Id: HighOrder.cpp,v 1.31 2008-06-20 12:15:44 remacle Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -292,7 +292,7 @@ void getEdgeVertices(GEdge *ge, MElement *ele, std::vector<MVertex*> &ve,
           relax /= 2.0;
           if (relax < 1.e-2)break;
         } 
-        if (relax < 1.e-2)printf("failure in computing equidistant parameters %g\n",relax);
+        if (relax < 1.e-2)Msg::Warning("failure in computing equidistant parameters %g",relax);
       }
       std::vector<MVertex*> temp;      
       for(int j = 0; j < nPts; j++){
@@ -401,6 +401,114 @@ void getEdgeVertices(GRegion *gr, MElement *ele, std::vector<MVertex*> &ve,
   }
 }
 
+void getFaceVertices(GFace *gf, 
+		     MElement *incomplete, 
+		     MElement *ele, 
+		     std::vector<MVertex*> &vf,
+                     faceContainer &faceVertices, 
+		     bool linear, int nPts = 1){
+  Double_Matrix points;
+  int start = 0;
+  
+  switch (nPts){
+  case 2 :
+    points = gmshFunctionSpaces::find(MSH_TRI_10).points;
+    start = 9;
+    break;
+  case 3 :
+    points = gmshFunctionSpaces::find(MSH_TRI_15).points;
+    start = 12;
+    break;
+  case 4 :
+    points = gmshFunctionSpaces::find(MSH_TRI_21).points;
+    start = 15;
+    break;
+  default :  
+    // do nothing (e.g. for quad faces)
+    break;
+  }
+
+  for(int i = 0; i < ele->getNumFaces(); i++){
+    MFace face = ele->getFace(i);
+    std::vector<MVertex*> p;
+    face.getOrderedVertices(p);
+    if(faceVertices.count(p)){
+      vf.insert(vf.end(), faceVertices[p].begin(), faceVertices[p].end());
+    }
+    else{
+      SPoint2 pts[20];
+      bool reparamOK = true;
+      if(!linear && 
+         gf->geomType() != GEntity::DiscreteSurface &&
+         gf->geomType() != GEntity::BoundaryLayerSurface){
+	for (int k=0;k<incomplete->getNumVertices(); k++){
+	  reparamOK &= reparamOnFace(incomplete->getVertex(k), gf, pts[k]);
+	}
+      }
+      if(face.getNumVertices() == 3){ // triangles
+        for(int k = start ; k < points.size1() ; k++){
+          MVertex *v;
+          const double t1 = points(k, 0);
+          const double t2 = points(k, 1);
+          if(!reparamOK || linear || gf->geomType() == GEntity::DiscreteSurface){
+            SPoint3 pc = face.interpolate(t1, t2);
+            v = new MVertex(pc.x(), pc.y(), pc.z(), gf);
+          }
+          else{
+	    double X(0),Y(0),Z(0),GUESS[2]={0,0};
+	    for (int j=0; j<incomplete->getNumVertices(); j++){
+	      double sf ; incomplete->getShapeFunction(j,t1,t2,0,sf);
+	      MVertex *vt = incomplete->getVertex(j);
+	      X += sf * vt->x();
+	      Y += sf * vt->y();
+	      Z += sf * vt->z();
+	      GUESS[0] += sf * pts[j][0];
+	      GUESS[1] += sf * pts[j][1];
+	    }
+	    GPoint gp = gf->closestPoint(SPoint3(X,Y,Z),GUESS);
+	    //	    printf("%g %g %g -- %g %g %g\n",X,Y,Z,gp.x(),gp.y(),gp.z());
+            v = new MFaceVertex(gp.x(), gp.y(), gp.z(), gf, gp.u(), gp.v());
+          }
+          faceVertices[p].push_back(v);
+          gf->mesh_vertices.push_back(v);
+          vf.push_back(v);
+        }
+      }
+      else if(face.getNumVertices() == 4){ // quadrangles
+        for(int j = 0; j < nPts; j++){
+          for(int k = 0; k < nPts; k++){
+            MVertex *v;
+            // parameters are between -1 and 1
+            double t1 = 2. * (double)(j + 1) / (nPts + 1) - 1.;
+            double t2 = 2. * (double)(k + 1) / (nPts + 1) - 1.;
+            if(!reparamOK || linear || gf->geomType() == GEntity::DiscreteSurface){
+              SPoint3 pc = face.interpolate(t1, t2);
+              v = new MVertex(pc.x(), pc.y(), pc.z(), gf);
+            }
+            else{
+              double uc = 0.25 * ((1 - t1) * (1 - t2) * pts[0][0] + 
+                                  (1 + t1) * (1 - t2) * pts[1][0] + 
+                                  (1 + t1) * (1 + t2) * pts[2][0] + 
+                                  (1 - t1) * (1 + t2) * pts[3][0]); 
+              double vc = 0.25 * ((1 - t1) * (1 - t2) * pts[0][1] + 
+                                  (1 + t1) * (1 - t2) * pts[1][1] + 
+                                  (1 + t1) * (1 + t2) * pts[2][1] + 
+                                  (1 - t1) * (1 + t2) * pts[3][1]); 
+              GPoint pc = gf->point(uc, vc);
+              v = new MFaceVertex(pc.x(), pc.y(), pc.z(), gf, uc, vc);
+            }
+            faceVertices[p].push_back(v);
+            gf->mesh_vertices.push_back(v);
+            vf.push_back(v);
+          }
+        }
+      }
+      else throw; // not tri or quad
+    }
+  }  
+}
+
+
 void getFaceVertices(GFace *gf, MElement *ele, std::vector<MVertex*> &vf,
                      faceContainer &faceVertices, bool linear, int nPts = 1)
 {
@@ -582,7 +690,14 @@ void setHighOrder(GFace *gf, edgeContainer &edgeVertices,
                           ve, nPts + 1));
       }
       else{
-        getFaceVertices(gf, t, vf, faceVertices, linear, nPts);
+	if (gf->geomType() == GEntity::Plane){
+	  getFaceVertices(gf, t, vf, faceVertices, linear, nPts);
+	}
+	else{
+	MTriangleN incpl (t->getVertex(0), t->getVertex(1), t->getVertex(2),
+                          ve, nPts + 1);
+        getFaceVertices(gf, &incpl, t, vf, faceVertices, linear, nPts);
+	}
         ve.insert(ve.end(), vf.begin(), vf.end());
         triangles2.push_back
           (new MTriangleN(t->getVertex(0), t->getVertex(1), t->getVertex(2),
@@ -798,7 +913,7 @@ static double mesh_functional_distorsion(MTriangle *t, double u, double v)
 {
   // compute uncurved element jacobian d_u x and d_v x
   double mat[2][3];  
-  t->jac(1, 0, 0, 0, mat);
+  t->jac(1, 0, 0, 0, 0,mat);
   double v1[3] = {mat[0][0], mat[0][1], mat[0][2]};
   double v2[3] = {mat[1][0], mat[1][1], mat[1][2]};
   double normal1[3];
@@ -806,7 +921,7 @@ static double mesh_functional_distorsion(MTriangle *t, double u, double v)
   double nn = sqrt(DSQR(normal1[0]) + DSQR(normal1[1]) + DSQR(normal1[2]));
   
   // compute uncurved element jacobian d_u x and d_v x
-  t->jac(u, v, mat);
+  t->jac(u, v, 0,mat);
   double v1b[3] = {mat[0][0], mat[0][1], mat[0][2]};
   double v2b[3] = {mat[1][0], mat[1][1], mat[1][2]};
   double normal[3];
@@ -825,7 +940,7 @@ void getMinMaxJac (MTriangle *t, double &minJ, double &maxJ)
 {
   double mat[2][3];  
   int n = 3;
-  t->jac(1, 0, 0, 0, mat);
+  t->jac(1, 0, 0, 0, 0,mat);
   double v1[3] = {mat[0][0], mat[0][1], mat[0][2]};
   double v2[3] = {mat[1][0], mat[1][1], mat[1][2]};
   double normal1[3], normal[3];
@@ -833,7 +948,7 @@ void getMinMaxJac (MTriangle *t, double &minJ, double &maxJ)
   double nn = sqrt(DSQR(normal1[0]) + DSQR(normal1[1]) + DSQR(normal1[2]));
   for(int i = 0; i < n; i++){
     for(int k = 0; k < n - i; k++){
-      t->jac((double)i / (n - 1), (double)k / (n - 1), mat);
+      t->jac((double)i / (n - 1), (double)k / (n - 1), 0,mat);
       double v1b[3] = {mat[0][0], mat[0][1], mat[0][2]};
       double v2b[3] = {mat[1][0], mat[1][1], mat[1][2]};
       prodve(v1b, v2b, normal);
@@ -1256,7 +1371,7 @@ void printJacobians(GModel *m, const char *nm)
           SPoint3 pt;
           double u = (double)i / (n - 1);
           double v = (double)k / (n - 1);         
-          t->pnt(u,v, pt);        
+          t->pnt(u,v,0, pt);        
           D[i][k] = mesh_functional_distorsion (t,u,v);
           X[i][k] = pt.x();
           Y[i][k] = pt.y();
diff --git a/Mesh/meshGRegion.cpp b/Mesh/meshGRegion.cpp
index 09b80552a0..3a434049a4 100644
--- a/Mesh/meshGRegion.cpp
+++ b/Mesh/meshGRegion.cpp
@@ -1,4 +1,4 @@
-// $Id: meshGRegion.cpp,v 1.53 2008-06-20 11:50:00 geuzaine Exp $
+// $Id: meshGRegion.cpp,v 1.54 2008-06-20 12:15:44 remacle Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -194,10 +194,7 @@ void TransferTetgenMesh(GRegion *gr, tetgenio &in, tetgenio &out,
 		     v[j]->x(), v[j]->y(), v[j]->z(),gp.x(),gp.y(),gp.z());
 
 	  // To be safe, we should ensure that this mesh motion does not lead to an invalid mesh !!!!
-	  v[j]->x() = gp.x();
-	  v[j]->y() = gp.y();
-	  v[j]->z() = gp.z();
-	  v1b = new MFaceVertex(v[j]->x(), v[j]->y(), v[j]->z(), gf,gp.u(),gp.v());
+	  v1b = new MFaceVertex(gp.x(),gp.y(),gp.z(),gf,gp.u(),gp.v());
 	}
 	else{
 	  v1b = new MVertex(v[j]->x(), v[j]->y(), v[j]->z(),gf);
diff --git a/Numeric/FunctionSpace.h b/Numeric/FunctionSpace.h
index b568ea9972..267347278d 100644
--- a/Numeric/FunctionSpace.h
+++ b/Numeric/FunctionSpace.h
@@ -80,7 +80,7 @@ struct gmshFunctionSpace
       }
     }
   }
-  inline void df(double u, double v, double grads[][2]) const
+  inline void df(double u, double v, double w,double grads[][2]) const
   {
     double p[256][2];
     computePows(u, v, p);
diff --git a/Numeric/gsl_newt.cpp b/Numeric/gsl_newt.cpp
index b95233f572..7194d47cdd 100644
--- a/Numeric/gsl_newt.cpp
+++ b/Numeric/gsl_newt.cpp
@@ -1,4 +1,4 @@
-// $Id: gsl_newt.cpp,v 1.19 2008-05-04 08:31:16 geuzaine Exp $
+// $Id: gsl_newt.cpp,v 1.20 2008-06-20 12:15:44 remacle Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -37,7 +37,7 @@
 #include <gsl/gsl_linalg.h>
 
 #define MAX_DIM_NEWT 10
-#define MAXITER 10000
+#define MAXITER 100
 #define PREC 1.e-8
 
 int nrdim;
@@ -101,8 +101,8 @@ void newt(double x[], int n, int *check,
     status = gsl_multiroot_fsolver_iterate(s);
     // Msg::Info("status %d %d %d %lf %lf\n",
     //     status,n,iter,gsl_vector_get(s->x,0),gsl_vector_get(s->x,1));
-    if(status)
-      break;    // solver problem
+     if(status)
+       break;    // solver problem
     status = gsl_multiroot_test_residual(s->f, n * PREC);
   }
   while(status == GSL_CONTINUE && iter < MAXITER);
-- 
GitLab