From 67e8a047902ce6c75239dcefa1b69155fefbb8a7 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Sat, 13 Jul 2013 18:13:24 +0000
Subject: [PATCH] more ho cleanup

---
 Common/CommandLine.cpp                        | 19 +++---
 Common/Context.cpp                            |  2 +-
 Common/Context.h                              |  2 +-
 Common/DefaultOptions.h                       |  8 +--
 Common/Options.cpp                            |  8 +--
 Common/Options.h                              |  2 +-
 Fltk/optionWindow.cpp                         |  4 +-
 Mesh/HighOrder.cpp                            | 38 ++----------
 Mesh/highOrderTools.cpp                       | 60 +++++--------------
 Solver/multiscaleLaplace.cpp                  |  3 -
 .../HighOrderMeshOptimizer/OptHomElastic.cpp  |  0
 .../HighOrderMeshOptimizer/OptHomElastic.h    |  0
 doc/VERSIONS.txt                              |  2 +
 13 files changed, 48 insertions(+), 100 deletions(-)
 rename Mesh/highOrderSmoother.cpp => contrib/HighOrderMeshOptimizer/OptHomElastic.cpp (100%)
 rename Mesh/highOrderSmoother.h => contrib/HighOrderMeshOptimizer/OptHomElastic.h (100%)

diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index f251a1a924..506ddd80c7 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -76,11 +76,8 @@ std::vector<std::pair<std::string, std::string> > GetUsage()
                                         "delquad, del3d, front3d, mmg3d)"));
   s.push_back(mp("-smooth int",        "Set number of mesh smoothing steps"));
   s.push_back(mp("-order int",         "Set mesh order (1, ..., 5)"));
-  s.push_back(mp("-hoOptimize",        "Optimize high order meshes"));
-  s.push_back(mp("-hoMindisto float",  "Min high-order element quality before optim (0.0->1.0)"));
-  s.push_back(mp("-hoNLayers int",     "Number of high order element layers to optimize"));
-  s.push_back(mp("-hoElasticity float","Poisson ration for elasticity analogy (nu in [-1.0,0.5])"));
   s.push_back(mp("-optimize[_netgen]", "Optimize quality of tetrahedral elements"));
+  s.push_back(mp("-optimize_ho",       "Optimize high order meshes"));
   s.push_back(mp("-optimize_lloyd",    "Optimize 2D meshes using Lloyd algorithm"));
   s.push_back(mp("-microstructure",    "Generate polycrystal Voronoi geometry"));
   s.push_back(mp("-clscale float",     "Set global mesh element size scaling factor"));
@@ -459,25 +456,29 @@ void GetOptions(int argc, char *argv[])
         CTX::instance()->mesh.optimizeNetgen = 1;
         i++;
       }
