diff --git a/Fltk/highOrderToolsWindow.cpp b/Fltk/highOrderToolsWindow.cpp
index 1f291e9a5c9b5f641010aa1733bdce3e556bfcdd..b1b5667eae27ed0383037eaa742bf9e356c376fa 100644
--- a/Fltk/highOrderToolsWindow.cpp
+++ b/Fltk/highOrderToolsWindow.cpp
@@ -123,6 +123,7 @@ static void highordertools_runelas_cb(Fl_Widget *w, void *data)
     p.onlyVisible = onlyVisible;
     p.dim  = GModel::current()->getDim();//o->meshOrder;
     p.itMax = (int) o->value[3]->value();
+    p.optPassMax = (int) o->value[4]->value();
     p.weightFixed =  o->value[5]->value();
     p.weightFree =  o->value[6]->value();
     p.DistanceFactor =  o->value[7]->value();
@@ -141,7 +142,7 @@ highOrderToolsWindow::highOrderToolsWindow(int deltaFontSize)
   FL_NORMAL_SIZE -= deltaFontSize;
 
   int width = 3 * IW + 4 * WB;
-  int height = 23 * BH;
+  int height = 25 * BH;
 
   win = new paletteWindow
     (width, height, CTX::instance()->nonModalWindows ? true : false, "High Order Tools");
@@ -152,7 +153,7 @@ highOrderToolsWindow::highOrderToolsWindow(int deltaFontSize)
 
 
   butt[1] = new Fl_Check_Button
-    (x,y, 1.5*IW-WB, BH, "Apply to visible entities only");
+    (x,y, 1.5*IW-WB, BH, "Visible entities only");
   butt[1]->type(FL_TOGGLE_BUTTON);
   butt[1]->value(1);
 
@@ -268,27 +269,26 @@ highOrderToolsWindow::highOrderToolsWindow(int deltaFontSize)
   choice[2]->callback(chooseopti_cb);
 
   static Fl_Menu_Item menu_objf[] = {
-    {"CAD Fixed Bnd", 0, 0, 0},
-    {"CAD Free Bnd", 0, 0, 0},
-    {"Mesh Only", 0, 0, 0},
+    {"Fixed", 0, 0, 0},
+    {"Free", 0, 0, 0},
     {0}
   };
 
   static Fl_Menu_Item menu_strategy[] = {
     {"Generic", 0, 0, 0},
-    {"Boundary Layer", 0, 0, 0},
+    {"Boundary Layer ", 0, 0, 0},
     {0}
   };
 
   y += BH;
   choice[0] = new Fl_Choice
-    (x,y, IW, BH, "Objective function");
+    (x,y, IW, BH, "Boundary nodes");
   choice[0]->menu(menu_objf);
   choice[0]->align(FL_ALIGN_RIGHT);
 
   y += BH;
   choice[1] = new Fl_Choice
-    (x,y, IW, BH, "Strategy");
+    (x,y, IW, BH, "Blob strategy");
   choice[1]->menu(menu_strategy);
   choice[1]->align(FL_ALIGN_RIGHT);
 
@@ -305,7 +305,7 @@ highOrderToolsWindow::highOrderToolsWindow(int deltaFontSize)
 
   y += BH;
   value[3] = new Fl_Value_Input
-    (x,y, IW, BH, "Maximum number of iterations");
+    (x,y, IW, BH, "Max. number of iterations");
   value[3]->minimum(1);
   value[3]->maximum(10000);
   value[3]->step(10);
@@ -314,15 +314,16 @@ highOrderToolsWindow::highOrderToolsWindow(int deltaFontSize)
 
   y += BH;
   value[4] = new Fl_Value_Input
-    (x,y, IW, BH, "Tolerance");
-  value[4]->minimum(1.e-12);
-  value[4]->maximum(0.1);
-  value[4]->step(1.e-5);
+    (x,y, IW, BH, "Max. number of optimization passes");
+  value[4]->minimum(1);
+  value[4]->maximum(100);
+  value[4]->step(1);
   value[4]->align(FL_ALIGN_RIGHT);
-  value[4]->value(1.e-4);
+  value[4]->value(50);
 
+  y += 1.5*BH;
   push[1] = new Fl_Button
