From 03689a7702fe83c2013f78c612beaf214e56c11f Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Wed, 19 Nov 2008 21:55:00 +0000
Subject: [PATCH] more work on high order

---
 Geo/MElement.cpp | 109 +++++++++++++++++++++++++----------------------
 Geo/MVertex.cpp  |  23 +++++++---
 2 files changed, 76 insertions(+), 56 deletions(-)

diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp
index 5d340647af..7fe335040a 100644
--- a/Geo/MElement.cpp
+++ b/Geo/MElement.cpp
@@ -814,12 +814,52 @@ const gmshFunctionSpace* MTriangle::getFunctionSpace(int o) const
   return 0;
 }
 
-const int numSubEdges = 12;
+#define NUM_SUB_EDGES (_order)
 
-int MTriangleN::getNumFacesRep(){ return numSubEdges * numSubEdges; }
+int MTriangleN::getNumEdgesRep(){ return 3 * NUM_SUB_EDGES; }
+
+void MTriangleN::getEdgeRep(int num, double *x, double *y, double *z, SVector3 *n)
+{
+  int numSubEdges = NUM_SUB_EDGES;
+
+  n[0] = n[1] = n[2] = getFace(0).normal();
+
+  if (num < numSubEdges){
+    SPoint3 pnt1, pnt2;
+    pnt((double)num / numSubEdges, 0., 0.,pnt1);
+    pnt((double)(num + 1) / numSubEdges, 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();
+    return;
+  }  
+  if (num < 2 * numSubEdges){
+    SPoint3 pnt1, pnt2;
+    num -= numSubEdges;
+    pnt(1. - (double)num / numSubEdges, (double)num / numSubEdges, 0, pnt1);
+    pnt(1. - (double)(num + 1) / numSubEdges, (double)(num + 1) / numSubEdges, 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();
+    return ;
+  }  
+  {
+    SPoint3 pnt1, pnt2;
+    num -= 2 * numSubEdges;
+    pnt(0, (double)num / numSubEdges, 0,pnt1);
+    pnt(0, (double)(num + 1) / numSubEdges, 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();
+  }
+}
+
+int MTriangleN::getNumFacesRep(){ return NUM_SUB_EDGES * NUM_SUB_EDGES; }
 
 void MTriangleN::getFaceRep(int num, double *x, double *y, double *z, SVector3 *n)
 {
+  int numSubEdges = NUM_SUB_EDGES;
+
   //  on the first layer, we have (numSubEdges-1) * 2 + 1 triangles
   //  on the second layer, we have (numSubEdges-2) * 2 + 1 triangles
   //  on the ith layer, we have (numSubEdges-1-i) * 2 + 1 triangles
@@ -879,42 +919,6 @@ void MTriangleN::getFaceRep(int num, double *x, double *y, double *z, SVector3 *
   z[0] = pnt1.z(); z[1] = pnt2.z(); z[2] = pnt3.z();
 }
 
-int MTriangleN::getNumEdgesRep(){ return 3 * numSubEdges; }
-
-void MTriangleN::getEdgeRep(int num, double *x, double *y, double *z, SVector3 *n)
-{
-  n[0] = n[1] = n[2] = getFace(0).normal();
-  int N = getNumEdgesRep() / 3;
-  if (num < N){
-    SPoint3 pnt1, 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();
-    return;
-  }  
-  if (num < 2 * N){
-    SPoint3 pnt1, pnt2;
-    num -= N;
-    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();
-    return ;
-  }  
-  {
-    SPoint3 pnt1, pnt2;
-    num -= 2 * N;
-    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();
-  }
-}
-
 void MTriangle::getIntegrationPoints(int pOrder, int *npts, IntPt **pts) const
 {
 #if !defined(HAVE_GMSH_EMBEDDED)
@@ -1033,40 +1037,43 @@ const gmshFunctionSpace* MTetrahedron::getFunctionSpace(int o) const
   return 0;
 }
 
-int MTetrahedronN::getNumEdgesRep(){ return 6 * numSubEdges; }
+int MTetrahedronN::getNumEdgesRep(){ return 6 * NUM_SUB_EDGES; }
 
 void MTetrahedronN::getEdgeRep(int num, double *x, double *y, double *z, SVector3 *n)
 {
+  int numSubEdges = NUM_SUB_EDGES;
+
   static double pp[4][3] = {{0,0,0},{1,0,0},{0,1,0},{0,0,1}};
   static int ed [6][2] = {{0,1},{0,2},{0,3},{1,2},{1,3},{2,3}};
   int iEdge = num / numSubEdges;
   int iSubEdge = num % numSubEdges;  
 
-  
   int iVertex1 = ed [iEdge][0];
   int iVertex2 = ed [iEdge][1];
-  double t1 = (double) iSubEdge / (double) numSubEdges;
-  double u1 = pp[iVertex1][0] * (1.-t1) + pp[iVertex2][0] * t1;
-  double v1 = pp[iVertex1][1] * (1.-t1) + pp[iVertex2][1] * t1;
-  double w1 = pp[iVertex1][2] * (1.-t1) + pp[iVertex2][2] * t1;
+  double t1 = (double)iSubEdge / (double)numSubEdges;
+  double u1 = pp[iVertex1][0] * (1. - t1) + pp[iVertex2][0] * t1;
+  double v1 = pp[iVertex1][1] * (1. - t1) + pp[iVertex2][1] * t1;
+  double w1 = pp[iVertex1][2] * (1. - t1) + pp[iVertex2][2] * t1;
 
-  double t2 = (double) (iSubEdge+1) / (double) numSubEdges;
-  double u2 = pp[iVertex1][0] * (1.-t2) + pp[iVertex2][0] * t2;
-  double v2 = pp[iVertex1][1] * (1.-t2) + pp[iVertex2][1] * t2;
-  double w2 = pp[iVertex1][2] * (1.-t2) + pp[iVertex2][2] * t2;
+  double t2 = (double)(iSubEdge + 1) / (double)numSubEdges;
+  double u2 = pp[iVertex1][0] * (1. - t2) + pp[iVertex2][0] * t2;
+  double v2 = pp[iVertex1][1] * (1. - t2) + pp[iVertex2][1] * t2;
+  double w2 = pp[iVertex1][2] * (1. - t2) + pp[iVertex2][2] * t2;
 
   SPoint3 pnt1, pnt2;
-  pnt(u1,v1,w1,pnt1);
-  pnt(u2,v2,w2,pnt2);
+  pnt(u1, v1, w1, pnt1);
+  pnt(u2, v2, w2, 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();
 }
 
-int MTetrahedronN::getNumFacesRep(){ return 4 * numSubEdges * numSubEdges ; }
+int MTetrahedronN::getNumFacesRep(){ return 4 * NUM_SUB_EDGES * NUM_SUB_EDGES; }
 
 void MTetrahedronN::getFaceRep(int num, double *x, double *y, double *z, SVector3 *n)
 {
+  int numSubEdges = NUM_SUB_EDGES;
+
   static double pp[4][3] = {{0,0,0},{1,0,0},{0,1,0},{0,0,1}};
   static int fak [4][3] = {{0,1,2},{0,1,3},{0,2,3},{1,2,3}};
   int iFace    = num / (numSubEdges * numSubEdges);
diff --git a/Geo/MVertex.cpp b/Geo/MVertex.cpp
index 18515fba75..0269e59a53 100644
--- a/Geo/MVertex.cpp
+++ b/Geo/MVertex.cpp
@@ -250,6 +250,7 @@ bool reparamMeshEdgeOnFace(MVertex *v1, MVertex *v2, GFace *gf,
   if (p1.size() == 1 && p2.size() == 1){
     param1 = p1[0];
     param2 = p2[0];
+    return true;
   }
   else if (p1.size() == 1 && p2.size() == 2){
     double d1 = 
@@ -260,6 +261,7 @@ bool reparamMeshEdgeOnFace(MVertex *v1, MVertex *v2, GFace *gf,
       (p1[0].x() - p2[1].y()) * (p1[0].y() - p2[1].y());
     param1 = p1[0];
     param2 = d2 < d1 ? p2[1] : p2[0];
+    return true;
   }  
   else if (p2.size() == 1 && p1.size() == 2){
     double d1 = 
@@ -270,12 +272,20 @@ bool reparamMeshEdgeOnFace(MVertex *v1, MVertex *v2, GFace *gf,
       (p2[0].x() - p1[1].y()) * (p2[0].y() - p1[1].y());
     param1 = d2 < d1 ? p1[1] : p1[0];
     param2 = p2[0];
+    return true;
   }  
+  else if(p1.size() > 1 && p2.size() > 1){
+    param1 = p1[0];
+    param2 = p2[0];
+    // shout, both vertices are on seams
+    return false;
+  }
   else{
+    // brute force!
     param1 = gf->parFromPoint(SPoint3(v1->x(), v1->y(), v1->z()));
     param2 = gf->parFromPoint(SPoint3(v2->x(), v2->y(), v2->z()));
+    return true;
   }
-  return true;
 }
 
 bool reparamMeshVertexOnFace(MVertex *v, GFace *gf, SPoint2 &param)
@@ -296,7 +306,7 @@ bool reparamMeshVertexOnFace(MVertex *v, GFace *gf, SPoint2 &param)
     GVertex *gv = (GVertex*)v->onWhat();
     param = gv->reparamOnFace(gf, 1);
 
-    // shout if we could be on a seam
+    // shout, we could be on a seam
     std::list<GEdge*> ed = gv->edges();
     for(std::list<GEdge*>::iterator it = ed.begin(); it != ed.end(); it++)
       if((*it)->isSeam(gf)) return false;
@@ -307,16 +317,19 @@ bool reparamMeshVertexOnFace(MVertex *v, GFace *gf, SPoint2 &param)
     v->getParameter(0, t);
     param = ge->reparamOnFace(gf, t, 1);
 
-    // shout if we are on a seam
+    // shout, we are on a seam
     if(ge->isSeam(gf))
       return false;
   }
   else{
     double uu, vv;
-    if(v->onWhat() == gf && v->getParameter(0, uu) && v->getParameter(1, vv))
+    if(v->onWhat() == gf && v->getParameter(0, uu) && v->getParameter(1, vv)){
       param = SPoint2(uu, vv);
-    else 
+    }
+    else {
+      // brute force!
       param = gf->parFromPoint(SPoint3(v->x(), v->y(), v->z()));
+    }
   }
   return true;
 }
-- 
GitLab