-      else if(!strcmp(argv[i] + 1, "hoOptimize")) {
+      else if(!strcmp(argv[i] + 1, "optimize_ho") ||
+              !strcmp(argv[i] + 1, "hoOptimize")) {
         i++;
-        opt_mesh_smooth_internal_edges(0, GMSH_SET, 1);
+        opt_mesh_ho_optimize(0, GMSH_SET, 1);
       }
-      else if(!strcmp(argv[i] + 1, "hoMindisto")) {
+      else if(!strcmp(argv[i] + 1, "ho_mindisto") ||
+              !strcmp(argv[i] + 1, "hoMindisto")) {
         i++;
         if(argv[i])
           opt_mesh_ho_mindisto(0, GMSH_SET, atof(argv[i++]));
         else
           Msg::Fatal("Missing number");
       }
-      else if(!strcmp(argv[i] + 1, "hoElasticity")) {
+      else if(!strcmp(argv[i] + 1, "ho_poisson") ||
+              !strcmp(argv[i] + 1, "hoElasticity")) {
         i++;
         if(argv[i])
           opt_mesh_ho_poisson(0, GMSH_SET, atof(argv[i++]));
         else
           Msg::Fatal("Missing number");
       }
-      else if(!strcmp(argv[i] + 1, "hoNlayers")) {
+      else if(!strcmp(argv[i] + 1, "ho_nlayers") ||
+              !strcmp(argv[i] + 1, "hoNlayers")) {
         i++;
         if(argv[i])
           opt_mesh_ho_nlayers(0, GMSH_SET, atoi(argv[i++]));
diff --git a/Common/Context.cpp b/Common/Context.cpp
index e590c67d9e..9f2f33dc99 100644
--- a/Common/Context.cpp
+++ b/Common/Context.cpp
@@ -83,7 +83,7 @@ CTX::CTX() : gamepad(0)
   mesh.prisms = mesh.pyramids = mesh.hexahedra = 0;
   mesh.volumesEdges = mesh.volumesFaces = mesh.surfacesEdges = mesh.surfacesFaces = 0;
   mesh.volumesFaces = mesh.surfacesEdges = mesh.surfacesFaces = 0;
-  mesh.smoothInternalEdges = mesh.smoothNormals = mesh.reverseAllNormals = 0;
+  mesh.hoOptimize = mesh.smoothNormals = mesh.reverseAllNormals = 0;
   mesh.explode = mesh.angleSmoothNormals = 0.;
   mesh.numSubEdges = 0;
   mesh.colorCarousel = 0;
diff --git a/Common/Context.h b/Common/Context.h
index b90539d770..c41cdc3907 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -41,7 +41,7 @@ struct contextMeshOptions {
   int remeshParam, remeshAlgo;
   int order, secondOrderLinear, secondOrderIncomplete;
   int secondOrderExperimental, meshOnlyVisible;
-  int smoothInternalEdges, minCircPoints, minCurvPoints;
+  int hoOptimize, minCircPoints, minCurvPoints;
   int smoothNLayers;
   double smoothDistoThreshold, smoothPoissonRatio;
   int saveAll, saveTri, saveGroupsOfNodes, binary, bdfFieldFormat, saveParametric;
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index ef6f041c0d..744de7d00c 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -960,12 +960,12 @@ StringXNumber MeshOptions_Number[] = {
   { F|O, "Hexahedra" , opt_mesh_hexahedra , 1. ,
     "Display mesh hexahedra?" },
   { F|0, "HighOrderNumLayers", opt_mesh_ho_nlayers, 3.,
-    "Number of high order mesh elements to consider for optimization."},
-  { F|O, "HighOrderOptimize" , opt_mesh_smooth_internal_edges , 0.,
-    "Number of smoothing steps of internal edges for high order meshes" },
+    "Number of high order mesh elements to consider for optimization"},
+  { F|O, "HighOrderOptimize" , opt_mesh_ho_optimize , 0.,
+    "Optimize high order meshes?" },
   { F|0, "HighOrderPoissonRatio", opt_mesh_ho_poisson, 0.33,
     "Poisson ratio of the material used in the elastic smoother for high order meshes."
-    "Must be between -1.0 and 0.5, excluded."},
+    "Must be between -1.0 and 0.5, excluded"},
   { F|O, "HighOrderSmoothingThreshold", opt_mesh_ho_mindisto, 0.5,
     "Distorition threshold when choosing which high order element to optimize."},
 
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 1a6c89827e..5e6e48f817 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -5590,16 +5590,16 @@ double opt_mesh_order(OPT_ARGS_NUM)
   return CTX::instance()->mesh.order;
 }
 
-double opt_mesh_smooth_internal_edges(OPT_ARGS_NUM)
+double opt_mesh_ho_optimize(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX::instance()->mesh.smoothInternalEdges = (int)val;
+    CTX::instance()->mesh.hoOptimize = (int)val;
 #if defined(HAVE_FLTK)
   if(FlGui::available() && (action & GMSH_GUI))
     FlGui::instance()->options->mesh.butt[3]->value
-      (CTX::instance()->mesh.smoothInternalEdges);
+      (CTX::instance()->mesh.hoOptimize);
 #endif
-  return CTX::instance()->mesh.smoothInternalEdges;
+  return CTX::instance()->mesh.hoOptimize;
 }
 
 double opt_mesh_ho_nlayers(OPT_ARGS_NUM)
diff --git a/Common/Options.h b/Common/Options.h
index 46ca772bf6..3b156db98d 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -446,7 +446,7 @@ double opt_mesh_allow_swap_edge_angle(OPT_ARGS_NUM);
 double opt_mesh_min_curv_points(OPT_ARGS_NUM);
 double opt_mesh_multiple_passes(OPT_ARGS_NUM);
 double opt_mesh_order(OPT_ARGS_NUM);
-double opt_mesh_smooth_internal_edges(OPT_ARGS_NUM);
+double opt_mesh_ho_optimize(OPT_ARGS_NUM);
 double opt_mesh_ho_nlayers(OPT_ARGS_NUM);
 double opt_mesh_ho_mindisto(OPT_ARGS_NUM);
 double opt_mesh_ho_poisson(OPT_ARGS_NUM);
diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp
index 5c12f19805..8d3eeaf74b 100644
--- a/Fltk/optionWindow.cpp
+++ b/Fltk/optionWindow.cpp
@@ -492,7 +492,9 @@ static void mesh_options_ok_cb(Fl_Widget *w, void *data)
   opt_mesh_optimize_netgen(0, GMSH_SET, o->mesh.butt[24]->value());
   opt_mesh_remove_4_triangles(0,GMSH_SET, o->mesh.butt[25]->value());
   opt_mesh_order(0, GMSH_SET, o->mesh.value[3]->value());
-  opt_mesh_smooth_internal_edges(0, GMSH_SET, o->mesh.butt[3]->value());
+
+  opt_mesh_ho_optimize(0, GMSH_SET, o->mesh.butt[3]->value());
+
   opt_mesh_second_order_incomplete(0, GMSH_SET, o->mesh.butt[4]->value());
   opt_mesh_points(0, GMSH_SET, o->mesh.butt[6]->value());
   opt_mesh_lines(0, GMSH_SET, o->mesh.butt[7]->value());
diff --git a/Mesh/HighOrder.cpp b/Mesh/HighOrder.cpp
index 71dde47bea..ffcf0b3b23 100644
--- a/Mesh/HighOrder.cpp
+++ b/Mesh/HighOrder.cpp
@@ -1252,7 +1252,7 @@ void getMeshInfoForHighOrder(GModel *gm, int &meshOrder, bool &complete,
   }
 }
 
-void ElasticAnalogy ( GModel *m, double threshold, bool onlyVisible)
+void ElasticAnalogy(GModel *m, double threshold, bool onlyVisible)
 {
   bool CAD, complete;
   int meshOrder;
@@ -1266,15 +1266,14 @@ void ElasticAnalogy ( GModel *m, double threshold, bool onlyVisible)
   checkHighOrderTriangles("Surface mesh", m, bad, worst);
   {
     for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it) {
-      if (onlyVisible && !(*it)->getVisibility())continue;
+      if (onlyVisible && !(*it)->getVisibility()) continue;
       std::vector<MElement*> v;
       v.insert(v.begin(), (*it)->triangles.begin(), (*it)->triangles.end());
       v.insert(v.end(), (*it)->quadrangles.begin(), (*it)->quadrangles.end());
-      if (CAD)hot.applySmoothingTo(v, (*it));
+      if (CAD) hot.applySmoothingTo(v, (*it));
       else hot.applySmoothingTo(v, 1.e32, false);
     }
   }
-  //    hot.ensureMinimumDistorsion(0.1);
   checkHighOrderTriangles("Final surface mesh", m, bad, worst);
 
   checkHighOrderTetrahedron("Volume Mesh", m, bad, worst);
@@ -1288,11 +1287,9 @@ void ElasticAnalogy ( GModel *m, double threshold, bool onlyVisible)
       hot.applySmoothingTo(v,1.e32,false);
     }
   }
-
-  // m->writeMSH("CORRECTED.msh");
+  checkHighOrderTetrahedron("File volume Mesh", m, bad, worst);
 }
 
