diff --git a/contrib/HighOrderMeshOptimizer/OptHomElastic.cpp b/contrib/HighOrderMeshOptimizer/OptHomElastic.cpp
deleted file mode 100644
index 303ea7b9c452f2a639966cc7093bf095b5646b5c..0000000000000000000000000000000000000000
--- a/contrib/HighOrderMeshOptimizer/OptHomElastic.cpp
+++ /dev/null
@@ -1,1818 +0,0 @@
-// Gmsh - Copyright (C) 1997-2013 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>.
-//
-// Contributor(s):
-//   Koen Hillewaert
-//
-
-#include "GmshConfig.h"
-
-#if defined(HAVE_SOLVER)
-
-#include "OS.h"
-#include "MLine.h"
-#include "MTriangle.h"
-#include "MQuadrangle.h"
-#include "MTetrahedron.h"
-#include "MHexahedron.h"
-#include "MPrism.h"
-#include "MPyramid.h"
-#include "HighOrder.h"
-#include "meshGFaceOptimize.h"
-#include "highOrderSmoother.h"
-#include "GFace.h"
-#include "GRegion.h"
-#include "Context.h"
-#include "Numeric.h"
-#include "dofManager.h"
-#include "elasticityTerm.h"
-#include "linearSystemCSR.h"
-#include "linearSystemFull.h"
-#include "linearSystemPETSc.h"
-
-#define SQU(a)      ((a)*(a))
-
-int optimalLocationPN_(GFace *gf, const MEdge &me, MTriangle *t1, MTriangle *t2,
-                       highOrderSmoother *s);
-static int swapHighOrderTriangles(GFace *gf);
-static int swapHighOrderTriangles(GFace *gf, edgeContainer&, faceContainer&,
-                                       highOrderSmoother *s);
-static int findOptimalLocationsP2(GFace *gf, highOrderSmoother *s);
-static int findOptimalLocationsPN(GFace *gf, highOrderSmoother *s);
-
-static double shapeMeasure(MElement *e)
-{
-  //const double d1 = e->distoShapeMeasure();
-  const double d1 = e->angleShapeMeasure();
-  //const double d2 = e->gammaShapeMeasure();
-  return d1;
-}
-
-void highOrderSmoother::moveTo(MVertex *v,
-                                   const std::map<MVertex*, SVector3> &m) const
-{
-  std::map<MVertex*,SVector3>::const_iterator it = m.find(v);
-  if (it != m.end()){
-    v->x() = it->second.x();
-    v->y() = it->second.y();
-    v->z() = it->second.z();
-  }
-}
-
-void highOrderSmoother::moveToStraightSidedLocation(MVertex *v) const
-{
-  moveTo( v, _straightSidedLocation);
-}
-
-void highOrderSmoother::moveToTargetLocation(MVertex *v) const
-{
-  moveTo( v, _targetLocation);
-}
-
-void highOrderSmoother::moveToStraightSidedLocation(MElement *e) const
-{
-  for(int i = 0; i < e->getNumVertices(); i++)
-    moveToStraightSidedLocation(e->getVertex(i));
-}
-
-void highOrderSmoother::moveToTargetLocation(MElement *e) const
-{
-  for(int i = 0; i < e->getNumVertices(); i++)
-    moveToTargetLocation(e->getVertex(i));
-}
-
-void highOrderSmoother::updateTargetLocation(MVertex*v, const SPoint3 &p3,
-                                                 const SPoint2 &p2)
-{
-  v->x() = p3.x();
-  v->y() = p3.y();
-  v->z() = p3.z();
-  v->setParameter(0,p2.x());
-  v->setParameter(1,p2.y());
-  _targetLocation[v] = SVector3(p3.x(), p3.y(), p3.z());
-}
-
-struct p2data{
-  GFace *gf;
-  MTriangle *t1, *t2;
-  MVertex *n12;
-  fullMatrix<double> *m1, *m2;
-  highOrderSmoother *s;
-  p2data(GFace *_gf, MTriangle *_t1, MTriangle *_t2, MVertex *_n12,
-         highOrderSmoother *_s)
-    : gf(_gf), t1(_t1), t2(_t2), n12(_n12), s(_s)
-  {
-    elasticityTerm el(0, 1.e3, .48,1);
-    s->moveToStraightSidedLocation(t1);
-    s->moveToStraightSidedLocation(t2);
-    m1 = new fullMatrix<double>(3 * t1->getNumVertices(),
-                                3 * t1->getNumVertices());
-    m2 = new fullMatrix<double>(3 * t2->getNumVertices(),
-                                3 * t2->getNumVertices());
-    SElement se1(t1), se2(t2);
-    el.elementMatrix(&se1, *m1);
-    el.elementMatrix(&se2, *m2);
-    s->moveToTargetLocation(t1);
-    s->moveToTargetLocation(t2);
-  }
-  ~p2data()
-  {
-    delete m1;
-    delete m2;
-  }
-};
-
-struct pNdata{
-  GFace *gf;
-  MTriangle *t1,*t2;
-  const std::vector<MVertex*> &n;
-  fullMatrix<double> *m1,*m2;
-  highOrderSmoother *s;
-  pNdata(GFace *_gf,MTriangle *_t1,MTriangle *_t2, const std::vector<MVertex*> &_n,
-         highOrderSmoother *_s)
-    : gf(_gf), t1(_t1), t2(_t2), n(_n), s(_s)
-  {
-    elasticityTerm el(0, 1.e3, .3333,1);
-    s->moveToStraightSidedLocation(t1);
-    s->moveToStraightSidedLocation(t2);
-    m1 = new  fullMatrix<double>(3 * t1->getNumVertices(),
-                                 3 * t1->getNumVertices());
-    m2 = new  fullMatrix<double>(3 * t2->getNumVertices(),
-                                 3 * t2->getNumVertices());
-    SElement se1(t1), se2(t2);
-    el.elementMatrix(&se1, *m1);
-    el.elementMatrix(&se2, *m2);
-    s->moveToTargetLocation(t1);
-    s->moveToTargetLocation(t2);
-  }
-  ~pNdata()
-  {
-    delete m1;
-    delete m2;
-  }
-};
-
-static double _DeformationEnergy(MElement *e,
-                                 fullMatrix<double> *K,
-                                 highOrderSmoother *s)
-{
-  int N = e->getNumVertices();
-  fullVector<double> Kdx(N*3),dx(N*3);
-
-  dx.scale(0.0);
-  Kdx.scale(0.0);
-  for (int i=0;i<N;i++){
-    SVector3 disp = s->getDisplacement(e->getVertex(i));
-    SVector3 str  = s->getSSL(e->getVertex(i));
-    dx(i)      = disp.x();
-    dx(i+N)    = disp.y();
-    dx(i+2*N)  = disp.z();
-    if (0 && (fabs(disp.x())>1.e-12 ||fabs(disp.y())>1.e-12))
-      printf("%6d (%12.5E %12.5E %12.5E -- %12.5E %12.5E %12.5E -- %12.5E %12.5E %12.5E)\n",
-             e->getVertex(i)->getNum(),
-             disp.x(),disp.y(),disp.z(),
-             str.x(),str.y(),str.z(),e->getVertex(i)->x(),e->getVertex(i)->y(),
-             e->getVertex(i)->z());
-  }
-
-  K->mult(dx, Kdx);
-  const double E = Kdx * dx;
-  return E;
-}
-
-static double _DeformationEnergy(p2data *p)
-{
-  return _DeformationEnergy(p->t1, p->m1, p->s) +
-    _DeformationEnergy(p->t2, p->m2, p->s);
-}
-
-static double _DeformationEnergy(pNdata *p)
-{
-  return _DeformationEnergy(p->t1, p->m1, p->s) +
-    _DeformationEnergy(p->t2, p->m2, p->s);
-}
-
-static double _function_p2tB(fullVector<double> &x, void *data)
-{
-  p2data *p = (p2data*)data;
-  GPoint gp12 = p->gf->point(SPoint2(x(0), x(1)));
-  double xx = p->n12->x();
-  double yy = p->n12->y();
-  double zz = p->n12->z();
-  p->n12->x() = gp12.x();
-  p->n12->y() = gp12.y();
-  p->n12->z() = gp12.z();
-
-  double E = _DeformationEnergy(p);
-  p->n12->x() = xx;
-  p->n12->y() = yy;
-  p->n12->z() = zz;
-  return E;
-}
-
-static double _function_p2t(fullVector<double> &x, void *data)
-{
-  p2data *p = (p2data*)data;
-  GPoint gp12 = p->gf->point(SPoint2(x(0), x(1)));
-  double xx = p->n12->x();
-  double yy = p->n12->y();
-  double zz = p->n12->z();
-  p->n12->x() = gp12.x();
-  p->n12->y() = gp12.y();
-  p->n12->z() = gp12.z();
-  double q = std::min(shapeMeasure(p->t1), shapeMeasure(p->t2));
-  p->n12->x() = xx;
-  p->n12->y() = yy;
-  p->n12->z() = zz;
-  return -q;
-}
-
-static double _function_pNt(fullVector<double> &x, void *data)
-{
-  pNdata *p = (pNdata*)data;
-  static double xx[256];
-  static double yy[256];
-  static double zz[256];
-  for (unsigned int i = 0; i < p->n.size(); i++){
-    GPoint gp12 = p->gf->point(SPoint2(x(2 * i), x(2 * i + 1)));
-    xx[i] = p->n[i]->x();
-    yy[i] = p->n[i]->y();
-    zz[i] = p->n[i]->z();
-    p->n[i]->x() = gp12.x();
-    p->n[i]->y() = gp12.y();
-    p->n[i]->z() = gp12.z();
-  }
-  double q = std::min(shapeMeasure(p->t1), shapeMeasure(p->t2));
-  for (unsigned int i = 0; i < p->n.size(); i++){
-    p->n[i]->x() = xx[i];
-    p->n[i]->y() = yy[i];
-    p->n[i]->z() = zz[i];
-  }
-  return -q;
-}
-
-static double _function_pNtB(fullVector<double> &x, void *data)
-{
-  pNdata *p = (pNdata*)data;
-  static double xx[256];
-  static double yy[256];
-  static double zz[256];
-  for (unsigned int i = 0; i < p->n.size(); i++){
-    GPoint gp12 = p->gf->point(SPoint2(x(2 * i), x(2 * i + 1)));
-    xx[i] = p->n[i]->x();
-    yy[i] = p->n[i]->y();
-    zz[i] = p->n[i]->z();
-    p->n[i]->x() = gp12.x();
-    p->n[i]->y() = gp12.y();
-    p->n[i]->z() = gp12.z();
-  }
-  double E = _DeformationEnergy(p);
-  for (unsigned int i = 0; i < p->n.size(); i++){
-    p->n[i]->x() = xx[i];
-    p->n[i]->y() = yy[i];
-    p->n[i]->z() = zz[i];
-  }
-  return E;
-}
-
-void getDistordedElements(const std::vector<MElement*> &v,
-                          const double & threshold,
-                          std::vector<MElement*> &d,
-                          double &minD)
-{
-  d.clear();
-  minD = 1;
-  for (unsigned int i = 0; i < v.size(); i++){
-    const double disto = v[i]->distoShapeMeasure();
-    if (disto < threshold)
-      d.push_back(v[i]);
-    minD = std::min(minD, disto);
-  }
-}
-
-void addOneLayer(const std::vector<MElement*> &v,
-                 std::vector<MElement*> &d,
-                 std::vector<MElement*> &layer)
-{
-  std::set<MVertex*> all;
-  for (unsigned int i = 0; i < d.size(); i++){
-    MElement *e = d[i];
-    int n = e->getNumPrimaryVertices();
-    for (int j = 0; j < n; j++){
-      all.insert(e->getVertex(j));
-    }
-  }
-  layer.clear();
-
-  std::sort(d.begin(), d.end());
-
-  for (unsigned int i = 0; i < v.size(); i++){
-    MElement *e = v[i];
-    bool found = std::binary_search(d.begin(), d.end(), e);
-    // element is not yet there
-    if (!found){
-      int n = e->getNumPrimaryVertices();
-      for (int j = 0; j < n; j++){
-        MVertex *vert = e->getVertex(j);
-        if (all.find(vert) != all.end()){
-          layer.push_back(e);
-          j = n;
-        }
-      }
-    }
-  }
-}
-
-
-void _printJacobiansAtNodes (const char * name, std::vector<MElement*> &v)
-{
-  FILE *fd = Fopen (name,"w");
-  fprintf(fd,"$MeshFormat\n2 0 8\n$EndMeshFormat\n$ElementNodeData\n1\n\"det J\"\n1\n0.0\n3\n1\n1\n%d\n", (int) v.size());
-  for (int i=0; i<v.size(); i++){
-    const polynomialBasis* pb = v[i]->getFunctionSpace();
-    fprintf(fd,"%d %d",v[i]->getNum(),v[i]->getNumVertices());
-    for (int j=0; j < v[i]->getNumVertices(); j++){
-      const double _u = pb->points(j,0);
-      const double _v = pb->points(j,1);
-      const double _w = pb->points(j,2);
-      double jac[3][3];
-      double J = v[i]->getJacobian (_u,_v,_w, jac);
-      fprintf(fd," %g",J);
-    }
-    fprintf(fd,"\n");
-  }
-  fprintf(fd,"$EndElementNodeData\n");
-  fclose(fd);
-}
-
-void highOrderSmoother::smooth(GFace *gf, bool metric)
-{
-  std::vector<MElement*> v;
-
-  v.insert(v.begin(), gf->triangles.begin(),gf->triangles.end());
-  v.insert(v.begin(), gf->quadrangles.begin(),gf->quadrangles.end());
-  Msg::Info("Smoothing high order mesh : model face %d (%d elements)", gf->tag(),
-            v.size());
-
-  //  gf->model()->writeMSH("before_smoothing.msh");
-  //  _printJacobiansAtNodes ("before_smoothing_jac.msh", v);
-  //  smooth_with_mixed_formulation(v,0.2);
-  //  gf->model()->writeMSH("after_smoothing.msh");
-  //  _printJacobiansAtNodes ("after_smoothing_jac.msh", v);
-  //  return;
-
-  if (metric)smooth_metric(v,gf);
-  else smooth(v);
-}
-
-void highOrderSmoother::smooth(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());
-  smooth(v);
-}
-
-// Use elastic solver to move the nodes: compute the stiffness matrix
-// of an element that correspond to the deformation of a straight
-// sided element to a curvilinear one
-
-
-
-
-void highOrderSmoother::optimize(GFace * gf,
-				 edgeContainer &edgeVertices,
-				 faceContainer &faceVertices)
-{
-  //  if (gf->geomType() != GEntity::Plane) return;
-
-    std::vector<MElement*> bad;
-
-
-  while (1) {
-    // relocate the vertices using elliptic smoother
-    //    smooth(gf);
-    //    for (int i = 0; i < 20; i++){
-    //      findOptimalLocationsPN(gf,this);
-    //      findOptimalLocationsPN(gf,this);
-    //    }
-    // then try to swap for better configurations
-
-    //smooth(gf, !CTX::instance()->mesh.highOrderNoMetric);
-
-
-    //    for (int i=0;i<100;i++){
-      //      int nbSwap =
-	//	swapHighOrderTriangles(gf,edgeVertices,faceVertices,this);
-	//      printf("%d swaps\n",nbSwap);
-    //    }
-
-     smooth(gf,true);
-    // smooth(gf,true);
-    // smooth(gf,true);
-    // smooth(gf,true);
-    break;
-
-    // if the smoothing procedure has been able to
-    // move the nodes to their right location, break !
-    //    break;
-    if (_MIDDLE == 1.0) break;
-    // if (!nbSwap){
-    //   printf("Cannot move thet nodes to their optimal location, "
-    //          "splits have to be added\n");
-    //   break;
-    // }
-  }
-}
-
-void highOrderSmoother::computeMetricVector(GFace *gf,
-                                                MElement *e,
-                                                fullMatrix<double> &J,
-                                                fullMatrix<double> &JT,
-                                                fullVector<double> &D)
-{
-  int nbNodes = e->getNumVertices();
-  for (int j = 0; j < nbNodes; j++){
-    SPoint2 param;
-    reparamMeshVertexOnFace(e->getVertex(j), gf, param);
-    Pair<SVector3,SVector3> der = gf->firstDer(param);
-    int XJ = j;
-    int YJ = j + nbNodes;
-    int ZJ = j + 2 * nbNodes;
-    int UJ = j;
-    int VJ = j + nbNodes;
-    J(XJ,UJ) = der.first().x();
-    J(YJ,UJ) = der.first().y();
-    J(ZJ,UJ) = der.first().z();
-    J(XJ,VJ) = der.second().x();
-    J(YJ,VJ) = der.second().y();
-    J(ZJ,VJ) = der.second().z();
-
-    JT(UJ,XJ) = der.first().x();
-    JT(UJ,YJ) = der.first().y();
-    JT(UJ,ZJ) = der.first().z();
-    JT(VJ,XJ) = der.second().x();
-    JT(VJ,YJ) = der.second().y();
-    JT(VJ,ZJ) = der.second().z();
-
-    GPoint gp = gf->point(param);
-    SVector3 ss = getSSL(e->getVertex(j));
-    D(XJ) = gp.x() - ss.x();
-    D(YJ) = gp.y() - ss.y();
-    D(ZJ) = gp.z() - ss.z();
-  }
-}
-
-void highOrderSmoother::smooth_metric(std::vector<MElement*>  & all, GFace *gf)
-{
-#ifdef HAVE_TAUCS
-  linearSystemCSRTaucs<double> *lsys = new linearSystemCSRTaucs<double>;
-#else
-  linearSystemCSRGmm<double> *lsys = new linearSystemCSRGmm<double>;
-  lsys->setNoisy(1);
-  lsys->setGmres(1);
-  lsys->setPrec(5.e-8);
-#endif
-  dofManager<double> myAssembler(lsys);
-  elasticityTerm El(0, 1.0, .33, getTag());
-
-  std::vector<MElement*> layer, v;
-  double minD;
-
-  getDistordedElements(all, 0.99, v, minD);
-
-  const int nbLayers = 3; //2, originally :)
-  for (int i = 0; i < nbLayers; i++){
-    addOneLayer(all, v, layer);
-    v.insert(v.end(), layer.begin(), layer.end());
-  }
-
-  Msg::Debug("%d elements after adding %d layers", (int)v.size(), nbLayers);
-
-  if (!v.size()) return;
-
-  addOneLayer(all, v, layer);
-
-  std::set<MVertex*>::iterator it;
-  std::map<MVertex*,SVector3>::iterator its;
-  std::map<MVertex*,SVector3>::iterator itpresent;
-  std::map<MVertex*,SVector3>::iterator ittarget;
-  std::set<MVertex*> verticesToMove;
-
-  for (unsigned int i = 0; i < layer.size(); i++){
-    for (int j = 0; j < layer[i]->getNumVertices(); j++){
-      MVertex *vert = layer[i]->getVertex(j);
-      myAssembler.fixVertex(vert, 0, getTag(), 0);
-      myAssembler.fixVertex(vert, 1, getTag(), 0);
-    }
-  }
-
-  // printf("%d vertices \n", _displ.size());
-
-  for (unsigned int i = 0; i < v.size(); i++){
-    for (int j = 0; j < v[i]->getNumVertices(); j++){
-      MVertex *vert = v[i]->getVertex(j);
-      // printf("%d %d %d v\n", i, j, v[i]->getNumVertices());
-      its = _straightSidedLocation.find(vert);
-      if (its == _straightSidedLocation.end()){
-        _straightSidedLocation[vert] =
-          SVector3(vert->x(), vert->y(), vert->z());
-        _targetLocation[vert] =
-          SVector3(vert->x(), vert->y(), vert->z());
-      }
-      else{
-        vert->x() = its->second.x();
-        vert->y() = its->second.y();
-        vert->z() = its->second.z();
-        if (vert->onWhat()->dim() < _dim){
-          myAssembler.fixVertex(vert, 0, getTag(), 0);
-          myAssembler.fixVertex(vert, 1, getTag(), 0);
-        }
-      }
-    }
-  }
-
-  // number the other DOFs
-  for (unsigned int i = 0; i < v.size(); i++){
-    for (int j = 0; j < v[i]->getNumVertices(); j++){
-      MVertex *vert = v[i]->getVertex(j);
-      myAssembler.numberVertex(vert, 0, getTag());
-      myAssembler.numberVertex(vert, 1, getTag());
-      verticesToMove.insert(vert);
-    }
-  }
-
-  double dx0 = smooth_metric_(v, gf, myAssembler, verticesToMove, El);
-  double dx = dx0;
-  Msg::Debug(" dx0 = %12.5E", dx0);
-  int iter = 0;
-  while(1){
-    double dx2 = smooth_metric_(v, gf, myAssembler, verticesToMove, El);
-    Msg::Debug(" dx2  = %12.5E", dx2);
-    if (fabs(dx2 - dx) < 1.e-4 * dx0)break;
-    if (iter++ > 2)break;
-    dx = dx2;
-  }
-
-  for (it = verticesToMove.begin(); it != verticesToMove.end(); ++it){
-    SPoint2 param;
-    reparamMeshVertexOnFace(*it, gf, param);
-    GPoint gp = gf->point(param);
-    if ((*it)->onWhat()->dim() == 2){
-      (*it)->x() = gp.x();
-      (*it)->y() = gp.y();
-      (*it)->z() = gp.z();
-      _targetLocation[*it] = SVector3(gp.x(), gp.y(), gp.z());
-    }
-    else{
-      SVector3 p =  _targetLocation[(*it)];
-      (*it)->x() = p.x();
-      (*it)->y() = p.y();
-      (*it)->z() = p.z();
-    }
-  }
-  delete lsys;
-}
-
-double highOrderSmoother::smooth_metric_(std::vector<MElement*>  & v,
-                                         GFace *gf,
-                                         dofManager<double> &myAssembler,
-                                         std::set<MVertex*> &verticesToMove,
-                                         elasticityTerm &El)
-{
-  std::set<MVertex*>::iterator it;
-  double dx = 0.0;
-
-  //  printf("size %d\n",myAssembler.sizeOfR());
-
-  if (myAssembler.sizeOfR()){
-
-    // while convergence -------------------------------------------------------
-    for (unsigned int i = 0; i < v.size(); i++){
-      MElement *e = v[i];
-      int nbNodes = e->getNumVertices();
-      const int n2 = 2 * nbNodes;
-      const int n3 = 3 * nbNodes;
-
-      fullMatrix<double> K33(n3, n3);
-      fullMatrix<double> K22(n2, n2);
-      fullMatrix<double> J32(n3, n2);
-      fullMatrix<double> J23(n2, n3);
-      fullVector<double> D3(n3);
-      fullVector<double> R2(n2);
-      fullMatrix<double> J23K33(n2, n3);
-      K33.setAll(0.0);
-      SElement se(e);
-      El.elementMatrix(&se, K33);
-      computeMetricVector(gf, e, J32, J23, D3);
-      J23K33.gemm(J23, K33, 1, 0);
-      K22.gemm(J23K33, J32, 1, 0);
-      J23K33.mult(D3, R2);
-      for (int j = 0; j < n2; j++){
-        Dof RDOF = El.getLocalDofR(&se, j);
-        myAssembler.assemble(RDOF, -R2(j));
-        for (int k = 0; k < n2; k++){
-          Dof CDOF = El.getLocalDofC(&se, k);
-          myAssembler.assemble(RDOF, CDOF, K22(j, k));
-        }
-      }
-    }
-    myAssembler.systemSolve();
-    // for all element, compute detJ at integration points --> material law
-    // end while convergence -------------------------------------------------------
-
-    for (it = verticesToMove.begin(); it != verticesToMove.end(); ++it){
-      if ((*it)->onWhat()->dim() == 2){
-	SPoint2 param;
-	reparamMeshVertexOnFace((*it), gf, param);
-	SPoint2 dparam;
-	myAssembler.getDofValue((*it), 0, getTag(), dparam[0]);
-	myAssembler.getDofValue((*it), 1, getTag(), dparam[1]);
-	SPoint2 newp = param+dparam;
-	dx += newp.x() * newp.x() + newp.y() * newp.y();
-	(*it)->setParameter(0, newp.x());
-	(*it)->setParameter(1, newp.y());
-      }
-    }
-    myAssembler.systemClear();
-  }
-
-  return dx;
-}
-
-
-double highOrderSmoother::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
-  linearSystemPETSc<double> *lsys = new  linearSystemPETSc<double>;
-  dofManager<double> myAssembler(lsys);
-  elasticityMixedTerm El_mixed (0, 1.0, .333, getTag());
-  elasticityTerm El (0, 1.0, .333, getTag());
-
-  std::set<MVertex*> _vertices;
-
-  //+++++++++ Boundary Conditions & Numbering +++++++++++++++++++++++++++++++
-  // fix all dof that correspond to vertices on the boundary
-  // the value is equal
-  for (unsigned int i = 0; i < v.size(); i++){
-    for (int j = 0; j < v[i]->getNumVertices(); j++){
-      MVertex *vert = v[i]->getVertex(j);
-      _vertices.insert(vert);
-    }
-  }
-
-  //+++++++++ Fix d tr(eps) = 0 +++++++++++++++++++++++++++++++
-  if (mixed){
-    for (unsigned int i = 0; i < disto.size(); i++){
-      for (int j = 0; j < disto[i]->getNumVertices(); j++){
-	MVertex *vert = disto[i]->getVertex(j);
-	myAssembler.fixVertex(vert, 4, getTag(), 0.0);
-      }
-    }
-  }
-
-  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() != 1){ // TEST
-      if (itt != _targetLocation.end() && vert->onWhat()->dim() < _dim){
-	myAssembler.fixVertex(vert, 0, getTag(), itt->second.x()-vert->x());
-	myAssembler.fixVertex(vert, 1, getTag(), itt->second.y()-vert->y());
-	myAssembler.fixVertex(vert, 2, getTag(), itt->second.z()-vert->z());
-      }
-      // ensure we do not touch any vertex that is on the boundary
-      else if (vert->onWhat()->dim() < _dim){
-	myAssembler.fixVertex(vert, 0, getTag(), 0);
-	myAssembler.fixVertex(vert, 1, getTag(), 0);
-	myAssembler.fixVertex(vert, 2, getTag(), 0);
-      }
-    }
-    if (_dim == 2)myAssembler.fixVertex(vert, 2, getTag(), 0);
-    // number vertices
-    myAssembler.numberVertex(vert, 0, getTag());
-    myAssembler.numberVertex(vert, 1, getTag());
-    myAssembler.numberVertex(vert, 2, getTag());
-    if (mixed){
-      myAssembler.numberVertex(vert, 3, getTag());
-      myAssembler.numberVertex(vert, 4, getTag());
-    }
-  }
-
-  //+++++++++ Assembly  & Solve ++++++++++++++++++++++++++++++++++++
-  if (myAssembler.sizeOfR()){
-    // assembly of the elasticity term on the
-    for (unsigned int i = 0; i < v.size(); i++){
-      SElement se(v[i]);
-      if (mixed)El_mixed.addToMatrix(myAssembler, &se);
-      else El.addToMatrix(myAssembler, &se);
-    }
-    // solve the system
-    lsys->systemSolve();
-  }
-
-  //+++++++++ 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());
-  for (std::set<MVertex*>::iterator it = _vertices.begin(); it != _vertices.end(); ++it){
-    double ax, ay, az;
-    myAssembler.getDofValue(*it, 0, getTag(), ax);
-    myAssembler.getDofValue(*it, 1, getTag(), ay);
-    myAssembler.getDofValue(*it, 2, getTag(), az);
-    (*it)->x() += max_incr*ax;
-    (*it)->y() += max_incr*ay;
-    (*it)->z() += max_incr*az;
-    fprintf(fd,"%d %g %g %g\n",(*it)->getIndex(), ax,ay,az);
-  }
-  fprintf(fd,"$EndNodeData\n");
-  fclose(fd);
-
-  //+------------------- Check now if elements are ok ---------------+++++++
-
-  (*_vertices.begin())->onWhat()->model()->writeMSH(meshName);
-
-  /*
-    std::map<MVertex*,double> facts;
-    while(1){
-    int count = 0;
-    for (unsigned int i = 0; i < v.size(); i++){
-    double disto = v[i]->distoShapeMeasure();
-    if (disto < thres){
-    count ++;
-    for (int j = 0; j < v[i]->getNumVertices(); j++){
-    MVertex *vert = v[i]->getVertex(j);
-    std::map<MVertex*,double>::iterator it = facts.find(vert);
-    if (it == facts.end())facts[vert] = .1;
-    else if (it->second < 1){
-    it->second += .1;
-    double ax, ay, az;
-    myAssembler.getDofValue(vert, 0, getTag(), ax);
-    myAssembler.getDofValue(vert, 1, getTag(), ay);
-    myAssembler.getDofValue(vert, 2, getTag(), az);
-    vert->x() -= .1*ax;
-    vert->y() -= .1*ay;
-    vert->z() -= .1*az;
-    }
-    }
-    }
-    if (!count)break;
-    Msg::Info("%d elements are negative : reducing displacement",count);
-    }
-  */
-
-  double percentage = max_incr * 100.;
-  while(1){
-    std::vector<MElement*> disto;
-    double minD;
-    getDistordedElements(v, 0.5, disto, minD);
-    if (minD < thres){
-      percentage -= 10.;
-      for (std::set<MVertex*>::iterator it = _vertices.begin(); it != _vertices.end(); ++it){
-	double ax, ay, az;
-	myAssembler.getDofValue(*it, 0, getTag(), ax);
-	myAssembler.getDofValue(*it, 1, getTag(), ay);
-	myAssembler.getDofValue(*it, 2, getTag(), az);
-	(*it)->x() -= .1*ax;
-	(*it)->y() -= .1*ay;
-	(*it)->z() -= .1*az;
-      }
-    }
-    else break;
-  }
-
-  delete lsys;
-  return percentage;
-#endif
-  return 0.0;
-}
-
-int highOrderSmoother::smooth_with_mixed_formulation (std::vector<MElement*> &all,
-						      double alpha)
-{
-  int ITER = 0;
-  double minD, FACT = 1.0;
-  std::vector<MElement*> disto;
-  // move the points to their straight sided locations
-  for (unsigned int i = 0; i < all.size(); i++)
-    moveToStraightSidedLocation(all[i]);
-  // apply the displacement
-  double percentage = 0.0;
-  while(1){
-    char NN[256];
-    sprintf(NN,"smoothing-%d.msh",ITER++);
-    //double percentage_of_what_is_left = apply_incremental_displacement (1.,all, false, alpha,NN,disto);
-    	  double percentage_of_what_is_left = apply_incremental_displacement (1.,all, true, alpha,NN,all);
-    percentage += (1.-percentage) * percentage_of_what_is_left/100.;
-    Msg::Info("The smoother was able to do %3d percent of the motion",(int)(percentage*100.));
-    if (percentage_of_what_is_left == 0.0) break;
-    else if (percentage_of_what_is_left == 100.)break;
-  }
-
-  getDistordedElements(all, 0.3, disto, minD);
-  Msg::Info("iter %d : %d elements / %d distorted  min Disto = %g ",ITER,
-	    all.size(), disto.size(), minD);
-
-  if (0 && percentage < 0.99){
-    char NN[256];
-    sprintf(NN,"smoothing-%d.msh",ITER++);
-    double percentage_of_what_is_left = apply_incremental_displacement (1.0,all, true, alpha,NN,disto);
-    percentage += (1.-percentage) * percentage_of_what_is_left/100.;
-    Msg::Info("The mixed smoother was able to do %3d percent of the motion",(int)(percentage*100.));
-  }
-
-  return 1;
-}
-
-
-void highOrderSmoother::smooth(std::vector<MElement*> &all)
-{
-#if defined(HAVE_TAUCS)
-  linearSystemCSRTaucs<double> *lsys = new linearSystemCSRTaucs<double>;
-#elif defined(HAVE_PETSC)
-  linearSystemPETSc<double> *lsys = new  linearSystemPETSc<double>;
-#else
-  linearSystemCSRGmm<double> *lsys = new linearSystemCSRGmm<double>;
-  lsys->setNoisy(1);
-  lsys->setGmres(1);
-  lsys->setPrec(5.e-8);
-#endif
-  dofManager<double> myAssembler(lsys);
-  elasticityTerm El(0, 1.0, .333, getTag());
-
-  std::vector<MElement*> layer, v;
-  double minD;
-
-  getDistordedElements(all, 0.15, v, minD);
-
-  Msg::Info("%d elements / %d distorted  min Disto = %g",
-             all.size(), v.size(), minD);
-
-  if (!v.size());
-
-  const int nbLayers = 3;
-  for (int i = 0; i < nbLayers; i++){
-    addOneLayer(all, v, layer);
-    v.insert(v.end(), layer.begin(), layer.end());
-  }
-
-  Msg::Debug("%d elements after adding %d layers\n", (int)v.size(), nbLayers);
-
-  addOneLayer(all, v, layer);
-
-  //  printf("%d elements in the next layer\n",layer.size());
-
-  for (unsigned int i = 0; i < layer.size(); i++){
-    for (int j = 0; j < layer[i]->getNumVertices(); j++){
-      MVertex *vert = layer[i]->getVertex(j);
-      myAssembler.fixVertex(vert, 0, getTag(), 0);
-      myAssembler.fixVertex(vert, 1, getTag(), 0);
-      myAssembler.fixVertex(vert, 2, getTag(), 0);
-    }
-  }
-
-  std::map<MVertex*,SVector3>::iterator it;
-  std::map<MVertex*,SVector3>::iterator its;
-  std::map<MVertex*,SVector3>::iterator itt;
-  std::map<MVertex*,SVector3> verticesToMove;
-
-  //  printf("%d vertices \n", _displ.size());
-
-  for (unsigned int i = 0; i < v.size(); i++){
-    for (int j = 0; j < v[i]->getNumVertices(); j++){
-      MVertex *vert = v[i]->getVertex(j);
-      // printf("%d %d %d v\n",i,j,v[i]->getNumVertices());
-      its = _straightSidedLocation.find(vert);
-      itt = _targetLocation.find(vert);
-      if (its != _straightSidedLocation.end() && vert->onWhat()->dim() < _dim){
-        myAssembler.fixVertex(vert, 0, getTag(), vert->x()-its->second.x());
-        myAssembler.fixVertex(vert, 1, getTag(), vert->y()-its->second.y());
-        myAssembler.fixVertex(vert, 2, getTag(), vert->z()-its->second.z());
-      }
-      // ensure we do not touch any vertex that is on the boundary
-      else if (vert->onWhat()->dim() < _dim){
-        myAssembler.fixVertex(vert, 0, getTag(), 0);
-        myAssembler.fixVertex(vert, 1, getTag(), 0);
-        myAssembler.fixVertex(vert, 2, getTag(), 0);
-      }
-    }
-  }
-
-  for (unsigned int i = 0; i < v.size(); i++)
-    moveToStraightSidedLocation(v[i]);
-
-  // number the other DOFs
-  for (unsigned int i = 0; i < v.size(); i++){
-    for (int j = 0; j < v[i]->getNumVertices(); j++){
-      MVertex *vert = v[i]->getVertex(j);
-      myAssembler.numberVertex(vert, 0, getTag());
-      myAssembler.numberVertex(vert, 1, getTag());
-      myAssembler.numberVertex(vert, 2, getTag());
-      // gather all vertices that are supposed to move
-      verticesToMove[vert] = SVector3(0.0, 0.0, 0.0);
-    }
-  }
-
-  //  Msg::Info("%d vertices FIXED %d NUMBERED", myAssembler.sizeOfF()
-  //        , myAssembler.sizeOfR());
-
-  if (myAssembler.sizeOfR()){
-
-    // assembly of the elasticity term on the
-    // set of elements
-    for (unsigned int i = 0; i < v.size(); i++){
-      SElement se(v[i]);
-      El.addToMatrix(myAssembler, &se);
-    }
-    // solve the system
-    lsys->systemSolve();
-  }
-
-  for (it = verticesToMove.begin(); it != verticesToMove.end(); ++it){
-    double ax, ay, az;
-    myAssembler.getDofValue(it->first, 0, getTag(), ax);
-    myAssembler.getDofValue(it->first, 1, getTag(), ay);
-    myAssembler.getDofValue(it->first, 2, getTag(), az);
-    it->first->x() += ax;
-    it->first->y() += ay;
-    it->first->z() += az;
-  }
-
-  // delete matrices and vectors
-
-  delete lsys;
-}
-
-void highOrderSmoother::smooth_cavity(std::vector<MElement*>& cavity,
-                                      std::vector<MElement*>& old_elems,
-                                      GFace* gf) {
-
-  //  printf("Smoothing a cavity...\n");
-  //  printf("Old elems : %d and %d\n", old_elems[0]->getNum(), old_elems[1]->getNum());
-  //  printf("Cavity elems : %d and %d\n", cavity[0]->getNum(), cavity[1]->getNum());
-  linearSystem<double> *lsys;
-#ifdef HAVE_TAUCS
-  if (cavity.size() < 20)
-    lsys = new linearSystemFull<double>;
-  else
-    lsys = new linearSystemCSRTaucs<double>;
-#else
-  linearSystemCSRGmm<double> *lsys_ = new linearSystemCSRGmm<double>;
-  lsys_->setNoisy(1);
-  lsys_->setGmres(1);
-  lsys_->setPrec(5.e-8);
-  lsys = lsys_;
-#endif
-
-  dofManager<double> myAssembler(lsys);
-  elasticityTerm El(0, 1.0, 0.333, getTag());
-
-  std::vector<MElement*> layer,v;
-
-  /* Debug only :p */
-  //cavity = old_elems;
-
-  v.insert(v.end(), gf->triangles.begin(),gf->triangles.end());
-  v.insert(v.end(), gf->quadrangles.begin(),gf->quadrangles.end());
-
-  addOneLayer(v,cavity,layer);
-
-  for (unsigned int i = 0; i < layer.size(); i++){
-    if (find(old_elems.begin(), old_elems.end(), layer[i]) == old_elems.end()) {
-      for (int j = 0; j < layer[i]->getNumVertices(); j++){
-	MVertex *vert = layer[i]->getVertex(j);
-	myAssembler.fixVertex(vert, 0, getTag(), 0);
-	myAssembler.fixVertex(vert, 1, getTag(), 0);
-	//printf("Fixing vertex %d\n", vert->getNum());
-      }
-    }
-  }
-
-  //printf("%d vertices \n", _displ.size());
-
-  std::set<MVertex*>::iterator it;
-  std::map<MVertex*,SVector3>::iterator its;
-  std::map<MVertex*,SVector3>::iterator itpresent;
-  std::map<MVertex*,SVector3>::iterator ittarget;
-  //std::map<MVertex*,SVector3> verticesToMove;
-  std::set<MVertex*> verticesToMove;
-
-  printf(" size = %d\n", (int)_straightSidedLocation.size());
-
-  for (unsigned int i = 0; i < cavity.size(); i++){
-    for (int j = 0; j < cavity[i]->getNumVertices(); j++){
-      MVertex *vert = cavity[i]->getVertex(j);
-      its = _straightSidedLocation.find(vert);
-      if (its == _straightSidedLocation.end()) {
-	//printf("SETTING LOCATIONS for %d\n",vert->getNum());
-        _straightSidedLocation[vert] =
-          SVector3(vert->x(), vert->y(), vert->z());
-        _targetLocation[vert] =
-          SVector3(vert->x(), vert->y(), vert->z());
-      }else {
-        vert->x() = its->second.x();
-        vert->y() = its->second.y();
-        vert->z() = its->second.z();
-        if (vert->onWhat()->dim() < _dim){
-          myAssembler.fixVertex(vert, 0, getTag(), 0);
-          myAssembler.fixVertex(vert, 1, getTag(), 0);
-	  //printf("Fixing vertex %d\n", vert->getNum());
-        }
-      }
-    }
-  }
-
-  // number the other DOFs
-  for (unsigned int i = 0; i < cavity.size(); i++){
-    for (int j = 0; j < cavity[i]->getNumVertices(); j++){
-      MVertex *vert = cavity[i]->getVertex(j);
-      //printf("Numbering vertex %d\n",vert->getNum());
-      myAssembler.numberVertex(vert, 0, getTag());
-      myAssembler.numberVertex(vert, 1, getTag());
-      verticesToMove.insert(vert);
-    }
-  }
-
-  //Msg::Info("%d vertices FIXED %d NUMBERED\n", myAssembler.sizeOfF()
-  //          , myAssembler.sizeOfR());
-
-  double dx0 = smooth_metric_(cavity, gf, myAssembler, verticesToMove, El);
-  double dx = dx0;
-  //printf(" dx0 = %12.5E\n", dx0);
-  int iter = 0;
-  while(1){
-    double dx2 = smooth_metric_(cavity, gf, myAssembler, verticesToMove, El);
-    //printf(" dx2  = %12.5E\n", dx2);
-    if (fabs(dx2 - dx) < 1.e-4 * dx0)break;
-    if (iter++ > 2)break;
-    dx = dx2;
-  }
-
-  for (it = verticesToMove.begin(); it != verticesToMove.end(); ++it){
-    SPoint2 param;
-    reparamMeshVertexOnFace(*it, gf, param);
-    GPoint gp = gf->point(param);
-    if ((*it)->onWhat()->dim() == 2){
-      (*it)->x() = gp.x();
-      (*it)->y() = gp.y();
-      (*it)->z() = gp.z();
-      _targetLocation[*it] = SVector3(gp.x(), gp.y(), gp.z());
-    }
-    else{
-      SVector3 p =  _targetLocation[(*it)];
-      (*it)->x() = p.x();
-      (*it)->y() = p.y();
-      (*it)->z() = p.z();
-    }
-    //printf("  Moving %d to %g %g %g\n", (*it)->getNum(),_targetLocation[(*it)][0], _targetLocation[(*it)][1],_targetLocation[(*it)][2] );
-  }
-
-  delete lsys;
-}
-
-
-/*
-  n3    n23     n2
-  x-----x-------x
-  |            /|
-  |    t1    /  |
-  |        /    |
-  x n13  x n12  x n24
-  |    /        |
-  |  /    t2    |
-  |/            |
-  x------x------x
-  n1    n14     n4
-*/
-
-/*
-  n34 is the new vertex, we'd like to put it at the
-  best place i.e. at a place where it maximizes the
-  minimal smoothness of the neighboring elements.
-
-  One can actually maximize this value or one can use
-  a standard interpolation scheme (transfinite or elliptic)
-  to place the point.
-*/
-
-static void getNodesP2(const MEdge &me, MTriangle *t1, MTriangle *t2,
-                       MVertex * &n1,MVertex * &n2,MVertex * &n3,MVertex * &n4,
-                       MVertex * &n12,MVertex * &n14,MVertex * &n24,MVertex * &n23,
-                       MVertex * &n13){
-
-  n1 = me.getVertex(0);
-  n2 = me.getVertex(1);
-
-  if (t1->getVertex(0) != n1 && t1->getVertex(0) != n2) n3 = t1->getVertex(0);
-  else if (t1->getVertex(1) != n1 && t1->getVertex(1) != n2) n3 = t1->getVertex(1);
-  else if (t1->getVertex(2) != n1 && t1->getVertex(2) != n2) n3 = t1->getVertex(2);
-  int iStart = 0;
-  for (;iStart<3;iStart++)
-    if (t1->getVertex(iStart) == n1)
-      break;
-  if (n2 == t1->getVertex((iStart+1)%3)){
-    n12 = t1->getVertex((iStart+0)%3 + 3);
-    n23 = t1->getVertex((iStart+1)%3 + 3);
-    n13 = t1->getVertex((iStart+2)%3 + 3);
-  }
-  else{
-    n13 = t1->getVertex((iStart+0)%3 + 3);
-    n23 = t1->getVertex((iStart+1)%3 + 3);
-    n12 = t1->getVertex((iStart+2)%3 + 3);
-  }
-
-  if (t2->getVertex(0) != n1 && t2->getVertex(0) != n2) n4 = t2->getVertex(0);
-  else if (t2->getVertex(1) != n1 && t2->getVertex(1) != n2) n4 = t2->getVertex(1);
-  else if (t2->getVertex(2) != n1 && t2->getVertex(2) != n2) n4 = t2->getVertex(2);
-  iStart = 0;
-  for (;iStart<3;iStart++)
-    if (t2->getVertex(iStart) == n1)
-      break;
-  if (n2 == t2->getVertex((iStart+1)%3)){
-    n24 = t2->getVertex((iStart+1)%3 + 3);
-    n14 = t2->getVertex((iStart+2)%3 + 3);
-  }
-  else{
-    n14 = t2->getVertex((iStart+0)%3 + 3);
-    n24 = t2->getVertex((iStart+1)%3 + 3);
-  }
-}
-
-static void getNodesPN (const MEdge &me, MTriangle *t1, MTriangle *t2,
-                        MVertex * &n1,MVertex * &n2,MVertex * &n3,MVertex * &n4,
-                        std::vector<MVertex *> &n12,
-                        std::vector<MVertex *> &n14,
-                        std::vector<MVertex *> &n24,
-                        std::vector<MVertex *> &n23,
-                        std::vector<MVertex *> &n13){
-
-  n1 = me.getVertex(0);
-  n2 = me.getVertex(1);
-
-  int order = t1->getPolynomialOrder();
-
-  if (t1->getVertex(0) != n1 && t1->getVertex(0) != n2) n3 = t1->getVertex(0);
-  else if (t1->getVertex(1) != n1 && t1->getVertex(1) != n2) n3 = t1->getVertex(1);
-  else if (t1->getVertex(2) != n1 && t1->getVertex(2) != n2) n3 = t1->getVertex(2);
-  int iStart = 0;
-  for (;iStart<3;iStart++)
-    if (t1->getVertex(iStart) == n1)
-      break;
-  if (n2 == t1->getVertex((iStart+1)%3)){
-    int start12 = 3 + ((iStart+0)%3) * (order-1);
-    for (int i=0;i<order-1;i++)n12.push_back(t1->getVertex(start12+i));
-    int start23 = 3 + ((iStart+1)%3) * (order-1);
-    for (int i=0;i<order-1;i++)n23.push_back(t1->getVertex(start23+i));
-    int start13 = 3 + ((iStart+2)%3) * (order-1);
-    for (int i=0;i<order-1;i++)n13.push_back(t1->getVertex(start13+i));
-  }
-  else{
-    int start13 = 3 + ((iStart+0)%3) * (order-1);
-    for (int i=order-2;i>=0;i--)n13.push_back(t1->getVertex(start13+i));
-    int start23 = 3 + ((iStart+1)%3) * (order-1);
-    for (int i=order-2;i>=0;i--)n23.push_back(t1->getVertex(start23+i));
-    int start12 = 3 + ((iStart+2)%3) * (order-1);
-    for (int i=order-2;i>=0;i--)n12.push_back(t1->getVertex(start12+i));
-  }
-
-  if (t2->getVertex(0) != n1 && t2->getVertex(0) != n2) n4 = t2->getVertex(0);
-  else if (t2->getVertex(1) != n1 && t2->getVertex(1) != n2) n4 = t2->getVertex(1);
-  else if (t2->getVertex(2) != n1 && t2->getVertex(2) != n2) n4 = t2->getVertex(2);
-  iStart = 0;
-  for (;iStart<3;iStart++)
-    if (t2->getVertex(iStart) == n1)
-      break;
-
-  if (n2 == t2->getVertex((iStart+1)%3)){
-    int start24 = 3 + ((iStart+1)%3) * (order-1);
-    for (int i=0;i<order-1;i++)n24.push_back(t2->getVertex(start24+i));
-    int start14 = 3 + ((iStart+2)%3) * (order-1);
-    for (int i=0;i<order-1;i++)n14.push_back(t2->getVertex(start14+i));
-  }
-  else{
-    int start14 = 3 + ((iStart+0)%3) * (order-1);
-    for (int i=order-2;i>=0;i--)n14.push_back(t1->getVertex(start14+i));
-    int start24 = 3 + ((iStart+1)%3) * (order-1);
-    for (int i=order-2;i>=0;i--)n24.push_back(t1->getVertex(start24+i));
-  }
-}
-
-static double surfaceTriangleUV(SPoint2 &v1, SPoint2 &v2, SPoint2 &v3)
-{
-  const double v12[2] = {v2.x() - v1.x(),v2.y() - v1.y()};
-  const double v13[2] = {v3.x() - v1.x(),v3.y() - v1.y()};
-  return 0.5 * fabs (v12[0] * v13[1] - v12[1] * v13[0]);
-}
-
-struct swap_triangles_p2
-{
-  MTriangle *t1, *t2;
-  MTriangle *t3, *t4;
-  double quality_old;
-  double quality_new;
-  double s_before,s_after;
-  MVertex *n1, *n2, *n3, *n4;
-  MVertex *n12, *n13, *n23, *n14, *n24;
-  MVertex *n34;
-
-  double evalConfiguration (GFace *gf, SPoint2 & p) const
-  {
-    GPoint gp34 = gf->point(p);
-    MFaceVertex _test (gp34.x(),gp34.y(),gp34.z(),gf,p.x(),p.y());
-    std::vector<MVertex *>vv;
-    vv.push_back(n13);vv.push_back(&_test);vv.push_back(n14);
-    MTriangleN t3_test (n1,n3,n4,vv,2,t1->getNum(),t1->getPartition());
-    vv.clear();
-    vv.push_back(&_test);vv.push_back(n23);vv.push_back(n24);
-    MTriangleN t4_test (n4,n3,n2,vv,2,t2->getNum(),t2->getPartition());
-    const double q3 = shapeMeasure(&t3_test);
-    const double q4 = shapeMeasure(&t4_test);
-    return std::min(q3,q4);
-  }
-
-  MVertex *optimalLocation (GFace *gf,
-                            SPoint2 &p3,
-                            SPoint2 &p4) const
-  {
-    SPoint2 p34_linear = (p3+p4)*.5;
-
-    GPoint gp34 = gf->point(p34_linear);
-    MFaceVertex *_test = new MFaceVertex (gp34.x(),gp34.y(),gp34.z(),
-                                          gf,p34_linear.x(),p34_linear.y());
-    std::vector<MVertex *>vv;
-    vv.push_back(n13);vv.push_back(_test);vv.push_back(n14);
-    MTriangleN t3_test (n1,n3,n4,vv,2,t1->getNum(),t1->getPartition());
-    vv.clear();
-    vv.push_back(_test);vv.push_back(n23);vv.push_back(n24);
-    MTriangleN t4_test (n4,n3,n2,vv,2,t2->getNum(),t2->getPartition());
-    p2data data(gf,&t3_test,&t4_test,_test,0);
-    fullVector<double> pp(2);
-    pp(0) = p34_linear.x();
-    pp(1) = p34_linear.y();
-    minimize_grad_fd (_function_p2tB, pp, &data);
-    return _test;
-  }
-
-  swap_triangles_p2(const MEdge &me, MTriangle *_t1, MTriangle *_t2, GFace *gf)
-    : t1(_t1), t2(_t2),n1(0),n2(0),n3(0),n12(0),n13(0), n23(0), n14(0), n24(0),n34(0)
-  {
-    const double qold1 = shapeMeasure(t1);
-    const double qold2 = shapeMeasure(t2);
-
-    getNodesP2 (me,t1,t2,n1,n2,n3,n4,n12,n14,n24,n23,n13);
-    SPoint2 p1,p2,p3,p4,p13,p24,p23,p14;
-    reparamMeshEdgeOnFace(n1,n2,gf,p1,p2);
-    reparamMeshEdgeOnFace(n3,n4,gf,p3,p4);
-    reparamMeshEdgeOnFace(n13,n24,gf,p13,p24);
-    reparamMeshEdgeOnFace(n23,n14,gf,p23,p14);
-
-    s_before = surfaceTriangleUV(p1,p2,p4) + surfaceTriangleUV(p1,p2,p3);
-    s_after =  surfaceTriangleUV(p3,p4,p1) + surfaceTriangleUV(p3,p4,p2);
-
-    n34 = optimalLocation (gf,p3,p4);
-
-    std::vector<MVertex *>vv;
-    vv.push_back(n13);vv.push_back(n34);vv.push_back(n14);
-    t3 = new MTriangleN (n1,n3,n4,vv,2,t1->getNum(),t1->getPartition());
-    vv.clear();
-    vv.push_back(n34);vv.push_back(n23);vv.push_back(n24);
-    t4 = new MTriangleN (n4,n3,n2,vv,2,t2->getNum(),t2->getPartition());
-
-    const double qnew1 = shapeMeasure(t3);
-    const double qnew2 = shapeMeasure(t4);
-
-    quality_new = std::min(qnew1,qnew2);
-    quality_old = std::min(qold1,qold2);
-  }
-  bool operator < (const swap_triangles_p2 &other) const
-  {
-    return  other.quality_new - other.quality_old < quality_new - quality_old;
-  }
-  void print() const
-  {
-    printf("%g <--- %g\n",quality_new,quality_old);
-    printf("%d %d %d %d %d %d\n",t1->getVertex(0)->getNum(),t1->getVertex(1)->getNum(),t1->getVertex(2)->getNum(),
-           t1->getVertex(3)->getNum(),t1->getVertex(4)->getNum(),t1->getVertex(5)->getNum());
-    printf("%d %d %d %d %d %d\n",t2->getVertex(0)->getNum(),t2->getVertex(1)->getNum(),t2->getVertex(2)->getNum(),
-           t2->getVertex(3)->getNum(),t2->getVertex(4)->getNum(),t2->getVertex(5)->getNum());
-    printf("%d %d %d %d %d %d\n",t3->getVertex(0)->getNum(),t3->getVertex(1)->getNum(),t3->getVertex(2)->getNum(),
-           t3->getVertex(3)->getNum(),t3->getVertex(4)->getNum(),t3->getVertex(5)->getNum());
-    printf("%d %d %d %d %d %d\n",t4->getVertex(0)->getNum(),t4->getVertex(1)->getNum(),t4->getVertex(2)->getNum(),
-           t4->getVertex(3)->getNum(),t4->getVertex(4)->getNum(),t4->getVertex(5)->getNum());
-    printf("%d %d %d %d %d %d %d %d %d\n",n1->getNum(),
-           n2->getNum(),n3->getNum(),n4->getNum(),
-           n12->getNum(),n23->getNum(),n13->getNum(),n24->getNum(),n14->getNum());
-  }
-
-};
-
-struct swap_triangles_pN
-{
-  MTriangle *t1, *t2;
-  MTriangle *t3, *t4;
-  double quality_old;
-  double quality_new;
-  double s_before,s_after;
-  MVertex *n1, *n2, *n3, *n4;
-  std::vector<MVertex*> n12, n13, n23, n14, n24, n34;
-  std::vector<MVertex*> n123, n124, n134, n234;
-  edgeContainer &edgeVertices;
-  faceContainer &faceVertices;
-  highOrderSmoother *s;
-
-  void cleanupDeletedEdge (bool swapWasSuccessfull )
-  {
-    MEdge _temp(swapWasSuccessfull ? n1 : n3 , swapWasSuccessfull ? n2 : n4 );
-    std::pair<MVertex*, MVertex*> _temp2(_temp.getMinVertex(), _temp.getMaxVertex());
-    edgeVertices.erase(_temp2);
-    // do the same for internal vertices !!
-  }
-
-  swap_triangles_pN(const MEdge &me, MTriangle *_t1, MTriangle *_t2, GFace *gf,
-                    edgeContainer &_edgeVertices,
-                    faceContainer &_faceVertices,
-                    highOrderSmoother *_s)
-    : t1(_t1), t2(_t2),edgeVertices(_edgeVertices),faceVertices(_faceVertices),s(_s)
-  {
-
-    const double qold1 = shapeMeasure(t1);
-    const double qold2 = shapeMeasure(t2);
-
-    getNodesPN (me,t1,t2,n1,n2,n3,n4,n12,n14,n24,n23,n13);
-    SPoint2 p1,p2,p3,p4,p13,p24,p23,p14;
-    reparamMeshEdgeOnFace(n1,n2,gf,p1,p2);
-    reparamMeshEdgeOnFace(n3,n4,gf,p3,p4);
-
-    s_before = surfaceTriangleUV(p1,p2,p4) + surfaceTriangleUV(p1,p2,p3);
-    s_after =  surfaceTriangleUV(p1,p4,p3) + surfaceTriangleUV(p3,p4,p2);
-
-    MTriangle t3lin(n1,n4,n3);
-    MTriangle t4lin(n3,n4,n2);
-
-    t3 =  setHighOrder(&t3lin,gf,edgeVertices,faceVertices,false,
-                       !t1->getNumFaceVertices(),
-                       t1->getPolynomialOrder()-1,s);
-    t4 =  setHighOrder(&t4lin,gf,edgeVertices,faceVertices,false,
-                       !t1->getNumFaceVertices(),
-                       t1->getPolynomialOrder()-1,s);
-
-    optimalLocationPN_ (gf,me, t3, t4,s);
-    std::vector<MElement*> cavity, old_elems;
-    cavity.push_back(t3);
-    cavity.push_back(t4);
-    old_elems.push_back(t1);
-    old_elems.push_back(t2);
-    //s->smooth_cavity(cavity, old_elems, gf);
-
-    const double qnew1 = shapeMeasure(t3);
-    const double qnew2 = shapeMeasure(t4);
-
-    quality_new = std::min(qnew1,qnew2);
-    quality_old = std::min(qold1,qold2);
-
-    //    if (quality_old < quality_new)
-    //printf("QUALITY GOING FROM %12.5E TO %12.5E\n",quality_old,quality_new);
-
-  }
-  bool operator < (const swap_triangles_pN &other) const
-  {
-    return  other.quality_new - other.quality_old < quality_new - quality_old;
-  }
-};
-
-static int optimalLocationP2_(GFace *gf,
-                              const MEdge &me,
-                              MTriangle *t1, MTriangle *t2,
-                              highOrderSmoother *s)
-{
-  double qini = std::min(shapeMeasure(t1),shapeMeasure(t2));
-
-  if (qini > 0.6) return 0;
-
-  MVertex *n1,*n2,*n3=0,*n4=0,*n12,*n14,*n24,*n23,*n13;
-  getNodesP2 (me,t1,t2,n1,n2,n3,n4,n12,n14,n24,n23,n13);
-  SPoint2 p1,p2,p3,p4,p12;
-  reparamMeshVertexOnFace(n12,gf,p12);
-  reparamMeshEdgeOnFace(n3,n4,gf,p3,p4);
-  reparamMeshEdgeOnFace(n3,n4,gf,p3,p4);
-  SPoint2 p34_linear = (p1+p2)*.5;
-  SPoint2 dirt = p4-p3;
-
-  fullVector<double> pp(2);
-  pp(0) = p12.x();
-  pp(1) = p12.y();
-  p2data data(gf,t1,t2,n12,s);
-
-  double init = _DeformationEnergy (&data);
-  double opti = minimize_grad_fd (_function_p2tB, pp, &data);
-
-  printf("opti %g init %g\n",opti,init);
-
-  if (init-opti < 1.e-5*(init))return 0;
-
-  double u0 = gf->parBounds(0).low();
-  double u1 = gf->parBounds(0).high();
-  double v0 = gf->parBounds(1).low();
-  double v1 = gf->parBounds(1).high();
-  if (pp(0) < u0 || pp(0) > u1 || pp(1) < v0 || pp(1) > v1)return 0;
-
-  GPoint gp12 = gf->point(SPoint2(pp(0),pp(1)));
-  n12->x() = gp12.x();
-  n12->y() = gp12.y();
-  n12->z() = gp12.z();
-  n12->setParameter(0,pp(0));
-  n12->setParameter(1,pp(1));
-  printf("Hum, order 2 here...");
-  return 1;
-}
-
-int optimalLocationPN_ (GFace *gf, const MEdge &me, MTriangle *t1, MTriangle *t2,
-                        highOrderSmoother *s)
-{
-  // if quality is sufficient, do nothing (this is an expensive
-  //  optimization process)
-  double qopt = std::min(shapeMeasure(t1),shapeMeasure(t2));
-  if (qopt > 0.6) return 0;
-  // get the 2 end vertex of the edge
-  MVertex *n1 = me.getVertex(0);
-  MVertex *n2 = me.getVertex(1);
-  // get all the other nodes that are on the edge
-  int N = t1->getNumVertices();
-  int NE = t1->getNumEdgeVertices();
-  std::vector<MVertex*> toOptimize;
-  for (int i=3;i<3+NE;i++){
-    MVertex *v1 = t1->getVertex(i);
-    for (int j=3;j<3+NE;j++){
-      MVertex *v2 = t2->getVertex(j);
-      if (v1 == v2 && v1 != n1 && v1 != n2){
-        toOptimize.push_back(v1);
-        break;
-      }
-    }
-  }
-
-  for (int i=3+NE;i<N;i++){
-    toOptimize.push_back(t1->getVertex(i));
-    toOptimize.push_back(t2->getVertex(i));
-  }
-
-  fullVector<double> pp(2*toOptimize.size());
-  for (unsigned int i=0;i<toOptimize.size();i++){
-    SPoint2 pt;
-    reparamMeshVertexOnFace(toOptimize[i],gf,pt);
-    pp(2*i)   = pt[0];
-    pp(2*i+1) = pt[1];
-  }
-
-  pNdata data(gf,t1,t2,toOptimize,s);
-  double init = _DeformationEnergy (&data);
-  double opti = minimize_grad_fd (_function_pNtB, pp, &data);
-  ///double opti = minimize_grad_fd (_function_pNt, pp, &data);
-  if (init-opti < 1.e-5*(init))return 0;
-  printf("Optimization has reduced the deformation energy %g -> %g\n",
-         init,opti);
-  for (unsigned int i=0;i<toOptimize.size();i++){
-    GPoint gp12 = gf->point(SPoint2(pp(2*i),pp(2*i+1)));
-    toOptimize[i]->x() = gp12.x();
-    toOptimize[i]->y() = gp12.y();
-    toOptimize[i]->z() = gp12.z();
-    toOptimize[i]->setParameter(0,pp(2*i));
-    toOptimize[i]->setParameter(1,pp(2*i+1));
-  }
-  return 1;
-}
-
-static int findOptimalLocationsP2(GFace *gf, highOrderSmoother *s)
-{
-  e2t_cont adj;
-  buildEdgeToTriangle(gf->triangles, adj);
-  int N=0;
-  for (e2t_cont::iterator it = adj.begin(); it!= adj.end(); ++it){
-    if (it->second.second)
-      N += optimalLocationP2_(gf,it->first, dynamic_cast<MTriangle*>(it->second.first),
-                              dynamic_cast<MTriangle*>(it->second.second),s);
-  }
-  return N;
-}
-
-static int findOptimalLocationsPN(GFace *gf,highOrderSmoother *s)
-{
-
-  e2t_cont adj;
-  buildEdgeToTriangle(gf->triangles, adj);
-  int N=0;
-
-  for (e2t_cont::iterator it = adj.begin(); it!= adj.end(); ++it){
-    if (it->second.second)
-      N += optimalLocationPN_(gf,it->first, dynamic_cast<MTriangle*>(it->second.first),
-                              dynamic_cast<MTriangle*>(it->second.second),s);
-  }
-  return N;
-}
-
-static int swapHighOrderTriangles(GFace *gf,
-                                  edgeContainer &edgeVertices,
-                                  faceContainer &faceVertices,
-                                  highOrderSmoother *s)
-{
-  printf ("Initial Size of the map %d\n", (int)edgeVertices.size());
-  printf ("Initial Size of the face map %d\n", (int)faceVertices.size());
-
-  e2t_cont adj;
-  buildEdgeToTriangle(gf->triangles, adj);
-
-  std::set<swap_triangles_pN> pairs;
-
-  for (e2t_cont::iterator it = adj.begin(); it!= adj.end(); ++it){
-    if (it->second.second){
-      MTriangle *t1 = dynamic_cast<MTriangle*>(it->second.first);
-      MTriangle *t2 = dynamic_cast<MTriangle*>(it->second.second);
-
-      const double qold1 = shapeMeasure(t1);
-      const double qold2 = shapeMeasure(t2);
-
-      //if (qold1 < 0.6 || qold2 < 0.06)
-        pairs.insert(swap_triangles_pN(it->first,t1,t2,gf,
-                                       edgeVertices,faceVertices,s));
-    }
-  }
-
-  std::set<swap_triangles_pN>::iterator itp = pairs.begin();
-
-  int nbSwap = 0;
-
-  std::set<MTriangle*> t_removed;
-  std::set<MVertex*> v_removed;
-
-  std::vector<MTriangle*> triangles2;
-  std::vector<MVertex*> mesh_vertices2;
-
-  itp = pairs.begin();
-  while(itp != pairs.end()){
-    double diff = fabs(itp->s_before - itp->s_after);
-
-    std::vector<MVertex*> v1,v2,v3,v4;
-    int o1 = itp->t1->getPolynomialOrder();
-    int o2 = itp->t2->getPolynomialOrder();
-    int o3 = itp->t3->getPolynomialOrder();
-    int o4 = itp->t4->getPolynomialOrder();
-
-    itp->t1->getFaceVertices(0,v1);
-    itp->t2->getFaceVertices(0,v2);
-    itp->t3->getFaceVertices(0,v3);
-    itp->t4->getFaceVertices(0,v4);
-
-    std::vector<MVertex*> ve1(v1.begin()+3,v1.begin()+3*o1);
-    std::vector<MVertex*> ve2(v2.begin()+3,v2.begin()+3*o2);
-    std::vector<MVertex*> ve3(v3.begin()+3,v3.begin()+3*o3);
-    std::vector<MVertex*> ve4(v4.begin()+3,v4.begin()+3*o4);
-    std::vector<MVertex*> vf1(v1.begin()+3*o1,v1.end());
-    std::vector<MVertex*> vf2(v2.begin()+3*o2,v2.end());
-    std::vector<MVertex*> vf3(v3.begin()+3*o3,v3.end());
-    std::vector<MVertex*> vf4(v4.begin()+3*o4,v4.end());
-
-    bool t1_rem = (t_removed.find(itp->t1) != t_removed.end());
-    bool t2_rem = (t_removed.find(itp->t2) != t_removed.end());
-
-    if ( !t1_rem && !t2_rem &&
-         itp->quality_new > 0 && //itp->quality_old &&
-         diff < 1.e-9){
-
-      swap_triangles_pN &sw = (swap_triangles_pN &) *itp;
-      sw.cleanupDeletedEdge (true);
-
-      t_removed.insert(itp->t1);
-      t_removed.insert(itp->t2);
-      v_removed.insert(vf1.begin(),vf1.end());
-      v_removed.insert(vf2.begin(),vf2.end());
-
-      triangles2.push_back(itp->t3);
-      triangles2.push_back(itp->t4);
-      mesh_vertices2.insert(mesh_vertices2.end(),vf3.begin(),vf3.end());
-      mesh_vertices2.insert(mesh_vertices2.end(),vf4.begin(),vf4.end());
-
-      for(std::vector<MVertex*>::iterator vit = ve1.begin(); vit != ve1.end(); vit++) {
-        if (find(ve2.begin(),ve2.end(),*vit)!=ve2.end())
-          v_removed.insert(*vit);
-      }
-
-      nbSwap++;
-    }
-    else {
-      for(std::vector<MVertex*>::iterator vit = ve3.begin(); vit != ve3.end(); vit++) {
-        if (find(ve4.begin(),ve4.end(),*vit)!=ve4.end())
-          v_removed.insert(*vit);
-	  //delete  *vit;
-      }
-
-      swap_triangles_pN &sw = (swap_triangles_pN &) *itp;
-      sw.cleanupDeletedEdge (false);
-
-      delete itp->t3;
-      delete itp->t4;
-    }
-    ++itp;
-  }
-
-  for (unsigned int i = 0; i < gf->mesh_vertices.size(); i++){
-    if (v_removed.find(gf->mesh_vertices[i]) == v_removed.end()){
-      mesh_vertices2.push_back(gf->mesh_vertices[i]);
-    }
-  }
-
-  gf->mesh_vertices.clear();
-  gf->mesh_vertices = mesh_vertices2;
-
-  for (unsigned int i = 0; i < gf->triangles.size(); i++){
-    if (t_removed.find(gf->triangles[i]) == t_removed.end()){
-      triangles2.push_back(gf->triangles[i]);
-    }
-    else {
-      delete gf->triangles[i];
-    }
-  }
-  gf->triangles.clear();
-  gf->triangles = triangles2;
-  printf("%d swaps performed\n", nbSwap);
-  printf("Final Size of the map %d\n", (int)edgeVertices.size());
-  printf("Final Size of the face map %d\n", (int)faceVertices.size());
-  return nbSwap;
-}
-
-static int swapHighOrderTriangles(GFace *gf)
-{
-  e2t_cont adj;
-  buildEdgeToTriangle(gf->triangles, adj);
-
-  std::set<swap_triangles_p2> pairs;
-
-  for (e2t_cont::iterator it = adj.begin(); it!= adj.end(); ++it){
-    if (it->second.second){
-      MTriangle *t1 = dynamic_cast<MTriangle*>(it->second.first);
-      MTriangle *t2 = dynamic_cast<MTriangle*>(it->second.second);
-      const double qold1 = shapeMeasure(t1);
-      const double qold2 = shapeMeasure(t2);
-      if (qold1 < 0.6 || qold2 < 0.6)
-        pairs.insert(swap_triangles_p2(it->first,t1,t2,gf));
-    }
-  }
-  std::set<swap_triangles_p2>::iterator itp = pairs.begin();
-
-  int nbSwap = 0;
-
-  std::set<MTriangle*> t_removed;
-  std::set<MVertex*> v_removed;
-
-  std::vector<MTriangle*> triangles2;
-  std::vector<MVertex*> mesh_vertices2;
-
-  itp = pairs.begin();
-  while(itp != pairs.end()){
-    double diff = fabs(itp->s_before - itp->s_after);
-    if ( t_removed.find(itp->t1) == t_removed.end() &&
-         t_removed.find(itp->t2) == t_removed.end() &&
-         itp->quality_new > itp->quality_old &&
-         diff < 1.e-9){
-      //      itp->print();
-      t_removed.insert(itp->t1);
-      t_removed.insert(itp->t2);
-      triangles2.push_back(itp->t3);
-      triangles2.push_back(itp->t4);
-      if (itp->n34 != itp->n12){
-        v_removed.insert(itp->n12);
-        mesh_vertices2.push_back(itp->n34);
-      }
-      nbSwap++;
-    }
-    else{
-      delete itp->t3;
-      delete itp->t4;
-      if (itp->n34 != itp->n12) delete itp->n34;
-    }
-    ++itp;
-  }
-
-  for (unsigned int i = 0; i < gf->mesh_vertices.size(); i++){
-    if (v_removed.find(gf->mesh_vertices[i]) == v_removed.end()){
-      mesh_vertices2.push_back(gf->mesh_vertices[i]);
-    }
-    else {
-      delete gf->mesh_vertices[i];
-    }
-  }
-  gf->mesh_vertices = mesh_vertices2;
-
-  for (unsigned int i = 0; i < gf->triangles.size(); i++){
-    if (t_removed.find(gf->triangles[i]) == t_removed.end()){
-      triangles2.push_back(gf->triangles[i]);
-    }
-    else {
-      delete gf->triangles[i];
-    }
-  }
-  //  printf("replacing %d by %d\n",gf->triangles.size(),triangles2.size());
-  gf->triangles = triangles2;
-  return nbSwap;
-}
-
-void  highOrderSmoother::swap(GFace *gf,
-                                  edgeContainer &edgeVertices,
-                                  faceContainer &faceVertices)
-{
-  // swapHighOrderTriangles(gf);
-  swapHighOrderTriangles(gf,edgeVertices,faceVertices,this);
-  // swapHighOrderTriangles(gf);
-  // swapHighOrderTriangles(gf);
-  // swapHighOrderTriangles(gf);
-}
-
-void  highOrderSmoother::smooth_p2point(GFace *gf)
-{
-  findOptimalLocationsP2(gf,this);
-  // findOptimalLocationsP2(gf);
-  // findOptimalLocationsP2(gf);
-}
-
-void  highOrderSmoother::smooth_pNpoint(GFace *gf)
-{
-  findOptimalLocationsPN(gf,this);
-}
-
-//-------------------------------------------------
-// Assume a GModel that is meshed with high order nodes that
-// are on their final position (at least they all lie on
-// surfaces and curves and the smoother may move them)
-//-------------------------------------------------
-
-highOrderSmoother::highOrderSmoother (GModel *gm)
-  : _tag(111)
-{
-  _clean();
-  // compute straigh sided positions that are actually X,Y,Z positions
-  // that are NOT always on curves and surfaces
-
-  // compute stright sided positions of vertices that are classified on model edges
-  for(GModel::eiter it = gm->firstEdge(); it != gm->lastEdge(); ++it){
-    for (int i=0;i<(*it)->lines.size();i++){
-      MLine *l = (*it)->lines[i];
-      int N = l->getNumVertices()-2;
-      SVector3 p0((*it)->lines[i]->getVertex(0)->x(),
-		  (*it)->lines[i]->getVertex(0)->y(),
-		  (*it)->lines[i]->getVertex(0)->z());
-      SVector3 p1((*it)->lines[i]->getVertex(1)->x(),
-		  (*it)->lines[i]->getVertex(1)->y(),
-		  (*it)->lines[i]->getVertex(1)->z());
-      for (int j=1;j<=N;j++){
-	const double xi = (double)j/(N+1);
-	const SVector3 straightSidedPoint = p0 *(1.-xi) + p1*xi;
-	_straightSidedLocation [(*it)->lines[i]->getVertex(j)] = straightSidedPoint;
-      }
-    }
-  }
-
-  // compute stright sided positions of vertices that are classified on model faces
-  for(GModel::fiter it = gm->firstFace(); it != gm->lastFace(); ++it){
-    for (int i=0;i<(*it)->triangles.size();i++){
-      MTriangle *t = (*it)->triangles[i];
-      MFace face = t->getFace(0);
-      const polynomialBasis* fs = t->getFunctionSpace();
-      for (int j=0;j<t->getNumVertices();j++){
-	if (t->getVertex(j)->onWhat() == *it){
-	  const double t1 = fs->points(j, 0);
-	  const double t2 = fs->points(j, 1);
-	  SPoint3 pc = face.interpolate(t1, t2);
-	  _straightSidedLocation [t->getVertex(j)] =
-	    SVector3(pc.x(),pc.y(),pc.z());
-	}
-      }
-    }
-    for (int i=0;i<(*it)->quadrangles.size();i++){
-      MQuadrangle *q = (*it)->quadrangles[i];
-      MFace face = q->getFace(0);
-      const polynomialBasis* fs = q->getFunctionSpace();
-      for (int j=0;j<q->getNumVertices();j++){
-	if (q->getVertex(j)->onWhat() == *it){
-	  const double t1 = fs->points(j, 0);
-	  const double t2 = fs->points(j, 1);
-	  SPoint3 pc = face.interpolate(t1, t2);
-	  _straightSidedLocation [q->getVertex(j)] =
-	    SVector3(pc.x(),pc.y(),pc.z());
-	}
-      }
-    }
-  }
-}
-
-
-#endif
-
diff --git a/contrib/HighOrderMeshOptimizer/OptHomElastic.h b/contrib/HighOrderMeshOptimizer/OptHomElastic.h
deleted file mode 100644
index bedd568dc3d3bb859ae19306b6fec55e0aa9e49f..0000000000000000000000000000000000000000
--- a/contrib/HighOrderMeshOptimizer/OptHomElastic.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// Gmsh - Copyright (C) 1997-2013 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>.
-
-#ifndef _HIGH_ORDER_SMOOTHER_H_
-#define _HIGH_ORDER_SMOOTHER_H_
-
-#include <map>
-#include <vector>
-#include "GmshConfig.h"
-#include "GmshMessage.h"
-
-#if defined(HAVE_SOLVER)
-
-#include "SVector3.h"
-#include "fullMatrix.h"
-#include "dofManager.h"
-#include "elasticityTerm.h"
-
-class MVertex;
-class MElement;
-class GFace;
-class GRegion;
-
-class highOrderSmoother 
-{
-  const int _tag;
-  std::map<MVertex*,SVector3> _straightSidedLocation;
-  std::map<MVertex*,SVector3> _targetLocation;
-  int _dim;
-  void _clean()
-  {
-    _straightSidedLocation.clear();
-    _targetLocation.clear();
-  }
-  double _MIDDLE;
-  void moveTo(MVertex *v, const std::map<MVertex*,SVector3> &) const;
-public:  
-  highOrderSmoother(int dim) : _tag(111), _dim(dim) {_clean();}
-  highOrderSmoother(GModel *gm);
-  void add(MVertex * v, const SVector3 &d ) {
-    _straightSidedLocation[v] = d;
-    _targetLocation[v]        = SPoint3(v->x(),v->y(),v->z());
-  }  
-  int smooth_with_mixed_formulation(std::vector<MElement*> & , 
-				    double alpha);
-  double apply_incremental_displacement (double max_incr, std::vector<MElement*> & v,
-					 bool mixed, double thres, char *meshName,
-					 std::vector<MElement*> & disto);
-  void smooth(std::vector<MElement*> & );
-  double smooth_metric_(std::vector<MElement*> &, GFace *gf,
-                        dofManager<double> &myAssembler,
-                        std::set<MVertex*> &verticesToMove,
-                        elasticityTerm &El);
-  void smooth_metric(std::vector<MElement*> &, GFace *gf );
-  void smooth(GFace *, bool metric = false);
-  void smooth_p2point(GFace *);
-  void smooth_pNpoint(GFace *);
-  void smooth(GRegion*);
-  void smooth_cavity(std::vector<MElement*> &,
-                     std::vector<MElement*> &,
-                     GFace *gf);
-  int getTag() const { return _tag; }
-  void swap(GFace *, 
-            edgeContainer &edgeVertices,
-            faceContainer &faceVertices);
-
-  void optimize(GFace *, 
-                edgeContainer &edgeVertices,
-                faceContainer &faceVertices);
-  void computeMetricVector(GFace *gf, 
-                           MElement *e, 
-                           fullMatrix<double> &J,
-                           fullMatrix<double> &JT,
-                           fullVector<double> &D);
-  void moveToStraightSidedLocation(MVertex *) const;
-  void moveToTargetLocation(MVertex *) const;
-  void moveToStraightSidedLocation(MElement *) const;
-  void moveToTargetLocation(MElement *) const;  
-  void updateTargetLocation(MVertex*, const SPoint3 &, const SPoint2 &) ;
-  inline SVector3 getSSL(MVertex *v) const
-  {
-     std::map<MVertex*,SVector3>::const_iterator it =  _straightSidedLocation.find(v);
-     if (it != _straightSidedLocation.end())return it->second;
-     else return SVector3(v->x(),v->y(),v->z());
-  }
-  inline SVector3 getDisplacement(MVertex *v) const
-  {
-     std::map<MVertex*,SVector3>::const_iterator it  =  _straightSidedLocation.find(v);
-     std::map<MVertex*,SVector3>::const_iterator itt =  _targetLocation.find(v);
-     if (it == _straightSidedLocation.end())
-       return SVector3(0.0,0.0,0.0);
-     else{
-       return SVector3(itt->second.x() - it->second.x(),
-                       itt->second.y() - it->second.y(),
-                       itt->second.z() - it->second.z());
-     }
-  }
-};
-
-#else
-
-class highOrderSmoother 
-{
- public:
-  highOrderSmoother(int dim) 
-  {
-    Msg::Error("Gmsh has to be compiled with solver support to use highOrderSmoother");
-  }
-  void add(MVertex * v, const SVector3 &d ){}  
-  void smooth(GRegion*){}
-  void optimize(GFace *, 
-                edgeContainer &edgeVertices,
-                faceContainer &faceVertices){}
-};
-
-#endif
-
-#endif