-    (width - BB - 2 * WB, y, BB, BH, "Apply");
+    (x,y, IW, BH, "Apply");
   push[1]->callback(highordertools_runelas_cb);
 
   y += 1.5*BH;
@@ -348,10 +349,10 @@ void highOrderToolsWindow::show(bool redrawOnly)
   else {
     value[0]->value(meshOrder);
     butt[0]->value(!complete);
-    if (CAD)output[0]->value("Available");
+    if (CAD) output[0]->value("Available");
     else {
       output[0]->value("Not Available");
-      choice[0]->value(2);
+      choice[0]->deactivate();
     }
     win->show();
   }
diff --git a/contrib/HighOrderMeshOptimizer/OptHOM.cpp b/contrib/HighOrderMeshOptimizer/OptHOM.cpp
index 445576fa6e47511660bea258d29101b201de6b10..41ecbf88fe8d8983e6e3107495cff1bc722a4d4a 100644
--- a/contrib/HighOrderMeshOptimizer/OptHOM.cpp
+++ b/contrib/HighOrderMeshOptimizer/OptHOM.cpp
@@ -291,7 +291,7 @@ void OptHOM::OptimPass(alglib::real_1d_array &x, const alglib::real_1d_array &in
 
 
 
-int OptHOM::optimize(double weightFixed, double weightFree, double b_min, double b_max, bool optimizeMetricMin, int pInt, int itMax)
+int OptHOM::optimize(double weightFixed, double weightFree, double b_min, double b_max, bool optimizeMetricMin, int pInt, int itMax, int optPassMax)
 {
 
   barrier_min = b_min;
@@ -342,7 +342,7 @@ int OptHOM::optimize(double weightFixed, double weightFree, double b_min, double
     recalcJacDist();
     jacBar = (minJac > 0.) ? 0.9*minJac : 1.1*minJac;
     setBarrierTerm(jacBar);
-    if (ITER ++ > 50) break;
+    if (ITER ++ > optPassMax) break;
   }
 
   if (!_optimizeMetricMin) {
@@ -354,15 +354,10 @@ int OptHOM::optimize(double weightFixed, double weightFree, double b_min, double
       recalcJacDist();
       jacBar =  1.1 * maxJac;
       setBarrierTerm(jacBar);
-      if (ITER ++ > 50) break;
+      if (ITER ++ > optPassMax) break;
     }
   }
 
-  //  for (int i = 0; i<3; i++) {
-  //    lambda *= 100;
-  //    OptimPass(x, gradObj, itMax);
-  //  }
-
   OptHomMessage("Optimization done Range (%g,%g)",minJac,maxJac);
 
   if (minJac > barrier_min && maxJac < barrier_max) return 1;
diff --git a/contrib/HighOrderMeshOptimizer/OptHOM.h b/contrib/HighOrderMeshOptimizer/OptHOM.h
index 85f7fd868d7500604ac6740e32d2ebf4a8d81d5e..2d6fcda080b0504318f649dc2fa5ad25209d8e8b 100644
--- a/contrib/HighOrderMeshOptimizer/OptHOM.h
+++ b/contrib/HighOrderMeshOptimizer/OptHOM.h
@@ -25,7 +25,7 @@ public:
   // returns 1 if the mesh has been optimized with success i.e. all jacobians are in the range
   // returns 0 if the mesh is valid (all jacobians positive, JMIN > 0) but JMIN < barrier_min || JMAX > barrier_max
   // returns -1 if the mesh is invalid : some jacobians cannot be made positive
-  int optimize(double lambda, double lambda2, double barrier_min, double barrier_max, bool optimizeMetricMin, int pInt, int itMax);  // optimize one list of elements
+  int optimize(double lambda, double lambda2, double barrier_min, double barrier_max, bool optimizeMetricMin, int pInt, int itMax, int optPassMax);  // optimize one list of elements
   void recalcJacDist();
   inline void getJacDist(double &minJ, double &maxJ, double &maxD, double &avgD);
   void updateMesh(const alglib::real_1d_array &x);
diff --git a/contrib/HighOrderMeshOptimizer/OptHomRun.cpp b/contrib/HighOrderMeshOptimizer/OptHomRun.cpp
index d6ac67769efda27e1d60f2e3940ee56689843865..1f75111c40cbda974b084dd19386b3507d64a0e0 100644
--- a/contrib/HighOrderMeshOptimizer/OptHomRun.cpp
+++ b/contrib/HighOrderMeshOptimizer/OptHomRun.cpp
@@ -457,10 +457,10 @@ void HighOrderMeshOptimizer (GModel *gm, OptHomParameters &p)
         OptHomMessage("Optimizing a blob %i/%i composed of %4d elements", i+1, toOptimize.size(), toOptimize[i].first.size());
         fflush(stdout);
         OptHOM temp(&entity, toOptimize[i].first, toOptimize[i].second, method);
-        int success = temp.optimize(p.weightFixed, p.weightFree, p.BARRIER_MIN, p.BARRIER_MAX, false, samples, p.itMax);
+        int success = temp.optimize(p.weightFixed, p.weightFree, p.BARRIER_MIN, p.BARRIER_MAX, false, samples, p.itMax, p.optPassMax);
         if (success >= 0 && p.BARRIER_MIN_METRIC > 0) {
           OptHomMessage("jacobian optimization succeed, starting svd optimization");
-          success = temp.optimize(p.weightFixed, p.weightFree, p.BARRIER_MIN_METRIC, p.BARRIER_MAX, true, samples, p.itMax);
+          success = temp.optimize(p.weightFixed, p.weightFree, p.BARRIER_MIN_METRIC, p.BARRIER_MAX, true, samples, p.itMax, p.optPassMax);
         }
         temp.mesh.updateGEntityPositions();
         if (success <= 0) {
@@ -512,7 +512,7 @@ void HighOrderMeshOptimizer (GModel *gm, OptHomParameters &p)
           temp.mesh.writeMSH(ossI.str().c_str());
           if (minJac > p.BARRIER_MIN && maxJac < p.BARRIER_MAX) break;
 
-          p.SUCCESS = std::min(p.SUCCESS,temp.optimize(p.weightFixed, p.weightFree, p.BARRIER_MIN, p.BARRIER_MAX, false, samples, p.itMax));
+          p.SUCCESS = std::min(p.SUCCESS,temp.optimize(p.weightFixed, p.weightFree, p.BARRIER_MIN, p.BARRIER_MAX, false, samples, p.itMax, p.optPassMax));
 
           //  temp.recalcJacDist();
           //  temp.getJacDist(minJac, maxJac, distMaxBND, distAvgBND);
@@ -560,7 +560,7 @@ void HighOrderMeshOptimizer (GModel *gm, OptHomParameters &p)
           ossI << "initial_" << (*itr)->tag() << "ITER_" << ITER << ".msh";
           temp.mesh.writeMSH(ossI.str().c_str());
           if (minJac > p.BARRIER_MIN  && maxJac < p.BARRIER_MAX) break;
-          p.SUCCESS = temp.optimize(p.weightFixed, p.weightFree, p.BARRIER_MIN, p.BARRIER_MAX, false, samples, p.itMax);
+          p.SUCCESS = temp.optimize(p.weightFixed, p.weightFree, p.BARRIER_MIN, p.BARRIER_MAX, false, samples, p.itMax, p.optPassMax);
           temp.recalcJacDist();
           temp.getJacDist(minJac, maxJac, distMaxBND, distAvgBND);
           temp.mesh.updateGEntityPositions();
diff --git a/contrib/HighOrderMeshOptimizer/OptHomRun.h b/contrib/HighOrderMeshOptimizer/OptHomRun.h
index 63b294812a7bebfc337e514d679af51ca18c1b09..29bf7bd3f9720d0588b353a2cd5344075b638e05 100644
--- a/contrib/HighOrderMeshOptimizer/OptHomRun.h
+++ b/contrib/HighOrderMeshOptimizer/OptHomRun.h
@@ -13,6 +13,7 @@ struct OptHomParameters {
   int nbLayers ; // number of layers taken around a bad element
   int dim ; // which dimension to optimize
   int itMax ; // max number of iterations in the optimization process
+  int optPassMax ; // max number of optimization passes
   double TMAX ; // max CPU time allowed
   bool onlyVisible ; // apply optimization to visible entities ONLY
   double DistanceFactor; // filter elements such that no elements further away than