-
 void SetOrderN(GModel *m, int order, bool linear, bool incomplete, bool onlyVisible)
 {
   // replace all the elements in the mesh with second order elements
@@ -1346,16 +1343,6 @@ void SetOrderN(GModel *m, int order, bool linear, bool incomplete, bool onlyVisi
     setHighOrder(*it, edgeVertices, faceVertices, linear, incomplete, nPts);
   }
 
-  //  highOrderTools hot(m);
-
-  // now we smooth mesh the internal vertices of the faces
-  // we do that model face by model face
-  std::vector<MElement*> bad;
-  double worst;
-
-  // printJacobians(m, "smoothness_b.pos");
-  // m->writeMSH("RAW.msh");
-
   for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it) {
     Msg::Info("Meshing volume %d order %d", (*it)->tag(), order);
     Msg::ProgressMeter(++counter, nTot, false, msg);
@@ -1365,23 +1352,10 @@ void SetOrderN(GModel *m, int order, bool linear, bool incomplete, bool onlyVisi
 
   double t2 = Cpu();
 
-  // printJacobians(m, "smoothness.pos");
-
+  std::vector<MElement*> bad;
+  double worst;
   checkHighOrderTriangles("Surface mesh", m, bad, worst);
-  if (!linear && CTX::instance()->mesh.smoothInternalEdges){
-    for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it) {
-      if (onlyVisible && !(*it)->getVisibility())continue;
-      std::vector<MElement*> v;
-      v.insert(v.begin(), (*it)->triangles.begin(), (*it)->triangles.end());
-      v.insert(v.end(), (*it)->quadrangles.begin(), (*it)->quadrangles.end());
-      //hot.applySmoothingTo(v, (*it));
-      // hot.applySmoothingTo(v, .1,0);
-    }
-    // hot.ensureMinimumDistorsion(0.1);
-    checkHighOrderTriangles("Final surface mesh", m, bad, worst);
-  }
   checkHighOrderTetrahedron("Volume Mesh", m, bad, worst);
-  // m->writeMSH("CORRECTED.msh");
 
   Msg::StatusBar(true, "Done meshing order %d (%g s)", order, t2 - t1);
 }
diff --git a/Mesh/highOrderTools.cpp b/Mesh/highOrderTools.cpp
index 49200f113e..0ff338032e 100644
--- a/Mesh/highOrderTools.cpp
+++ b/Mesh/highOrderTools.cpp
@@ -174,19 +174,6 @@ void highOrderTools::ensureMinimumDistorsion (double threshold)
   ensureMinimumDistorsion(v,threshold);
 }
 
-/*
-void highOrderTools::applySmoothingTo(GRegion *gr)
-{
-   std::vector<MElement*> v;
-   v.insert(v.begin(), gr->tetrahedra.begin(),gr->tetrahedra.end());
-   v.insert(v.begin(), gr->hexahedra.begin(),gr->hexahedra.end());
-   v.insert(v.begin(), gr->prisms.begin(),gr->prisms.end());
-   Msg::Info("Smoothing high order mesh : model region %d (%d elements)", gr->tag(),
-   v.size());
-   applySmoothingTo(v,gr);
-}
-*/
-
 void highOrderTools::computeMetricInfo(GFace *gf,
                                        MElement *e,
                                        fullMatrix<double> &J,
@@ -260,7 +247,8 @@ void highOrderTools::applySmoothingTo(std::vector<MElement*> & all, GFace *gf)
   }
 
   if (!v.size()) return;
-  Msg::Info("Smoothing high order mesh : model face %d (%d elements considered in the elastic analogy, worst mapping %12.5E, %3d bad elements)", gf->tag(),
+  Msg::Info("Smoothing high order mesh : model face %d (%d elements considered in "
+            "the elastic analogy, worst mapping %12.5E, %3d bad elements)", gf->tag(),
             v.size(),minD,numBad);
 
   addOneLayer(all, v, layer);
@@ -323,7 +311,6 @@ void highOrderTools::applySmoothingTo(std::vector<MElement*> & all, GFace *gf)
     }
     else{
       SVector3 p =  getTL(*it);
-      //      printf("%12.5E %12.5E %12.5E %d %d\n",p.x(),p.y(),p.z(),(*it)->onWhat()->dim(),(*it)->onWhat()->tag());
       (*it)->x() = p.x();
       (*it)->y() = p.y();
       (*it)->z() = p.z();
@@ -416,7 +403,7 @@ highOrderTools::highOrderTools (GModel *gm, GModel *mesh, int order)
   computeStraightSidedPositions();
 }
 
-void highOrderTools::computeStraightSidedPositions ()
+void highOrderTools::computeStraightSidedPositions()
 {
   _clean();
   // compute straigh sided positions that are actually X,Y,Z positions
@@ -552,12 +539,12 @@ void highOrderTools::computeStraightSidedPositions ()
 
 // apply a displacement that does not create elements that are
 // distorted over a value "thres"
-double highOrderTools::apply_incremental_displacement (double max_incr,
-                                                       std::vector<MElement*> & v,
-                                                       bool mixed,
-                                                       double thres,
-                                                       char *meshName,
-                                                       std::vector<MElement*> & disto)
+double highOrderTools::apply_incremental_displacement(double max_incr,
+                                                      std::vector<MElement*> & v,
+                                                      bool mixed,
+                                                      double thres,
+                                                      char *meshName,
+                                                      std::vector<MElement*> & disto)
 {
 #ifdef HAVE_PETSC
   // assume that the mesh is OK, yet already curved
@@ -592,16 +579,11 @@ double highOrderTools::apply_incremental_displacement (double max_incr,
     }
   }
 
-  printf("coucou1\n");
-
   for (std::set<MVertex*>::iterator it = _vertices.begin(); it != _vertices.end(); ++it){
     MVertex *vert = *it;
     std::map<MVertex*,SVector3>::iterator itt = _targetLocation.find(vert);
     // impose displacement @ boundary
-    //    if (!(vert->onWhat()->geomType()  == GEntity::Line
-    //	  && vert->onWhat()->tag()  == 2)){
     if (itt != _targetLocation.end() && vert->onWhat()->dim() < _dim){
-      //		printf("fixing motion of vertex %d to %g %g\n",vert->getNum(),itt->second.x()-vert->x(),itt->second.y()-vert->y());
       myAssembler.fixVertex(vert, 0, _tag, itt->second.x()-vert->x());
       myAssembler.fixVertex(vert, 1, _tag, itt->second.y()-vert->y());
       myAssembler.fixVertex(vert, 2, _tag, itt->second.z()-vert->z());
@@ -624,28 +606,21 @@ double highOrderTools::apply_incremental_displacement (double max_incr,
     }
   }
 
-  printf("coucou2\n");
-
-  //+++++++++ Assembly  & Solve ++++++++++++++++++++++++++++++++++++
   if (myAssembler.sizeOfR()){
     // assembly of the elasticity term on the
-    double t1 = Cpu();
     for (unsigned int i = 0; i < v.size(); i++){
       SElement se(v[i]);
-      if (mixed)El_mixed.addToMatrix(myAssembler, &se);
+      if (mixed) El_mixed.addToMatrix(myAssembler, &se);
       else El.addToMatrix(myAssembler, &se);
     }
-    double t2 = Cpu();
     // solve the system
-    printf("coucou3 %12.5E\n", t2-t1);
     lsys->systemSolve();
-    double t3 = Cpu();
-    printf("coucou4 %12.5E\n", t3-t2);
   }
 
-  //+++++++++ Move vertices @ maximum ++++++++++++++++++++++++++++++++++++
+  // Move vertices @ maximum
   FILE *fd = Fopen ("d.msh","w");
-  fprintf(fd,"$MeshFormat\n2 0 8\n$EndMeshFormat\n$NodeData\n1\n\"tr(sigma)\"\n1\n0.0\n3\n1\n3\n%d\n", (int) _vertices.size());
+  fprintf(fd,"$MeshFormat\n2 0 8\n$EndMeshFormat\n$NodeData\n1\n"
+          "\"tr(sigma)\"\n1\n0.0\n3\n1\n3\n%d\n", (int) _vertices.size());
   for (std::set<MVertex*>::iterator it = _vertices.begin(); it != _vertices.end(); ++it){
     double ax, ay, az;
     myAssembler.getDofValue(*it, 0, _tag, ax);
@@ -659,12 +634,10 @@ double highOrderTools::apply_incremental_displacement (double max_incr,
   fprintf(fd,"$EndNodeData\n");
   fclose(fd);
 
-  //+------------------- Check now if elements are ok ---------------+++++++
+  // Check now if elements are ok
 
   (*_vertices.begin())->onWhat()->model()->writeMSH(meshName);
 
-  printf("coucou5\n");
-
   double percentage = max_incr * 100.;
   while(1){
     std::vector<MElement*> disto;
@@ -684,7 +657,6 @@ double highOrderTools::apply_incremental_displacement (double max_incr,
     }
     else break;
   }
-  printf("coucou6\n");
 
   delete lsys;
   return percentage;
@@ -708,8 +680,8 @@ void highOrderTools::ensureMinimumDistorsion(std::vector<MElement*> &all,
   }
 }
 
-double highOrderTools::applySmoothingTo (std::vector<MElement*> &all,
-					 double threshold, bool mixed)
+double highOrderTools::applySmoothingTo(std::vector<MElement*> &all,
+                                        double threshold, bool mixed)
 {
   int ITER = 0;
   double minD;
diff --git a/Solver/multiscaleLaplace.cpp b/Solver/multiscaleLaplace.cpp
index b7f0dcb4fd..6e0e82342c 100644
--- a/Solver/multiscaleLaplace.cpp
+++ b/Solver/multiscaleLaplace.cpp
@@ -756,9 +756,6 @@ static void printLevel_onlysmall(const char* fn,
 multiscaleLaplace::multiscaleLaplace (std::vector<MElement *> &elements,
                                       std::map<MVertex*, SPoint3> &allCoordinates)
 {
-  //To go through this execute gmsh with the option -optimize_hom
-  //if (!CTX::instance()->mesh.smoothInternalEdges)return;
-
   //Find the boundary loops
   //The loop with the largest equivalent radius is the Dirichlet boundary
   std::vector<std::pair<MVertex*,double> > boundaryNodes;
diff --git a/Mesh/highOrderSmoother.cpp b/contrib/HighOrderMeshOptimizer/OptHomElastic.cpp
similarity index 100%
rename from Mesh/highOrderSmoother.cpp
rename to contrib/HighOrderMeshOptimizer/OptHomElastic.cpp
diff --git a/Mesh/highOrderSmoother.h b/contrib/HighOrderMeshOptimizer/OptHomElastic.h
similarity index 100%
rename from Mesh/highOrderSmoother.h
rename to contrib/HighOrderMeshOptimizer/OptHomElastic.h
diff --git a/doc/VERSIONS.txt b/doc/VERSIONS.txt
index 3035f508ec..284cbf082d 100644
--- a/doc/VERSIONS.txt
+++ b/doc/VERSIONS.txt
@@ -1,3 +1,5 @@
+2.8.2 (July x, 2013): improved high order tools.
+
 2.8.1 (July 11, 2013): improved compound surfaces and transfinite arrangements.
 
 2.8.0 (July 8, 2013): improved Delaunay point insertion; fixed mesh orientation
-- 
GitLab