diff --git a/CMakeLists.txt b/CMakeLists.txt
index 744fe3695db19c4c91f4891cee5df5389bd0703a..78caf910c30e3705cde6e606f62f494923d9a4cc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -35,6 +35,7 @@ option(ENABLE_MATHEX "Enable MathEx expression parser" ON)
 option(ENABLE_MED "Enable MED mesh and post-processing file formats" ON)
 option(ENABLE_MESH "Build the mesh module" ON)
 option(ENABLE_METIS "Enable Metis mesh partitioner" ON)
+option(ENABLE_MMG3D "Enable 3D Mobile Mesh Generation" ON)
 option(ENABLE_MPEG_ENCODE "Enable built-in MPEG encoder" ON)
 option(ENABLE_MPI "Enable MPI parallelization" OFF)
 option(ENABLE_MSVC_STATIC_RUNTIME "Use static Visual C++ runtime" OFF)
@@ -537,6 +538,12 @@ if(HAVE_MESH)
     set_config_option(HAVE_BAMG "Bamg")
   endif(ENABLE_BAMG)
 
+  if(ENABLE_MMG3D)
+    add_subdirectory(contrib/mmg3d)
+    include_directories(contrib/mmg3d/build/sources)
+    set_config_option(HAVE_MMG3D "Mmg3d")
+  endif(ENABLE_MMG3D)
+
   if(ENABLE_TETGEN_NEW AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/TetgenNew/tetgen.h)
     add_subdirectory(contrib/TetgenNew)
     include_directories(contrib/TetgenNew)
diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index 12b07737ead006b75a4f3c2f656ab0d0b25583ff..091f202422d128e4abb8e1190d00b5b8fa320d72 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -66,7 +66,7 @@ void PrintUsage(const char *name)
   Msg::Direct("  -bin                  Use binary format when available");  
   Msg::Direct("  -parametric           Save vertices with their parametric coordinates");  
   Msg::Direct("  -numsubedges          Set the number of subdivisions when displaying high order elements");  
-  Msg::Direct("  -algo string          Select mesh algorithm (meshadapt, del2d, front2d, delquad, del3d, front3d)");
+  Msg::Direct("  -algo string          Select mesh algorithm (meshadapt, del2d, front2d, delquad, del3d, front3d, mmg3d)");
   Msg::Direct("  -smooth int           Set number of mesh smoothing steps");
   Msg::Direct("  -order int            Set mesh order (1, ..., 5)");
   Msg::Direct("  -optimize[_netgen]    Optimize quality of tetrahedral elements");
@@ -550,6 +550,12 @@ void GetOptions(int argc, char *argv[])
             CTX::instance()->mesh.algo3d = ALGO_3D_DELAUNAY;
           else if(!strncmp(argv[i], "front3d", 7) || !strncmp(argv[i], "netgen", 6))
             CTX::instance()->mesh.algo3d = ALGO_3D_FRONTAL;
+          else if(!strncmp(argv[i], "mmg3d", 5))
+            CTX::instance()->mesh.algo3d = ALGO_3D_MMG3D;
+          else if(!strncmp(argv[i], "delfr3d", 7))
+            CTX::instance()->mesh.algo3d = ALGO_3D_FRONTAL_DEL;
+          else if(!strncmp(argv[i], "delhex3d", 8))
+            CTX::instance()->mesh.algo3d = ALGO_3D_FRONTAL_HEX;
           else
             Msg::Fatal("Unknown mesh algorithm");
           i++;
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index d1d4947561dd37a0578f31b279953d0da705c65c..6d68032505eaf3dac496cbc6d3e4a76a90221bd0 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -1018,7 +1018,7 @@ StringXNumber MeshOptions_Number[] = {
 #else
     ALGO_3D_FRONTAL ,
 #endif
-    "3D mesh algorithm (1=Delaunay, 4=Frontal)" }, 
+    "3D mesh algorithm (1=Delaunay, 4=Frontal, 5=Frontal Delaunay, 6=Frontal Hex, 7=MMG3D)" }, 
   { F|O, "AngleSmoothNormals" , opt_mesh_angle_smooth_normals , 30.0 ,
     "Threshold angle below which normals are not smoothed" }, 
   { F|O, "AnisoMax" , opt_mesh_aniso_max, 1.e33,
diff --git a/Common/GmshConfig.h.in b/Common/GmshConfig.h.in
index 0b6e218679788eecc14d30b026fcc88d989c59b5..8997d6166b192d610d5905acb387ee6eb4bffdf6 100644
--- a/Common/GmshConfig.h.in
+++ b/Common/GmshConfig.h.in
@@ -31,6 +31,7 @@
 #cmakedefine HAVE_MED
 #cmakedefine HAVE_MESH
 #cmakedefine HAVE_METIS
+#cmakedefine HAVE_MMG3D
 #cmakedefine HAVE_MPEG_ENCODE
 #cmakedefine HAVE_MPI
 #cmakedefine HAVE_NATIVE_FILE_CHOOSER
diff --git a/Common/GmshDefines.h b/Common/GmshDefines.h
index c9588df974953115cd5767eaa27666010f859b12..40883c08efcfc88f6ff4d49bc9517d02b6b60a70 100644
--- a/Common/GmshDefines.h
+++ b/Common/GmshDefines.h
@@ -188,6 +188,9 @@
 // 3D meshing algorithms (numbers should not be changed)
 #define ALGO_3D_DELAUNAY       1
 #define ALGO_3D_FRONTAL        4
+#define ALGO_3D_FRONTAL_DEL    5
+#define ALGO_3D_FRONTAL_HEX    6
+#define ALGO_3D_MMG3D          7
 
 // Meshing methods
 #define MESH_NONE         0
diff --git a/Common/Options.cpp b/Common/Options.cpp
index ea727f097b5ab7ee26ab4282e731d0e208b922e2..fad1ca4b32354804c218a97e3bf6436c52415a91 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -5788,6 +5788,15 @@ double opt_mesh_algo3d(OPT_ARGS_NUM)
 #if defined(HAVE_FLTK)
   if(FlGui::available() && (action & GMSH_GUI)) {
     switch (CTX::instance()->mesh.algo3d) {
+    case ALGO_3D_MMG3D:
+      FlGui::instance()->options->mesh.choice[3]->value(4);
+      break;
+    case ALGO_3D_FRONTAL_HEX:
+      FlGui::instance()->options->mesh.choice[3]->value(3);
+      break;
+    case ALGO_3D_FRONTAL_DEL:
+      FlGui::instance()->options->mesh.choice[3]->value(2);
+      break;
     case ALGO_3D_FRONTAL:
       FlGui::instance()->options->mesh.choice[3]->value(1);
       break;
diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp
index 658e241b5b5e9393684ee8852d585349d62efb23..ae18612bb1827b294e74f25512548ee81ec65999 100644
--- a/Fltk/optionWindow.cpp
+++ b/Fltk/optionWindow.cpp
@@ -482,6 +482,9 @@ static void mesh_options_ok_cb(Fl_Widget *w, void *data)
                   ALGO_2D_AUTO);
   opt_mesh_algo3d(0, GMSH_SET,
                   (o->mesh.choice[3]->value() == 0) ? ALGO_3D_DELAUNAY : 
+                  (o->mesh.choice[3]->value() == 2) ? ALGO_3D_FRONTAL_DEL : 
+                  (o->mesh.choice[3]->value() == 3) ? ALGO_3D_FRONTAL_HEX : 
+                  (o->mesh.choice[3]->value() == 4) ? ALGO_3D_MMG3D : 
                   ALGO_3D_FRONTAL);
   opt_mesh_algo_recombine(0, GMSH_SET, o->mesh.choice[1]->value());
   opt_mesh_recombine_all(0, GMSH_SET, o->mesh.butt[21]->value());
@@ -2068,6 +2071,9 @@ optionWindow::optionWindow(int deltaFontSize)
       static Fl_Menu_Item menu_3d_algo[] = {
         {"Delaunay", 0, 0, 0},
         {"Frontal", 0, 0, 0},
+        {"Frontal Delaunay", 0, 0, 0},
+        {"Frontal Hex", 0, 0, 0},
+        {"MMG3D", 0, 0, 0},
         {0}
       };
       static Fl_Menu_Item menu_recombination_algo[] = {
diff --git a/Geo/GEdge.cpp b/Geo/GEdge.cpp
index 7e0a86b73bc899700ff9261a4dd3a411f86fe5d8..4c4606cafcdf59af4f1064758ffa522bbb0c63e1 100644
--- a/Geo/GEdge.cpp
+++ b/Geo/GEdge.cpp
@@ -219,6 +219,17 @@ SVector3 GEdge::secondDer(double par) const
 {
   // use central differences
   const double eps = 1.e-3;
+  Range<double> rg = parBounds(0);
+  if (par-eps <= rg.low()){
+    SVector3 x1 = firstDer(par);
+    SVector3 x2 = firstDer(par + eps);
+    return 1000 * (x2 - x1);
+  }
+  else if (par+eps >= rg.high()){
+    SVector3 x1 = firstDer(par-eps);
+    SVector3 x2 = firstDer(par);
+    return 1000 * (x2 - x1);
+  }
   SVector3 x1 = firstDer(par - eps);
   SVector3 x2 = firstDer(par + eps);
   return 500 * (x2 - x1);
diff --git a/Geo/GFaceCompound.cpp b/Geo/GFaceCompound.cpp
index 2b03cb029fb27dc3f2c4b041b4614ec385ee68bd..c8a0e169425b2c907853ee0461dbb78e9eae6cf4 100644
--- a/Geo/GFaceCompound.cpp
+++ b/Geo/GFaceCompound.cpp
@@ -1697,13 +1697,18 @@ GPoint GFaceCompound::point(double par1, double par2) const
   }
   
   const bool LINEARMESH = true; //false
+  
+  if (lt->gf->geomType() != GEntity::DiscreteSurface){
+    SPoint2 pParam = lt->gfp1*(1.-U-V) + lt->gfp2*U + lt->gfp3*V;
+    return lt->gf->point(pParam);
+  }
 
   if(LINEARMESH){
 
     //linear Lagrange mesh
     //-------------------------
     p = lt->v1*(1.-U-V) + lt->v2*U + lt->v3*V;
-    return GPoint(p.x(),p.y(),p.z(),this,par);
+    return GPoint(p.x(),p.y(),p.z(),this,par);    
 
   }
   else{
diff --git a/Geo/Geo.cpp b/Geo/Geo.cpp
index 3e5aab3dcc66d6bc09a640664def4f43a4ad7bb1..776a25aa766e35ca99865374dd1405ae4c4d4aba 100644
--- a/Geo/Geo.cpp
+++ b/Geo/Geo.cpp
@@ -3543,7 +3543,7 @@ void setSurfaceEmbeddedCurves(Surface *s, List_T *curves)
     if(c)
       List_Add(s->EmbeddedCurves, &c);
     else
-      Msg::Error("Unknown curve %d", iCurve);
+      Msg::Error("Unknown curve %d", (int)iCurve);
   }
 }
 
diff --git a/Mesh/BackgroundMesh.cpp b/Mesh/BackgroundMesh.cpp
index 369d107f27cb4d04bbd1fec2fcac2bbf0745e7e7..b81af0c6e9d9a9b4479d745b6c9788040986c664 100644
--- a/Mesh/BackgroundMesh.cpp
+++ b/Mesh/BackgroundMesh.cpp
@@ -222,16 +222,16 @@ static double LC_MVertex_CURV(GEntity *ge, double U, double V)
   double Crv = 0;
   switch(ge->dim()){
   case 0:        
-    Crv = max_edge_curvature((const GVertex *)ge);
-    Crv = std::max(max_surf_curvature((const GVertex *)ge), Crv);
-    //Crv = max_surf_curvature((const GVertex *)ge);
+    //    Crv = max_edge_curvature((const GVertex *)ge);
+    //    Crv = std::max(max_surf_curvature((const GVertex *)ge), Crv);
+    Crv = max_surf_curvature((const GVertex *)ge);
     break;
   case 1:
     {
       GEdge *ged = (GEdge *)ge;
-      Crv = ged->curvature(U)*2;
-      Crv = std::max(Crv, max_surf_curvature(ged, U));
-      //Crv = max_surf_curvature(ged, U);      
+      //      Crv = ged->curvature(U)*2;
+      //      Crv = std::max(Crv, max_surf_curvature(ged, U));
+      Crv = max_surf_curvature(ged, U);
     }
     break;
   case 2:
@@ -441,16 +441,17 @@ backgroundMesh::backgroundMesh(GFace *_gf)
   _octree = new MElementOctree(_triangles); 
 
   // compute the mesh sizes at nodes
-  if (CTX::instance()->mesh.lcFromPoints)
+  if (CTX::instance()->mesh.lcExtendFromBoundary){
     propagate1dMesh(_gf);
+  }
   else {
     std::map<MVertex*, MVertex*>::iterator itv2 = _2Dto3D.begin();
     for ( ; itv2 != _2Dto3D.end(); ++itv2){
       _sizes[itv2->first] = MAX_LC;
     }
   }
-  // ensure that other criteria are fullfilled 
-  updateSizes(_gf);
+  // ensure that other criteria are fullfilled
+  //    updateSizes(_gf);
 
   // compute optimal mesh orientations
   propagatecrossField(_gf);
@@ -700,7 +701,7 @@ void backgroundMesh::updateSizes(GFace *_gf)
       bool success = reparamMeshVertexOnFace(v, _gf, p);       
       lc = BGM_MeshSize(_gf, p.x(), p.y(), v->x(), v->y(), v->z());
     }
-    //    printf("2D -- %g %g 3D -- %g %g\n",p.x(),p.y(),v->x(),v->y());
+    //    printf("2D -- %g %g 3D -- %g %g lc %g\n",p.x(),p.y(),v->x(),v->y(),lc);
     itv->second = std::min(lc,itv->second);
     itv->second = std::max(itv->second, CTX::instance()->mesh.lcMin);
     itv->second = std::min(itv->second, CTX::instance()->mesh.lcMax);
diff --git a/Mesh/CMakeLists.txt b/Mesh/CMakeLists.txt
index 22aeb98b05aff9d1bf5bcb4e96afe0a34cdeadb6..3f626aff6c361a6b3f96e83aec525d398f46e8a9 100644
--- a/Mesh/CMakeLists.txt
+++ b/Mesh/CMakeLists.txt
@@ -16,7 +16,7 @@ set(SRC
     meshGRegion.cpp 
       meshGRegionDelaunayInsertion.cpp meshGRegionTransfinite.cpp 
       meshGRegionExtruded.cpp  meshGRegionCarveHole.cpp 
-      meshGRegionLocalMeshMod.cpp
+      meshGRegionLocalMeshMod.cpp meshGRegionMMG3D.cpp
     BackgroundMesh.cpp 
     qualityMeasures.cpp 
     BoundaryLayers.cpp 
diff --git a/Mesh/Field.cpp b/Mesh/Field.cpp
index de40cee7b4baa896e304baba7e954b15c4b4d1b3..b26a705e096e03b68c920279dd0d336c4f35ec2d 100644
--- a/Mesh/Field.cpp
+++ b/Mesh/Field.cpp
@@ -1580,7 +1580,8 @@ class AttractorField : public Field
       for(std::list<int>::iterator it = edges_id.begin();
           it != edges_id.end(); ++it) {
         Curve *c = FindCurve(*it);
-        if(c) {
+	GEdge *e = GModel::current()->getEdgeByTag(*it);
+        if(c && !e) {
           for(int i = 0; i < n_nodes_by_edge; i++) {
             double u = (double)i / (n_nodes_by_edge - 1);
             Vertex V = InterpolateCurve(c, u, 0);
@@ -1589,7 +1590,6 @@ class AttractorField : public Field
           }
         }
         else {
-          GEdge *e = GModel::current()->getEdgeByTag(*it);
           if(e) {
             for(int i = 0; i < n_nodes_by_edge; i++) {
               double u = (double)i / (n_nodes_by_edge - 1);
diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp
index 609a15a4e7adc59f2ded451450552d485d0f5a80..4da46d9e240529f1e1fbe2060d653757d12c0d41 100644
--- a/Mesh/meshGFace.cpp
+++ b/Mesh/meshGFace.cpp
@@ -886,7 +886,7 @@ static bool meshGenerator(GFace *gf, int RECUR_ITER,
     if(CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL)
       bowyerWatsonFrontal(gf);
     else if(CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL_QUAD)
-      bowyerWatsonFrontalQuad(gf);
+      bowyerWatsonFrontalLayers(gf,true);
     else if(CTX::instance()->mesh.algo2d == ALGO_2D_DELAUNAY ||
             CTX::instance()->mesh.algo2d == ALGO_2D_AUTO)
       bowyerWatson(gf);
@@ -1477,7 +1477,7 @@ static bool meshGeneratorPeriodic(GFace *gf, bool debug = true)
     if(CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL)
       bowyerWatsonFrontal(gf);
     else if(CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL_QUAD)
-      bowyerWatsonFrontalQuad(gf);
+      bowyerWatsonFrontalLayers(gf,true);
     else if(CTX::instance()->mesh.algo2d == ALGO_2D_DELAUNAY ||
             CTX::instance()->mesh.algo2d == ALGO_2D_AUTO)
       bowyerWatson(gf);
diff --git a/Mesh/meshGFaceDelaunayInsertion.cpp b/Mesh/meshGFaceDelaunayInsertion.cpp
index f5eb885cf259fae81805d70106846c9e115e1bd6..d70a5ca0ab3f74e08ff60daff7afe715d684f985 100644
--- a/Mesh/meshGFaceDelaunayInsertion.cpp
+++ b/Mesh/meshGFaceDelaunayInsertion.cpp
@@ -15,6 +15,7 @@
 #include "GFace.h"
 #include "Numeric.h"
 #include "STensor3.h"
+#include "Context.h"
 
 double LIMIT_ = 0.5 * sqrt(2.0) * 1;
 
@@ -558,7 +559,9 @@ bool insertVertex(GFace *gf, MVertex *v, double *param , MTri3 *t,
     double d2 = sqrt((it->v[1]->x() - v->x()) * (it->v[1]->x() - v->x()) +
                      (it->v[1]->y() - v->y()) * (it->v[1]->y() - v->y()) +
                      (it->v[1]->z() - v->z()) * (it->v[1]->z() - v->z()));
-    if (d1 < LL * .25 || d2 < LL * .25) onePointIsTooClose = true;
+    const double MID[3] = {0.5*(it->v[0]->x()+it->v[1]->x()),0.5*(it->v[0]->y()+it->v[1]->y()),0.5*(it->v[0]->z()+it->v[1]->z())}; 
+    double d3 = sqrt((MID[0] - v->x()) * (MID[0] - v->x()) + (MID[1] - v->y()) * (MID[1] - v->y()) + (MID[2] - v->z()) * (MID[2] - v->z()));
+    if (d1 < LL * .25 || d2 < LL * .25 || d3 < LL * .25) onePointIsTooClose = true;
     
     // if (t4->getRadius () < LIMIT_ / 2) onePointIsTooClose = true;
 
@@ -662,6 +665,7 @@ static MTri3* search4Triangle (MTri3 *t, double pt[2],
   bool inside = invMapUV(t->tri(), pt, Us, Vs, uv, 1.e-8);    
   if (inside) return t;
   SPoint3 q1(pt[0],pt[1],0);
+  int ITER = 0;
   while (1){
     //    printf("%d %d %d\n",t->tri()->getVertex(0)->getIndex(),t->tri()->getVertex(1)->getIndex() ,t->tri()->getVertex(2)->getIndex());
     SPoint3 q2((Us[t->tri()->getVertex(0)->getIndex()] +  Us[t->tri()->getVertex(1)->getIndex()] + Us[t->tri()->getVertex(2)->getIndex()])/3.0,
@@ -679,6 +683,7 @@ static MTri3* search4Triangle (MTri3 *t, double pt[2],
     if (!t)break;
     bool inside = invMapUV(t->tri(), pt, Us, Vs, uv, 1.e-8);        
     if (inside) {return t;}
+    if (ITER++ > AllTris.size())break;
   }
 
   for(std::set<MTri3*,compareTri3Ptr>::iterator itx =  AllTris.begin(); itx != AllTris.end();++itx){
@@ -730,7 +735,7 @@ static bool insertAPoint(GFace *gf, std::set<MTri3*,compareTri3Ptr>::iterator it
     if (inside)ptin = worst->getNeigh(2);
     }
   }
-  else if (MTri3::radiusNorm == -1){
+  else {
     ptin =  search4Triangle (worst, center, Us, Vs, AllTris);
     if (ptin)inside = true;
   }
@@ -745,7 +750,7 @@ static bool insertAPoint(GFace *gf, std::set<MTri3*,compareTri3Ptr>::iterator it
     MVertex *v = new MFaceVertex(p.x(), p.y(), p.z(), gf, center[0], center[1]);
     v->setIndex(Us.size());
     double lc1,lc;
-    if (0 && backgroundMesh::current()){
+    if (backgroundMesh::current()){
       lc1 = lc = 
 	backgroundMesh::current()->operator()(center[0], center[1], 0.0);
     }
@@ -947,6 +952,69 @@ static double lengthMetric(const double p[2], const double q[2],
      
 */
 
+void optimalPointFrontal (GFace *gf, 
+			  MTri3* worst, 
+			  int active_edge,
+			  std::vector<double> &Us,
+			  std::vector<double> &Vs,
+			  std::vector<double> &vSizes,
+			  std::vector<double> &vSizesBGM,			  
+			  double newPoint[2],
+			  double metric[3]){
+  double center[2],r2;
+  MTriangle *base = worst->tri();
+  circUV(base, Us, Vs, center, gf);
+  double pa[2] = {(Us[base->getVertex(0)->getIndex()] + 
+		   Us[base->getVertex(1)->getIndex()] + 
+		   Us[base->getVertex(2)->getIndex()]) / 3.,
+		  (Vs[base->getVertex(0)->getIndex()] + 
+		   Vs[base->getVertex(1)->getIndex()] + 
+		   Vs[base->getVertex(2)->getIndex()]) / 3.};
+  buildMetric(gf, pa, metric);
+  circumCenterMetric(worst->tri(), metric, Us, Vs, center, r2); 
+  // compute the middle point of the edge
+  int ip1 = active_edge - 1 < 0 ? 2 : active_edge - 1;
+  int ip2 = active_edge;
+
+  double P[2] =  {Us[base->getVertex(ip1)->getIndex()],  
+		  Vs[base->getVertex(ip1)->getIndex()]};
+  double Q[2] =  {Us[base->getVertex(ip2)->getIndex()], 
+		  Vs[base->getVertex(ip2)->getIndex()]};
+  double midpoint[2] = {0.5 * (P[0] + Q[0]), 0.5 * (P[1] + Q[1])};
+      
+  // now we have the edge center and the center of the circumcircle, 
+  // we try to find a point that would produce a perfect triangle while
+  // connecting the 2 points of the active edge
+  
+  double dir[2] = {center[0] - midpoint[0], center[1] - midpoint[1]};
+  double norm = sqrt(dir[0] * dir[0] + dir[1] * dir[1]);
+  dir[0] /= norm;
+  dir[1] /= norm;
+  const double RATIO = sqrt(dir[0] * dir[0] * metric[0] +
+			    2 * dir[1] * dir[0] * metric[1] +
+			    dir[1] * dir[1] * metric[2]);    
+  
+  const double p = 0.5 * lengthMetric(P, Q, metric); // / RATIO;
+  const double q = lengthMetric(center, midpoint, metric);
+  const double rhoM1 = 0.5 * 
+    (vSizes[base->getVertex(ip1)->getIndex()] + 
+     vSizes[base->getVertex(ip2)->getIndex()] ) / sqrt(3.);// * RATIO;
+  const double rhoM2 = 0.5 * 
+    (vSizesBGM[base->getVertex(ip1)->getIndex()] + 
+     vSizesBGM[base->getVertex(ip2)->getIndex()] ) / sqrt(3.);// * RATIO;
+  const double rhoM  = Extend1dMeshIn2dSurfaces() ? std::min(rhoM1, rhoM2) : rhoM2;
+  
+  const double rhoM_hat = std::min(std::max(rhoM, p), (p * p + q * q) / (2 * q));
+  const double d = (rhoM_hat + sqrt (rhoM_hat * rhoM_hat - p * p)) / RATIO;
+  
+  //  printf("(%g %g) (%g %g) %g %g %g %g %g %g\n",P[0],P[1],Q[0],Q[1],RATIO,p,q,rhoM,rhoM_hat,d);
+
+
+  newPoint[0] = midpoint[0] + d * dir[0]; 
+  newPoint[1] = midpoint[1] + d * dir[1];
+}
+
+
 void bowyerWatsonFrontal(GFace *gf)
 {
   std::set<MTri3*,compareTri3Ptr> AllTris;
@@ -975,9 +1043,9 @@ void bowyerWatsonFrontal(GFace *gf)
     /*
         if(ITER % 1== 0){
           char name[245];
-          sprintf(name,"delfr2d%d-ITER%4d.pos",gf->tag(),ITER);
+          sprintf(name,"delfr2d%d-ITER%d.pos",gf->tag(),ITER);
           _printTris (name, AllTris, Us,Vs,false);
-          sprintf(name,"delfr2dA%d-ITER%4d.pos",gf->tag(),ITER);
+          sprintf(name,"delfr2dA%d-ITER%d.pos",gf->tag(),ITER);
           _printTris (name, ActiveTris, Us,Vs,false);
         }
     */
@@ -991,64 +1059,13 @@ void bowyerWatsonFrontal(GFace *gf)
       if(ITER++ % 5000 == 0)
         Msg::Debug("%7d points created -- Worst tri radius is %8.3f",
                    vSizes.size(), worst->getRadius());
-      // compute circum center of that guy
-      double center[2],metric[3],r2;
-      MTriangle *base = worst->tri();
-      circUV(base, Us, Vs, center, gf);
-      double pa[2] = {(Us[base->getVertex(0)->getIndex()] + 
-                       Us[base->getVertex(1)->getIndex()] + 
-                       Us[base->getVertex(2)->getIndex()]) / 3.,
-                      (Vs[base->getVertex(0)->getIndex()] + 
-                       Vs[base->getVertex(1)->getIndex()] + 
-                       Vs[base->getVertex(2)->getIndex()]) / 3.};
-      buildMetric(gf, pa, metric);
-      circumCenterMetric(worst->tri(), metric, Us, Vs, center, r2); 
-      // compute the middle point of the edge
-      int ip1 = active_edge - 1 < 0 ? 2 : active_edge - 1;
-      int ip2 = active_edge;
-      // printf("the active edge is %d : %g %g -> %g %g\n",
-      //        active_edge,base->getVertex(ip1)->x(),base->getVertex(ip1)->y(),
-      //        base->getVertex(ip2)->x(),base->getVertex(ip2)->y());
-      double P[2] =  {Us[base->getVertex(ip1)->getIndex()],  
-                      Vs[base->getVertex(ip1)->getIndex()]};
-      double Q[2] =  {Us[base->getVertex(ip2)->getIndex()], 
-                      Vs[base->getVertex(ip2)->getIndex()]};
-      double midpoint[2] = {0.5 * (P[0] + Q[0]), 0.5 * (P[1] + Q[1])};
-      
-      // now we have the edge center and the center of the circumcircle, 
-      // we try to find a point that would produce a perfect triangle while
-      // connecting the 2 points of the active edge
-      
-      double dir[2] = {center[0] - midpoint[0], center[1] - midpoint[1]};
-      double norm = sqrt(dir[0] * dir[0] + dir[1] * dir[1]);
-      dir[0] /= norm;
-      dir[1] /= norm;
-      const double RATIO = sqrt(dir[0] * dir[0] * metric[0] +
-                                2 * dir[1] * dir[0] * metric[1] +
-                                dir[1] * dir[1] * metric[2]);    
-      
-      const double p = 0.5 * lengthMetric(P, Q, metric); // / RATIO;
-      const double q = lengthMetric(center, midpoint, metric);
-      const double rhoM1 = 0.5 * 
-        (vSizes[base->getVertex(ip1)->getIndex()] + 
-         vSizes[base->getVertex(ip2)->getIndex()] ) / sqrt(3.);// * RATIO;
-      const double rhoM2 = 0.5 * 
-        (vSizesBGM[base->getVertex(ip1)->getIndex()] + 
-         vSizesBGM[base->getVertex(ip2)->getIndex()] ) / sqrt(3.);// * RATIO;
-      const double rhoM  = Extend1dMeshIn2dSurfaces() ? std::min(rhoM1, rhoM2) : rhoM2;
-      // const double rhoM = 0.5 * 
-      //   (vSizes[base->getVertex(ip1)->getIndex()] + 
-      //    vSizes[base->getVertex(ip2)->getIndex()] ) / sqrt(3.);// * RATIO;
-      
-      const double rhoM_hat = std::min(std::max(rhoM, p), (p * p + q * q) / (2 * q));
-      const double d = (rhoM_hat + sqrt (rhoM_hat * rhoM_hat - p * p)) / RATIO;
-      
-      double newPoint[2] = {midpoint[0] + d * dir[0], midpoint[1] + d * dir[1]};
+      double newPoint[2], metric[3];
+      optimalPointFrontal (gf,worst,active_edge,Us,Vs,vSizes,vSizesBGM,newPoint,metric);
       insertAPoint(gf, AllTris.end(), newPoint, metric, Us, Vs, vSizes,
                    vSizesBGM, vMetricsBGM, AllTris, &ActiveTris, worst);
     } 
-    /*
-   if(ITER % 100== 0){
+    
+    /*   if(ITER % 1== 0){
        char name[245];
        sprintf(name,"frontal%d-ITER%d.pos",gf->tag(),ITER);
        _printTris (name, AllTris, Us,Vs,false);
@@ -1064,8 +1081,91 @@ void bowyerWatsonFrontal(GFace *gf)
   transferDataStructure(gf, AllTris, Us, Vs); 
 } 
 
+void optimalPointFrontalQuad (GFace *gf, 
+			      MTri3* worst, 
+			      int active_edge,
+			      std::vector<double> &Us,
+			      std::vector<double> &Vs,
+			      std::vector<double> &vSizes,
+			      std::vector<double> &vSizesBGM,			  
+			      double newPoint[2],
+			      double metric[3]){
+  MTriangle *base = worst->tri();
+  int ip1 = active_edge - 1 < 0 ? 2 : active_edge - 1;
+  int ip2 = active_edge;
+  int ip3 = (active_edge+1)%3;
+	
+  double P[2] =  {Us[base->getVertex(ip1)->getIndex()],  
+		  Vs[base->getVertex(ip1)->getIndex()]};
+  double Q[2] =  {Us[base->getVertex(ip2)->getIndex()], 
+		  Vs[base->getVertex(ip2)->getIndex()]};
+  double O[2] =  {Us[base->getVertex(ip3)->getIndex()], 
+		  Vs[base->getVertex(ip3)->getIndex()]};
+  double midpoint[2] = {0.5 * (P[0] + Q[0]), 0.5 * (P[1] + Q[1])};
+  
+  // compute background mesh data
+  double quadAngle  = backgroundMesh::current()->getAngle (midpoint[0],midpoint[1],0);
+  double center[2];
+  circumCenterInfinite (base, quadAngle,Us,Vs,center);                        
+  
+  // rotate the points with respect to the angle
+  double XP1 = 0.5*(Q[0] - P[0]);
+  double YP1 = 0.5*(Q[1] - P[1]);
+  double xp =  XP1 * cos(quadAngle) + YP1 * sin(quadAngle); 
+  double yp = -XP1 * sin(quadAngle) + YP1 * cos(quadAngle); 	  
+  // ensure xp > yp
+  bool exchange = false;
+  if (fabs(xp) < fabs(yp)){
+    double temp = xp;
+    xp = yp;
+    yp = temp;
+    exchange = true;
+  }
+	
+  buildMetric(gf, midpoint, metric);
+  double RATIO = 1./pow(metric[0]*metric[2]-metric[1]*metric[1],0.25);
+  
+  const double p = 0.5 * lengthInfniteNorm(P, Q, quadAngle); 
+  const double q = lengthInfniteNorm(center, midpoint, quadAngle);
+  const double rhoM1 = 0.5 * RATIO * 
+    (vSizes[base->getVertex(ip1)->getIndex()] + 
+     vSizes[base->getVertex(ip2)->getIndex()] ) / sqrt(3.);// * RATIO;
+  const double rhoM2 = 0.5 * RATIO *  
+    (vSizesBGM[base->getVertex(ip1)->getIndex()] + 
+     vSizesBGM[base->getVertex(ip2)->getIndex()] ) / sqrt(3.);// * RATIO;
+  const double rhoM  = Extend1dMeshIn2dSurfaces() ? std::min(rhoM1, rhoM2) : rhoM2;
+  
+  const double rhoM_hat = std::min(std::max(rhoM, p), (p * p + q * q) / (2 * q));
+  const double factor = (rhoM_hat + sqrt (rhoM_hat * rhoM_hat - p * p)) /(sqrt(3)*p);
+	
+  double npx,npy;
+  if (xp*yp >  0){
+    npx = - fabs(xp)*factor;
+    npy = fabs(xp)*(1.+factor) - fabs(yp);
+  }
+  else {
+    npx = fabs(xp) * factor;
+    npy = (1.+factor)*fabs(xp) - fabs(yp);
+  }
+  if (exchange){
+    double temp = npx;
+    npx = npy;
+    npy = temp;
+  }	  
+  
+  
+  newPoint[0] = midpoint[0] + cos(quadAngle) * npx - sin(quadAngle) * npy;
+  newPoint[1] = midpoint[1] + sin(quadAngle) * npx + cos(quadAngle) * npy;
+
+  if ((midpoint[0] - newPoint[0])*(midpoint[0] - O[0]) +
+      (midpoint[1] - newPoint[1])*(midpoint[1] - O[1]) < 0){
+    newPoint[0] = midpoint[0] - cos(quadAngle) * npx + sin(quadAngle) * npy;
+    newPoint[1] = midpoint[1] - sin(quadAngle) * npx - cos(quadAngle) * npy;
+  } 
+}	
 
-void bowyerWatsonFrontalQuad(GFace *gf)
+
+void bowyerWatsonFrontalLayers(GFace *gf, bool quad)
 {
 
   std::set<MTri3*,compareTri3Ptr> AllTris;
@@ -1080,7 +1180,10 @@ void bowyerWatsonFrontalQuad(GFace *gf)
 				 gf->triangles[i]->getVertex(1),
 				 gf->triangles[i]->getVertex(2)));
     }
+    int CurvControl = CTX::instance()->mesh.lcFromCurvature;
+    CTX::instance()->mesh.lcFromCurvature = 0;    
     bowyerWatson(gf);
+    CTX::instance()->mesh.lcFromCurvature = CurvControl;    
     backgroundMesh::set(gf);
     char name[256];
     sprintf(name,"bgm-%d.pos",gf->tag());
@@ -1091,10 +1194,10 @@ void bowyerWatsonFrontalQuad(GFace *gf)
     gf->triangles = TR;    
   }
 
-  LIMIT_ = sqrt(2)*.99;
-  //  LIMIT_ = 1.7;
-  MTri3::radiusNorm = -1;
-
+  if (quad){
+    LIMIT_ = sqrt(2)*.99;
+    MTri3::radiusNorm =-1;
+  }
   
   buildMeshGenerationDataStructures
     (gf, AllTris, vSizes, vSizesBGM, vMetricsBGM,Us, Vs);
@@ -1117,6 +1220,7 @@ void bowyerWatsonFrontalQuad(GFace *gf)
 
   // insert points
   int ITERATION = 1;
+  int max_layers = quad ? 10000 : 4;
   while (1){
     ITERATION ++;
     if(ITERATION % 1== 0){
@@ -1142,7 +1246,7 @@ void bowyerWatsonFrontalQuad(GFace *gf)
       
       MTri3 *worst = (*WORST_ITER);
       ActiveTris.erase(WORST_ITER);
-      if (!worst->isDeleted() && isActive(worst, LIMIT_, active_edge,&_front) && 
+      if (!worst->isDeleted() && (ITERATION > max_layers ? isActive(worst, LIMIT_, active_edge) : isActive(worst, LIMIT_, active_edge,&_front) ) && 
 	  worst->getRadius() > LIMIT_){
 	//	for (active_edge = 0 ; active_edge < 0 ; active_edge ++){
 	//	  if (active_edges[active_edge])break;	
@@ -1152,107 +1256,9 @@ void bowyerWatsonFrontalQuad(GFace *gf)
 		     vSizes.size(), worst->getRadius(),_front.size());
 	
 	// compute the middle point of the edge
-	MTriangle *base = worst->tri();
-	int ip1 = active_edge - 1 < 0 ? 2 : active_edge - 1;
-	int ip2 = active_edge;
-	int ip3 = (active_edge+1)%3;
-	
-	double P[2] =  {Us[base->getVertex(ip1)->getIndex()],  
-			Vs[base->getVertex(ip1)->getIndex()]};
-	double Q[2] =  {Us[base->getVertex(ip2)->getIndex()], 
-			Vs[base->getVertex(ip2)->getIndex()]};
-	double O[2] =  {Us[base->getVertex(ip3)->getIndex()], 
-			Vs[base->getVertex(ip3)->getIndex()]};
-	double midpoint[2] = {0.5 * (P[0] + Q[0]), 0.5 * (P[1] + Q[1])};
-	
-	// compute background mesh data
-	double quadAngle  = backgroundMesh::current()->getAngle (midpoint[0],midpoint[1],0);
-	//      quadAngle  = 35*M_PI/180;
-	//double quadAngle  = backgroundMesh::current()->getAngle (0.5*(base->getVertex(ip1)->x()+base->getVertex(ip2)->x()),
-	//							       0.5*(base->getVertex(ip1)->y()+base->getVertex(ip2)->y()),
-	//						       0.5*(base->getVertex(ip1)->x()+base->getVertex(ip2)->x()));
-	//      printf("quadAngle = %12.5E\n",quadAngle*180/M_PI);
-	//      double meshSize  = backgroundMesh::current()->operator()(midpoint[0],midpoint[1],0);
-	//double quadAngle = 0;      
-	double center[2];
-	circumCenterInfinite (base, quadAngle,Us,Vs,center);                        
-	
-	// rotate the points with respect to the angle
-	double XP1 = 0.5*(Q[0] - P[0]);
-	double YP1 = 0.5*(Q[1] - P[1]);
-	double xp =  XP1 * cos(quadAngle) + YP1 * sin(quadAngle); 
-	double yp = -XP1 * sin(quadAngle) + YP1 * cos(quadAngle); 	  
-	// ensure xp > yp
-	bool exchange = false;
-	if (fabs(xp) < fabs(yp)){
-	  double temp = xp;
-	  xp = yp;
-	  yp = temp;
-	  exchange = true;
-	}
-	
-	// dl^2 = dx^2 sqrt(\det M)
-	double metric[3];
-	buildMetric(gf, midpoint, metric);
-	double RATIO = 1./pow(metric[0]*metric[2]-metric[1]*metric[1],0.25);
-	
-	if (gf->tag() == 1900){RATIO = 0.3;/*printf("%g ratio\n",RATIO);*/}
-	//	printf("%g ratio\n",RATIO);
-	const double p = 0.5 * lengthInfniteNorm(P, Q, quadAngle); 
-	const double q = lengthInfniteNorm(center, midpoint, quadAngle);
-	const double rhoM1 = 0.5 * RATIO * 
-	  (vSizes[base->getVertex(ip1)->getIndex()] + 
-	   vSizes[base->getVertex(ip2)->getIndex()] ) / sqrt(3.);// * RATIO;
-	const double rhoM2 = 0.5 * RATIO *  
-	  (vSizesBGM[base->getVertex(ip1)->getIndex()] + 
-	   vSizesBGM[base->getVertex(ip2)->getIndex()] ) / sqrt(3.);// * RATIO;
-	const double rhoM  = Extend1dMeshIn2dSurfaces() ? std::min(rhoM1, rhoM2) : rhoM2;
-	
-	const double rhoM_hat = std::min(std::max(rhoM, p), (p * p + q * q) / (2 * q));
-	// const double rhoM_hat = std::max(rhoM, p);
-	// assume rhoM = L/\sqrt{3}
-	// assume that p = L/2
-	// d = L/\sqrt{3} + \sqrt{L/3 - L/4} = L/\sqrt{3} + L/2\sqrt{3} = \sqrt{3} L / 2 ... OK 
-	const double factor = (rhoM_hat + sqrt (rhoM_hat * rhoM_hat - p * p)) /(sqrt(3)*p);
-	//      printf("factor = %g\n",factor);
-	
-	double npx,npy;
-	if (xp*yp >  0){
-	  npx = - fabs(xp)*factor;
-	  npy = fabs(xp)*(1.+factor) - fabs(yp);
-	}
-	else {
-	  npx = fabs(xp) * factor;
-	  npy = (1.+factor)*fabs(xp) - fabs(yp);
-	}
-	if (exchange){
-	  double temp = npx;
-	  npx = npy;
-	  npy = temp;
-	}	  
-	
-	
-	double newPoint[2] = {midpoint[0] + cos(quadAngle) * npx - sin(quadAngle) * npy,
-			      midpoint[1] + sin(quadAngle) * npx + cos(quadAngle) * npy};
-	/*
-	  printf("exchange %d\n",exchange);
-	  printf("P %g %g\n",P[0],P[1]);
-	  printf("Q %g %g\n",Q[0],Q[1]);
-	  printf("midpoint %g %g\n",midpoint[0],midpoint[1]);
-	  printf("xp yp  %g %g\n",xp,yp);
-	  printf("O %g %g\n",O[0],O[1]);
-	  printf("dx %g %g\n",npx,npy);
-	*/
-	if ((midpoint[0] - newPoint[0])*(midpoint[0] - O[0]) +
-	    (midpoint[1] - newPoint[1])*(midpoint[1] - O[1]) < 0){
-	  newPoint[0] = midpoint[0] - cos(quadAngle) * npx + sin(quadAngle) * npy;
-	  newPoint[1] = midpoint[1] - sin(quadAngle) * npx - cos(quadAngle) * npy;
-	  
-	  //	printf("wrong sense %g \n",(midpoint[0] - newPoint[0])*(midpoint[0] - O[0]) +
-	  //	  (midpoint[1] - newPoint[1])*(midpoint[1] - O[1]));
-	} 
-	
-	//      printf("new %g %g\n",newPoint[0],newPoint[1]);
+	double newPoint[2],metric[3]={1,0,1};
+	if (quad)optimalPointFrontalQuad (gf,worst,active_edge,Us,Vs,vSizes,vSizesBGM,newPoint,metric);
+	else optimalPointFrontal (gf,worst,active_edge,Us,Vs,vSizes,vSizesBGM,newPoint,metric);
 	
 	
 	insertAPoint(gf, AllTris.end(), newPoint, 0, Us, Vs, vSizes,
@@ -1261,8 +1267,9 @@ void bowyerWatsonFrontalQuad(GFace *gf)
 	//	ActiveTrisNotInFront.insert(worst);
 	//      }
 	
+	
 	/*
-	  if(ITER % 100== 0){
+	  if(ITER % 1== 0){
 	  char name[245];
 	  sprintf(name,"frontal%d-ITER%d.pos",gf->tag(),ITER);
 	  _printTris (name, AllTris, Us,Vs,false);
diff --git a/Mesh/meshGFaceDelaunayInsertion.h b/Mesh/meshGFaceDelaunayInsertion.h
index 0aab515285a5683c9cb9907b5410f570b356aebc..0890d9888c29358cd8a79d92f88da6472a523dda 100644
--- a/Mesh/meshGFaceDelaunayInsertion.h
+++ b/Mesh/meshGFaceDelaunayInsertion.h
@@ -96,7 +96,7 @@ void connectTriangles(std::vector<MTri3*> &);
 void connectTriangles(std::set<MTri3*,compareTri3Ptr> &AllTris);
 void bowyerWatson(GFace *gf);
 void bowyerWatsonFrontal(GFace *gf);
-void bowyerWatsonFrontalQuad(GFace *gf);
+void bowyerWatsonFrontalLayers(GFace *gf, bool quad);
 
 struct edgeXface
 {
diff --git a/Mesh/meshGRegion.cpp b/Mesh/meshGRegion.cpp
index 0f104fa8f69a338efe4267f0c51793a3666834c1..4fb32b0633a16b3c92fd48d1c5f112a8e6f36b51 100644
--- a/Mesh/meshGRegion.cpp
+++ b/Mesh/meshGRegion.cpp
@@ -21,6 +21,7 @@
 #include "BDS.h"
 #include "Context.h"
 #include "GFaceCompound.h"
+#include "meshGRegionMMG3D.h"
 
 #if defined(HAVE_ANN)
 #include "ANN/ANN.h"
@@ -561,7 +562,14 @@ void MeshDelaunayVolume(std::vector<GRegion*> &regions)
   }
 
   // now do insertion of points
-  insertVerticesInRegion(gr);
+ if(CTX::instance()->mesh.algo3d == ALGO_3D_FRONTAL_DEL)
+   bowyerWatsonFrontalLayers(gr, false);
+ else if(CTX::instance()->mesh.algo3d == ALGO_3D_FRONTAL_HEX)
+   bowyerWatsonFrontalLayers(gr, true);
+ else if(CTX::instance()->mesh.algo3d == ALGO_3D_MMG3D)
+   refineMeshMMG(gr);
+ else
+   insertVerticesInRegion(gr);
 #endif
 }
 
@@ -851,7 +859,7 @@ void meshGRegion::operator() (GRegion *gr)
 
   std::list<GFace*> myface = gr->faces();
 
-  if(CTX::instance()->mesh.algo3d == ALGO_3D_DELAUNAY){
+  if(CTX::instance()->mesh.algo3d != ALGO_3D_FRONTAL){
     delaunay.push_back(gr);
   }
   else if(CTX::instance()->mesh.algo3d == ALGO_3D_FRONTAL){
diff --git a/Mesh/meshGRegionDelaunayInsertion.cpp b/Mesh/meshGRegionDelaunayInsertion.cpp
index 484c31b5e37b8bbe0299ab40051e71c20e2f7557..9eb2efa6bd2e7d1a8124d1307198e7dc5b7acf74 100644
--- a/Mesh/meshGRegionDelaunayInsertion.cpp
+++ b/Mesh/meshGRegionDelaunayInsertion.cpp
@@ -17,6 +17,25 @@
 #include "GRegion.h"
 #include "MTriangle.h"
 #include "Numeric.h"
+#include "Context.h"
+
+int MTet4::radiusNorm = 2;
+static double LIMIT_ = 1;
+
+
+static bool isActive(MTet4 *t, double limit_, int &active)
+{
+  if (t->isDeleted()) return false;
+  for (active = 0; active < 4; active++){
+    MTet4 *neigh = t->getNeigh(active);
+    if (!neigh || (neigh->getRadius() < limit_ && neigh->getRadius() > 0)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+
 
 int MTet4::inCircumSphere(const double *p) const
 {
@@ -82,6 +101,35 @@ void connectTets(ITER beg, ITER end)
   }
 }
 
+static void updateActiveFaces(MTet4 *t, double limit_, std::set<MFace,Less_Face> &front)
+{
+  if (t->isDeleted()) return;
+  for (int active = 0; active < 4; active++){
+    MTet4 *neigh = t->getNeigh(active);
+    if (!neigh || (neigh->getRadius() < limit_ && neigh->getRadius() > 0)) {
+      faceXtet fxt (t,active);
+      MFace me (fxt.v[0],fxt.v[1],fxt.v[2]);
+      front.insert(me);
+    }
+  }
+}
+
+static bool isActive(MTet4 *t, double limit_, int &i, std::set<MFace,Less_Face> *front)
+{
+  if (t->isDeleted()) return false;
+  for (i = 0; i < 4; i++){
+    MTet4 *neigh = t->getNeigh(i);
+    if (!neigh || (neigh->getRadius() < limit_ && neigh->getRadius() > 0)) {
+      faceXtet fxt (t,i);
+      MFace me (fxt.v[0],fxt.v[1],fxt.v[2]);
+      if(front->find(me) != front->end()){
+	return true;
+      }
+    }
+  }
+  return false;
+}
+
 void connectTets(std::list<MTet4*> &l) { connectTets(l.begin(), l.end()); } 
 void connectTets(std::vector<MTet4*> &l) { connectTets(l.begin(), l.end()); }
 
@@ -121,8 +169,9 @@ bool insertVertex(MVertex *v,
                   MTet4 *t,
                   MTet4Factory &myFactory,
                   std::set<MTet4*,compareTet4Ptr> &allTets,
-                  std::vector<double> & vSizes,
-                  std::vector<double> & vSizesBGM)
+		  std::vector<double> & vSizes,
+                  std::vector<double> & vSizesBGM,
+		  std::set<MTet4*,compareTet4Ptr> *activeTets = 0 )
 {
   std::list<faceXtet> shell;
   std::list<MTet4*> cavity; 
@@ -130,102 +179,83 @@ bool insertVertex(MVertex *v,
 
   recurFindCavity(shell, cavity, v, t);  
 
-  // Msg::Info("%d %d",cavity.size(),NC);
-  // if (NC != cavity.size())throw;
-
   // check that volume is conserved
   double newVolume = 0;
   double oldVolume = 0;
 
-  //  char name2[245];
-  //  FILE *ff2 = fopen (name2,"w");
-  //  fprintf(ff2,"View\"test\"{\n");
-
   std::list<MTet4*>::iterator ittet = cavity.begin();
   std::list<MTet4*>::iterator ittete = cavity.end();
   while (ittet != ittete){
     oldVolume += fabs((*ittet)->getVolume());
-//       fprintf(ff2,"SS(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g) {0,0,0,0};\n",
-//            (*ittet)->tet()->getVertex(0)->x(),
-//            (*ittet)->tet()->getVertex(0)->y(),
-//            (*ittet)->tet()->getVertex(0)->z(),
-//            (*ittet)->tet()->getVertex(1)->x(),
-//            (*ittet)->tet()->getVertex(1)->y(),
-//            (*ittet)->tet()->getVertex(1)->z(),
-//            (*ittet)->tet()->getVertex(2)->x(),
-//            (*ittet)->tet()->getVertex(2)->y(),
-//            (*ittet)->tet()->getVertex(2)->z(),
-//            (*ittet)->tet()->getVertex(3)->x(),
-//            (*ittet)->tet()->getVertex(3)->y(),
-//            (*ittet)->tet()->getVertex(3)->z());
-//       if(!(*ittet)->inCircumSphere ( v ))throw;
       ++ittet;
     }
-//   fprintf(ff2,"};\n");
-//   fclose(ff2);
-//  Msg::Info("cavity of size %d volume %g",cavity.size(),oldVolume);
-  // create new tetrahedron using faces that are
-  // on the border of the cavity
-  // add those to a list
-  // add also tets that are on the other side of the face
-  // in order to perform the connexions afterwards
-
-//   char name[245];
-//   sprintf(name,"test%d.pos",III);
-
-//   FILE *ff = fopen(name,"w");
-//   fprintf(ff,"View\"test\"{\n");
 
   MTet4** newTets = new MTet4*[shell.size()];;
   int k = 0;
 
   std::list<faceXtet>::iterator it = shell.begin();
 
+  bool onePointIsTooClose = false;
   while (it != shell.end()){
     MTetrahedron *tr = new MTetrahedron(it->v[0], it->v[1], it->v[2], v);
-    //      Msg::Info("shell %d %d %d",it->v[0]->getNum(),it->v[1]->getNum(),it->v[2]->getNum());
-//            fprintf(ff,"ST(%g,%g,%g,%g,%g,%g,%g,%g,%g) {0,0,0};\n",
-//                 it->v[0]->x(),
-//                 it->v[0]->y(),
-//                 it->v[0]->z(),
-//                 it->v[1]->x(),
-//                 it->v[1]->y(),
-//                 it->v[1]->z(),
-//                 it->v[2]->x(),
-//                 it->v[2]->y(),
-//                 it->v[2]->z());
-      
+
+    const double ONE_THIRD = 1./3.;
+    double lc = .25 * (vSizes[tr->getVertex(0)->getIndex()] +
+		       vSizes[tr->getVertex(1)->getIndex()] +
+		       vSizes[tr->getVertex(2)->getIndex()] +
+		       vSizes[tr->getVertex(3)->getIndex()]);
+    double lcBGM = .25 * (vSizesBGM[tr->getVertex(0)->getIndex()] +
+			  vSizesBGM[tr->getVertex(1)->getIndex()] +
+			  vSizesBGM[tr->getVertex(2)->getIndex()] +
+			  vSizesBGM[tr->getVertex(3)->getIndex()]);
+    double LL = std::min(lc, lcBGM);
+    
     MTet4 *t4 = myFactory.Create(tr, vSizes, vSizesBGM); 
-      t4->setOnWhat(t->onWhat());
-      newTets[k++] = t4;
-      // all new tets are pushed front in order to ba able to destroy
-      // them if the cavity is not star shaped around the new vertex.
-      // here, we better use robust perdicates that implies to orient
-      // all faces and ensure that the tets are all oriented the same.
-      new_cavity.push_back(t4);
-      MTet4 *otherSide = it->t1->getNeigh(it->i1);
-
-      if (otherSide)
-        new_cavity.push_back(otherSide);
-      //      if (!it->t1->isDeleted())throw;
-      newVolume += fabs(t4->getVolume());
-      ++it;
-    }
-//   fprintf(ff,"};\n");
-//   fclose (ff);
-//  Msg::Info("new cavity of vol %g (%d boundaries)",newVolume,shell.size());
+    t4->setOnWhat(t->onWhat());
+
+    double d1 = sqrt((it->v[0]->x() - v->x()) * (it->v[0]->x() - v->x()) +
+                     (it->v[0]->y() - v->y()) * (it->v[0]->y() - v->y()) +
+                     (it->v[0]->z() - v->z()) * (it->v[0]->z() - v->z()));
+    double d2 = sqrt((it->v[1]->x() - v->x()) * (it->v[1]->x() - v->x()) +
+                     (it->v[1]->y() - v->y()) * (it->v[1]->y() - v->y()) +
+                     (it->v[1]->z() - v->z()) * (it->v[1]->z() - v->z()));
+    double d3 = sqrt((it->v[2]->x() - v->x()) * (it->v[2]->x() - v->x()) +
+                     (it->v[2]->y() - v->y()) * (it->v[2]->y() - v->y()) +
+                     (it->v[2]->z() - v->z()) * (it->v[2]->z() - v->z()));
+
+    if (d1 < LL * .25 || d2 < LL * .25 || d3 < LL * .25) onePointIsTooClose = true;
+    newTets[k++] = t4;
+    // all new tets are pushed front in order to ba able to destroy
+    // them if the cavity is not star shaped around the new vertex.
+    // here, we better use robust perdicates that implies to orient
+    // all faces and ensure that the tets are all oriented the same.
+    new_cavity.push_back(t4);
+    MTet4 *otherSide = it->t1->getNeigh(it->i1);
+    
+    if (otherSide)
+      new_cavity.push_back(otherSide);
+    //      if (!it->t1->isDeleted())throw;
+    newVolume += fabs(t4->getVolume());
+    ++it;
+  }
   // OK, the cavity is star shaped
-  if (fabs(oldVolume - newVolume) < 1.e-10 * oldVolume){      
+  if (fabs(oldVolume - newVolume) < 1.e-10 * oldVolume &&
+      !onePointIsTooClose){      
     connectTets(new_cavity.begin(), new_cavity.end());      
     allTets.insert(newTets, newTets + shell.size());
-    
-//     ittet = cavity.begin();
-//     ittete = cavity.end();
-//     while ( ittet != ittete ){
-//       myFactory.Free (*ittet);
-//       ++ittet;
-//     }
+
+    if (activeTets){
+      for (std::list<MTet4*>::iterator i = new_cavity.begin(); i != new_cavity.end(); ++i){
+        int active_face;
+        if(isActive(*i, LIMIT_, active_face) && (*i)->getRadius() > LIMIT_){
+          if ((*activeTets).find(*i) == (*activeTets).end())
+            (*activeTets).insert(*i);
+        }
+      }
+    }
+
     delete [] newTets;
+
     return true;
   }
   else { // The cavity is NOT star shaped
@@ -840,6 +870,21 @@ void insertVerticesInRegion (GRegion *gr)
       Msg::Info("cleaning up the memory %d -> %d", n1, allTets.size());
     }
   }
+
+    // relocate vertices
+  int nbReloc = 0;
+  for (int SM=0;SM<CTX::instance()->mesh.nbSmoothing;SM++){
+    for(MTet4Factory::iterator it = allTets.begin(); it != allTets.end(); ++it){
+      if (!(*it)->isDeleted()){
+	double qq = (*it)->getQuality();
+	if (qq < .4)
+	  for (int i = 0; i < 4; i++){
+	    if (smoothVertex(*it, i, QMTET_2)) nbReloc++;
+	  }
+      }
+    }
+  }
+
   
   while(1){
     if(allTets.begin() == allTets.end()) break;
@@ -851,6 +896,230 @@ void insertVerticesInRegion (GRegion *gr)
     myFactory.Free(worst);
     allTets.erase(allTets.begin());      
   }
+}
+
+MVertex * optimalPointFrontal (GRegion *gr, 
+			       MTet4 *worst,
+			       int active_face,
+			       std::vector<double> &vSizes,
+			       std::vector<double> &vSizesBGM){
+  double centerTet[3], centerFace[3];
+  MTetrahedron *base = worst->tet();
+  faceXtet fxt ( worst, active_face );
+  double pa[3] = {fxt.v[0]->x(),fxt.v[0]->y(),fxt.v[0]->z()};
+  double pb[3] = {fxt.v[1]->x(),fxt.v[1]->y(),fxt.v[1]->z()};
+  double pc[3] = {fxt.v[2]->x(),fxt.v[2]->y(),fxt.v[2]->z()};
+  circumCenterXYZ(pa, pb, pc, centerFace);
+  worst->circumcenter(centerTet);
+  
+  SVector3 dir (centerTet[0] - centerFace[0],
+		centerTet[1] - centerFace[1],
+		centerTet[2] - centerFace[2]);
+
+  const double q = dir.norm();
+  dir.normalize();
+
+  SVector3 rDir (pa[0] - centerFace[0],
+		 pa[1] - centerFace[1],
+		 pa[2] - centerFace[2]);
+  
+  const double p = 0.5 * rDir.norm();
+
+  const double rhoM1 = 0.33333 * (vSizes[fxt.v[0]->getIndex()] + 
+				  vSizes[fxt.v[1]->getIndex()] + 
+				  vSizes[fxt.v[2]->getIndex()] );
+  const double rhoM2 = 0.33333 * (vSizesBGM[fxt.v[0]->getIndex()] + 
+				  vSizesBGM[fxt.v[1]->getIndex()] + 
+				  vSizesBGM[fxt.v[2]->getIndex()] );
 
+  const double rhoM  = std::min(rhoM1, rhoM2);
+  
+  const double HEIGHT = 1/sqrt(3.);
+
+  const double rhoM_hat = std::min(std::max(rhoM, p), (p * p + q * q) / (2 * q));
+  const double d = (rhoM_hat + sqrt (rhoM_hat * rhoM_hat - p * p)) * HEIGHT;
+
+  //  const double a = 2*p *3 /sqrt(3);
+  const double a = .025;
+  const double tt = a*sqrt(6.)/3;
 
+  MVertex *vert = new MVertex(centerFace[0] + tt * dir[0],
+			      centerFace[1] + tt * dir[1],
+			      centerFace[2] + tt * dir[2],
+			      gr);
+  return vert;
 }
+
+
+void bowyerWatsonFrontalLayers(GRegion *gr, bool hex)
+{
+
+  std::vector<double> vSizes;
+  std::vector<double> vSizesBGM;
+  MTet4Factory myFactory(1600000);
+  std::set<MTet4*, compareTet4Ptr> &allTets = myFactory.getAllTets();
+  std::set<MTet4*, compareTet4Ptr> activeTets;
+  int NUM = 0;
+
+  if (!backgroundMesh::current()) {
+    // TODO !!!
+  }
+
+  if (hex){
+    LIMIT_ = sqrt(2)*.99;
+    MTet4::radiusNorm =-1;
+  }
+
+  { // leave this in a block so the map gets deallocated directly
+    std::map<MVertex*, double> vSizesMap;
+    for(unsigned int i = 0; i < gr->tetrahedra.size(); i++)
+      setLcs(gr->tetrahedra[i], vSizesMap);
+    for(std::map<MVertex*, double>::iterator it = vSizesMap.begin(); 
+        it != vSizesMap.end(); ++it){
+      it->first->setIndex(NUM++);
+      vSizes.push_back(it->second);
+      vSizesBGM.push_back(it->second);
+    }
+  }
+  
+  for(unsigned int i = 0; i < gr->tetrahedra.size(); i++)
+    allTets.insert(myFactory.Create(gr->tetrahedra[i], vSizes,vSizesBGM));
+
+  gr->tetrahedra.clear();
+  connectTets(allTets.begin(), allTets.end());
+
+  fs_cont search;
+  buildFaceSearchStructure(gr->model(), search);
+  
+  for(MTet4Factory::iterator it = allTets.begin(); it != allTets.end(); ++it){
+    if(!(*it)->onWhat()){
+      std::list<MTet4*> theRegion;
+      std::set<GFace *> faces_bound;
+      GRegion *bidon = (GRegion*)123;
+      double _t1 = Cpu();
+      Msg::Debug("start with a non classified tet");      
+      recur_classify(*it, theRegion, faces_bound, bidon, gr->model(), search);
+      double _t2 = Cpu();
+      Msg::Debug("found %d tets with %d faces (%g sec for the classification)",
+                 theRegion.size(), faces_bound.size(), _t2 - _t1);
+      GRegion *myGRegion = getRegionFromBoundingFaces(gr->model(), faces_bound);
+      // Msg::Info("a region is found %p",myGRegion);
+      if(myGRegion) // a geometrical region associated to the list of faces has been found
+        for(std::list<MTet4*>::iterator it2 = theRegion.begin(); 
+            it2 != theRegion.end(); ++it2) (*it2)->setOnWhat(myGRegion);
+      else // the tets are in the void 
+        for(std::list<MTet4*>::iterator it2 = theRegion.begin();
+            it2 != theRegion.end(); ++it2)(*it2)->setDeleted(true);
+    }
+  }
+  search.clear();
+
+  for(MTet4Factory::iterator it = allTets.begin(); it!=allTets.end(); ++it){
+    (*it)->setNeigh(0, 0);
+    (*it)->setNeigh(1, 0);
+    (*it)->setNeigh(2, 0);
+    (*it)->setNeigh(3, 0);
+  }
+  connectTets(allTets.begin(), allTets.end());
+
+  int ITER = 0, active_face;
+
+  std::set<MFace,Less_Face> _front;
+  for(MTet4Factory::iterator it = allTets.begin(); it!=allTets.end(); ++it){
+    if(isActive(*it,LIMIT_,active_face) && (*it)->getRadius() > LIMIT_){
+      activeTets.insert(*it);
+      updateActiveFaces(*it, LIMIT_, _front);
+    }
+    else if ((*it)->getRadius() < LIMIT_)break;
+  }
+
+  // insert points
+  int ITERATION = 1;
+  while (1){
+    if (ITERATION == 8)break;
+    ITERATION ++;
+
+    std::set<MTet4*, compareTet4Ptr> activeTetsNotInFront;
+
+    while (1){
+      
+      if (!activeTets.size())break;
+
+      //      printf("%d active tets %d tets\n",activeTets.size(),allTets.size());
+
+      std::set<MTet4*,compareTet4Ptr>::iterator WORST_ITER = activeTets.begin();      
+      MTet4 *worst = (*WORST_ITER);
+      if(worst->isDeleted()){
+	activeTets.erase(WORST_ITER);
+	//	myFactory.Free(worst);
+      }
+      else {
+	activeTets.erase(WORST_ITER);
+	if (isActive(worst, LIMIT_, active_face,&_front)  && 
+	    worst->getRadius() > LIMIT_){
+	  //	  printf("worst = %12.5E\n",worst->getRadius());
+	
+	  if(ITER++ % 5000 == 0)
+	    Msg::Info("%d points created -- Worst tet radius is %g",
+		      vSizes.size(), worst->getRadius());
+	
+	  MVertex *v = optimalPointFrontal (gr,worst,active_face,vSizes,vSizesBGM);
+	  v->setIndex(NUM++);
+	  vSizes.push_back(.025);
+	  vSizesBGM.push_back(.025);
+
+	  if(!worst->inCircumSphere(v) ||
+	     !insertVertex(v, worst, myFactory, allTets, vSizes,vSizesBGM,&activeTets)){	    
+	    myFactory.changeTetRadius(allTets.begin(), 0.);
+	    if(v) delete v;
+	  }
+	  else{
+	    //	    printf("yeah ! one new vertex \n");
+	    v->onWhat()->mesh_vertices.push_back(v);	  
+	    //	    if (ITER == 100)break;
+	  }
+	}
+	else if (worst->getRadius() > LIMIT_){
+	  activeTetsNotInFront.insert(worst);
+	}
+      }
+    }
+    _front.clear();
+    MTet4Factory::iterator it = activeTetsNotInFront.begin();
+    for ( ; it!=activeTetsNotInFront.end();++it){
+      if((*it)->getRadius() > LIMIT_ && isActive(*it,LIMIT_,active_face)){
+	activeTets.insert(*it);
+	updateActiveFaces(*it, LIMIT_, _front);
+      }
+    }
+    if (!activeTets.size())break;
+  }
+
+
+  int nbReloc = 0;
+  for (int SM=0;SM<CTX::instance()->mesh.nbSmoothing;SM++){
+    for(MTet4Factory::iterator it = allTets.begin(); it != allTets.end(); ++it){
+      if (!(*it)->isDeleted()){
+	double qq = (*it)->getQuality();
+	if (qq < .4)
+	  for (int i = 0; i < 4; i++){
+	    if (smoothVertex(*it, i, QMTET_2)) nbReloc++;
+	  }
+      }
+    }
+  }
+
+
+  while(1){
+    if(allTets.begin() == allTets.end()) break;
+    MTet4 *worst = *allTets.begin();
+    if(!worst->isDeleted()){
+      worst->onWhat()->tetrahedra.push_back(worst->tet());
+      worst->tet() = 0;
+    }
+    myFactory.Free(worst);
+    allTets.erase(allTets.begin());      
+  }
+  MTet4::radiusNorm = 2;
+  LIMIT_ = 1;
+} 
diff --git a/Mesh/meshGRegionDelaunayInsertion.h b/Mesh/meshGRegionDelaunayInsertion.h
index 2e20470e75ccf485717993b1729ebc50278278e2..cdd9b581a303ca77e6ff31658352e7fd9890daf5 100644
--- a/Mesh/meshGRegionDelaunayInsertion.h
+++ b/Mesh/meshGRegionDelaunayInsertion.h
@@ -55,6 +55,7 @@ class MTet4
   MTet4 *neigh[4];
   GRegion *gr;
  public :
+  static int radiusNorm; // 2 is euclidian norm, -1 is infinite norm  
   ~MTet4(){}
   MTet4() 
     : deleted(false), circum_radius(0.0), base(0), gr(0)
@@ -170,6 +171,7 @@ class MTet4
 void connectTets(std::list<MTet4*> &);
 void connectTets(std::vector<MTet4*> &);
 void insertVerticesInRegion(GRegion *gr);
+void bowyerWatsonFrontalLayers(GRegion *gr, bool hex);
 
 class compareTet4Ptr
 {
diff --git a/Mesh/meshGRegionMMG3D.cpp b/Mesh/meshGRegionMMG3D.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4b8ae84bcda5417f2e12145dac5b67d7470d6fa3
--- /dev/null
+++ b/Mesh/meshGRegionMMG3D.cpp
@@ -0,0 +1,153 @@
+#include "GmshConfig.h"
+#include "meshGRegionMMG3D.h"
+#ifdef HAVE_MMG3D
+#include <set>
+#include "GRegion.h"
+#include "GFace.h"
+#include "MTetrahedron.h"
+#include "MTriangle.h"
+#include "MVertex.h"
+#include "BackgroundMesh.h"
+
+extern "C" {
+#include <libmmg3d.h>
+#define M_UNUSED    (1 << 0)
+}
+
+void MMG2gmsh (GRegion *gr, MMG_pMesh mmg, std::map<int,MVertex*> &mmg2gmsh){
+  printf("%d vertices in MMG\n",mmg->np);
+  for (int k=1;k<= mmg->np ; k++){
+    MMG_pPoint ppt = &mmg->point[k]; 
+    if (ppt->tag & M_UNUSED) continue;
+    if (mmg2gmsh.find(k) == mmg2gmsh.end()){
+      MVertex *v = new MVertex(ppt->c[0],ppt->c[1],ppt->c[2],gr);
+      mmg2gmsh[k] = v;
+      gr->mesh_vertices.push_back(v);
+    }
+  }  
+
+  
+  for (int k=1; k<=mmg->ne; k++) { 
+    MMG_pTetra ptetra = &mmg->tetra[k]; 
+    if ( ptetra->v[0] ){
+      MVertex *v1 = mmg2gmsh[ptetra->v[0]];
+      MVertex *v2 = mmg2gmsh[ptetra->v[1]];
+      MVertex *v3 = mmg2gmsh[ptetra->v[2]];
+      MVertex *v4 = mmg2gmsh[ptetra->v[3]];
+      if (!v1 || !v2 || !v3 || !v4){
+	Msg::Error("Element %d Unknown Vertex in MMG2gmsh %d(%p) %d(%p) %d(%p) %d(%p)",k,ptetra->v[0],v1,ptetra->v[1],v2,ptetra->v[2],v3,ptetra->v[3],v4);
+      }
+      else gr->tetrahedra.push_back(new MTetrahedron(v1,v2,v3,v4));
+    }
+  }
+}
+
+void gmsh2MMG (GRegion *gr, MMG_pMesh mmg, MMG_pSol sol, std::map<int,MVertex*> &mmg2gmsh){
+  mmg->ne = gr->tetrahedra.size();
+  std::set<MVertex*> allVertices;
+  for (int i=0;i< gr->tetrahedra.size() ; i++){
+    allVertices.insert(gr->tetrahedra[i]->getVertex(0));
+    allVertices.insert(gr->tetrahedra[i]->getVertex(1));
+    allVertices.insert(gr->tetrahedra[i]->getVertex(2));
+    allVertices.insert(gr->tetrahedra[i]->getVertex(3));
+  }
+  mmg->np = sol->np = allVertices.size();
+  
+  std::list<GFace*> f = gr->faces();
+
+  mmg->nt = 0;
+  for (std::list<GFace*>::iterator it = f.begin(); it != f.end() ; ++it){
+    mmg->nt += (*it)->triangles.size();
+  }
+  
+  mmg->npmax = sol->npmax = 1000000;
+  mmg->ntmax = 700000;
+  mmg->nemax = 7000000;
+
+  mmg->point = (MMG_pPoint)calloc(mmg->npmax+1,sizeof(MMG_Point));
+  mmg->tetra = (MMG_pTetra)calloc(mmg->nemax+1,sizeof(MMG_Tetra));
+  mmg->tria  = (MMG_pTria) calloc(mmg->ntmax+1,sizeof(MMG_Tria));
+  mmg->disp  = (MMG_pDispl)calloc(mmg->npmax+1,sizeof(MMG_Displ));
+  mmg->adja = (int*)calloc(4*mmg->nemax+5,sizeof(int));
+
+  sol->offset = 1;
+  sol->met = (double*)calloc(sol->npmax+1,sol->offset*sizeof(double)); 
+  
+  int k=1;
+  std::map<int,int> gmsh2mmg_num;
+  for (std::set<MVertex*>::iterator it = allVertices.begin() ; it != allVertices.end() ; ++it){
+    MMG_pPoint ppt = &mmg->point[k]; 
+
+    mmg2gmsh[k] = *it;
+
+    ppt->c[0] = (*it)->x();
+    ppt->c[1] = (*it)->y();
+    ppt->c[2] = (*it)->z();
+    ppt->ref  = gr->tag();
+    gmsh2mmg_num[(*it)->getNum()] = k;
+
+    MVertex *v = *it;
+    double U=0,V=0;
+    if (v->onWhat()->dim() == 1){
+      v->getParameter(0,U);
+    }
+    else if (v->onWhat()->dim() == 2){
+      v->getParameter(0,U);
+      v->getParameter(1,V);
+    }
+    double lc = BGM_MeshSize(v->onWhat(), U,V,v->x(), v->y(), v->z());  
+    int isol = (k-1) * sol->offset + 1; 
+    for (int i=0; i<sol->offset; i++)  {
+      sol->met[isol + i] = lc;
+      //      printf("sol[%d] = %12.5E\n",isol + i,lc);
+    }
+    k++;
+  }
+  
+  for (k=1; k<=mmg->ne; k++) { 
+    MMG_pTetra ptetra = &mmg->tetra[k]; 
+    ptetra->v[0] = gmsh2mmg_num[gr->tetrahedra[k-1]->getVertex(0)->getNum()];
+    ptetra->v[1] = gmsh2mmg_num[gr->tetrahedra[k-1]->getVertex(1)->getNum()];
+    ptetra->v[2] = gmsh2mmg_num[gr->tetrahedra[k-1]->getVertex(2)->getNum()];
+    ptetra->v[3] = gmsh2mmg_num[gr->tetrahedra[k-1]->getVertex(3)->getNum()];
+    ptetra->ref  = gr->tag();
+  }
+
+  k = 1;
+  for (std::list<GFace*>::iterator it = f.begin(); it != f.end() ; ++it){
+    for (int i=0;i<(*it)->triangles.size();i++){
+      MMG_pTria ptriangle = &mmg->tria[k]; 
+      ptriangle->v[0] = gmsh2mmg_num[(*it)->triangles[i]->getVertex(0)->getNum()];
+      ptriangle->v[1] = gmsh2mmg_num[(*it)->triangles[i]->getVertex(1)->getNum()];
+      ptriangle->v[2] = gmsh2mmg_num[(*it)->triangles[i]->getVertex(2)->getNum()];
+      ptriangle->ref  = (*it)->tag();
+      k++;
+    }
+  } 
+  mmg->disp = 0;
+  
+}
+
+void refineMeshMMG(GRegion *gr){
+  MMG_pMesh mmg = (MMG_pMesh)calloc(1,sizeof(MMG_Mesh)); 
+  MMG_pSol  sol = (MMG_pSol)calloc(1,sizeof(MMG_Sol)); 
+  std::map<int,MVertex*> mmg2gmsh;
+  gmsh2MMG (gr, mmg, sol,mmg2gmsh);
+  int opt[9] = {1,0,64,0,0,(Msg::GetVerbosity() > 20) ? 3 : -1,0,0,0};
+  mmg3d::MMG_mmg3dlib(opt,mmg,sol); 
+
+  for (int i=0;i<gr->tetrahedra.size();++i)delete gr->tetrahedra[i];
+  gr->tetrahedra.clear();
+  for (int i=0;i<gr->mesh_vertices.size();++i)delete gr->mesh_vertices[i];
+  gr->mesh_vertices.clear();
+
+
+  MMG2gmsh (gr, mmg, mmg2gmsh);  
+  MMG_saveMesh(mmg ,"test.mesh");
+}
+
+#else
+void refineMeshMMG(GRegion *gr){
+  Msg::Error("You should compile your version of Gmsh with MMG3D, the Mobile Mesh Generator");
+}
+#endif
diff --git a/Mesh/meshGRegionMMG3D.h b/Mesh/meshGRegionMMG3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..59c50d6c20c0e627a0bc736b7ae3846024629fd7
--- /dev/null
+++ b/Mesh/meshGRegionMMG3D.h
@@ -0,0 +1,5 @@
+#ifndef _MESHGREGIONMMG3D_H_
+#define _MESHGREGIONMMG3D_H_
+class GRegion;
+void refineMeshMMG(GRegion *gr);
+#endif
diff --git a/benchmarks/3d/coin.geo b/benchmarks/3d/coin.geo
index cc49a2b262181c7fda152c2d29f98b7aad684a01..ba4c91c060fe64d95d21f90590ca0181ab0d2b9e 100644
--- a/benchmarks/3d/coin.geo
+++ b/benchmarks/3d/coin.geo
@@ -14,8 +14,9 @@
 0.085 261542 1568048 1285.29
 */
 lcar1 = .2;
+lcar2 = .2;
 
-Point(newp) = {0.5,0.5,0.5,lcar1}; /* Point      1 */
+Point(newp) = {0.5,0.5,0.5,lcar2}; /* Point      1 */
 Point(newp) = {0.5,0.5,0,lcar1}; /* Point      2 */
 Point(newp) = {0,0.5,0.5,lcar1}; /* Point      3 */
 Point(newp) = {0,0,0.5,lcar1}; /* Point      4 */
diff --git a/benchmarks/3d/thai.geo b/benchmarks/3d/thai.geo
index dff1f8df15c248a6c988b9200bda902a294a62f8..1e90077968a07cb3c9e85958998be673335d01e6 100644
--- a/benchmarks/3d/thai.geo
+++ b/benchmarks/3d/thai.geo
@@ -1,3 +1,5 @@
+Mesh.RecombineAll=1;
+Mesh.RecombinationAlgorithm=1;
 Point(1) = {3.42295068244, 47, -7.5, 1e+022};
 Point(2) = {3.42295068244, 58, -7.5, 1e+022};
 Point(3) = {-3.5, 47, -7.5, 1e+022};
@@ -2428,3 +2430,4 @@ Line Loop(2032) = {2021, -184, -266, 268, 2019, 2020};
 Plane Surface(2033) = {2032};
 Surface Loop(2035) = {309, 282, 288, 349, 297, 295, 290, 2014, 2012, 325, 377, 2023, 2025, 429, 425, 435, 437, 439, 427, 441, 443, 445, 449, 453, 451, 447, 457, 455, 460, 462, 464, 466, 468, 470, 472, 474, 476, 478, 480, 482, 484, 395, 418, 405, 420, 422, 375, 391, 393, 389, 397, 399, 2033, 2027, 379, 304, 280, 284, 2016, 2018, 299, 321, 347, 2029, 2031, 385, 383, 286, 293, 311, 313, 2010, 337, 339, 335, 341, 371, 365, 367, 369, 363, 373, 381, 416, 408, 414, 410, 412, 2008, 431, 433, 333, 327, 331, 329, 353, 361, 355, 357, 359, 351, 317, 315};
 Volume(2036) = {2035};
+Recombine Surface {405, 375, 418, 420, 422, 2023, 425, 325, 377, 297, 445, 443, 455, 449, 295, 2012, 460, 474, 453, 480, 439, 435, 470, 468, 429, 2008, 482, 357, 355, 331, 353, 464, 351, 333, 349, 282, 290, 288, 447, 441, 412, 462, 427, 408, 457, 410, 431, 451, 433, 437, 309, 315, 317, 327, 329, 359, 361, 2014, 2025, 484, 466, 472, 476, 478, 381, 304, 379, 2027, 286, 284, 280, 2016, 293, 311, 313, 347, 373, 2010, 371, 369, 367, 335, 337, 299, 2029, 2018, 341, 339, 321, 365, 363, 395, 399, 397, 2033, 383, 389, 391, 393, 414, 416, 385, 2031};
diff --git a/benchmarks/step/capot.geo b/benchmarks/step/capot.geo
index d2ba4152d72f4340b39c3ae541c3b9a44c4722a6..c49a17d9d40362669f239f0dfea4ae84c2eb8ac6 100644
--- a/benchmarks/step/capot.geo
+++ b/benchmarks/step/capot.geo
@@ -1,7 +1,13 @@
 Mesh.RemeshParametrization=1; //(0) harmonic (1) conformal 
 Mesh.RemeshAlgorithm=0; //(0) nosplit (1) automatic (2) split metis
 
-Mesh.CharacteristicLengthFactor=0.2;
+Mesh.Algorithm = 8; //(1=MeshAdapt, 2=Automatic, 5=Delaunay, 6=Frontal, 7=bamg)
+Mesh.RecombinationAlgorithm = 1;
+
+
+
+
+//Mesh.CharacteristicLengthFactor=0.2;
 Merge "capot.brep";
 
 Compound Line(1000) = {47,50};
@@ -10,3 +16,4 @@ Compound Line(1001) = {44,46};
 Compound Surface(100) = {1, 8, 15, 17, 16, 18, 9, 2, 3, 10, 7, 14, 11, 4, 12, 5, 6, 13} ;
 
 Physical Surface(100)={100};
+Recombine Surface {100};
diff --git a/benchmarks/stl/mobilette.geo b/benchmarks/stl/mobilette.geo
index 43a248c0cda24dd1e5a6d81d2756117209812b35..96dd603053e510c04d776e7ee0b70892bb826cdc 100644
--- a/benchmarks/stl/mobilette.geo
+++ b/benchmarks/stl/mobilette.geo
@@ -1,4 +1,4 @@
-Mesh.Algorithm = 6; //(1=MeshAdapt, 2=Automatic, 5=Delaunay, 6=Frontal, 7=bamg) 
+Mesh.Algorithm = 8; //(1=MeshAdapt, 2=Automatic, 5=Delaunay, 6=Frontal, 7=bamg) 
 Mesh.CharacteristicLengthMin=1.5/2;
 Mesh.CharacteristicLengthMax=2.5/2;
 Mesh.RemeshAlgorithm=1;
@@ -26,5 +26,8 @@ EndFor
 Surface Loop(1) = {s : s + #ss[]-1};
 Volume(1) = {1};
 
+Mesh.RecombineAll=1;
+Mesh.RecombinationAlgorithm=1;
+
 Physical Surface(1) = {s : s + #ss[]-1};
 Physical Volume(1) = 1;
diff --git a/contrib/mmg3d/CMakeLists.txt b/contrib/mmg3d/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..07000169786cf12c1dffbd916bd0c811f5861863
--- /dev/null
+++ b/contrib/mmg3d/CMakeLists.txt
@@ -0,0 +1,69 @@
+# Gmsh - Copyright (C) 1997-2011 C. Geuzaine, J.-F. Remacle
+#
+# See the LICENSE.txt file for license information. Please report all
+# bugs and problems to <gmsh@geuz.org>.
+
+set(SRC
+./build/sources/mmg3d.c
+./build/sources/inout.c
+./build/sources/mmg3dlib.c
+./build/sources/scalem.c
+./build/sources/outqua.c
+./build/sources/baryct.c
+./build/sources/zaldy.c
+./build/sources/typelt.c
+./build/sources/swaptet.c
+./build/sources/swapar.c
+./build/sources/swap710.c
+./build/sources/swap68.c
+./build/sources/swap56.c
+./build/sources/swap44.c
+./build/sources/swap23.c
+./build/sources/spledg.c
+./build/sources/solmap.c
+./build/sources/simu710.c
+./build/sources/simu68.c
+./build/sources/simu56.c
+./build/sources/simu44.c
+./build/sources/simu23.c
+./build/sources/ratio.c
+./build/sources/queue.c
+./build/sources/quality.c
+./build/sources/pattern.c
+./build/sources/opttyp.c
+./build/sources/opttet.c
+./build/sources/optra4.c
+./build/sources/optlentet.c
+./build/sources/optlen.c
+./build/sources/optlap.c
+./build/sources/optcte.c
+./build/sources/optcoq.c
+./build/sources/optbdry.c
+./build/sources/movevertex.c
+./build/sources/mmg3d9.c
+./build/sources/delaunay.c
+./build/sources/hash.c
+./build/sources/length.c
+./build/sources/mmg3d4.c
+./build/sources/mmg3d1.c
+./build/sources/memory.c
+./build/sources/matrix.c
+./build/sources/locate.c
+./build/sources/librnbg.c
+./build/sources/heap.c
+./build/sources/eigenv.c
+./build/sources/cutelt.c
+./build/sources/coquil.c
+./build/sources/colpoi.c
+./build/sources/chrono.c
+./build/sources/chkmsh.c
+./build/sources/cenrad.c
+./build/sources/cendel.c
+./build/sources/bucket.c
+./build/sources/boulep.c
+./build/sources/analarcutting.c
+./build/sources/analar.c
+)
+
+file(GLOB_RECURSE HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h)
+append_gmsh_src(contrib/mmg3d "${SRC};${HDR}")
diff --git a/contrib/mmg3d/INSTALL.txt b/contrib/mmg3d/INSTALL.txt
new file mode 100644
index 0000000000000000000000000000000000000000..14d9f7844f8caf7b3646b011f9b47c9edbaea7a6
--- /dev/null
+++ b/contrib/mmg3d/INSTALL.txt
@@ -0,0 +1,40 @@
+MMG3D 4.0 installation instructions
+====================================
+
+The simplest way to compile is to use cmake  : 
+
+1) The cmake tool is available at this adress :
+
+http://www.cmake.org/
+
+2) 'cd' to the directory build/ containing :
+CMakeLists.txt 
+a directory named sources/ containing all the MMG3D files.
+
+3) Configure and create the makefile with cmake :  
+
+By default, the configuration is done to create an executable
+of MMG3D. 
+
+NB : By default, cmake find Scotch software : 
+http://www.labri.fr/perso/pelegrin/scotch/scotch_en.html
+
+i) If you use the gui interface of cmake : 'cmake-gui' 
+You can specify if you would compile the shared or static library  
+and if you have or not Scotch software.
+
+OR
+
+ii) 'cmake . ' 
+You can specify the following option :
+-DCOMPIL_STATIC_LIBRARY="ON"  or -DCOMPIL_SHARED_LIBRARY="ON"   
+(by default : OFF)
+-DUSE_SCOTCH="OFF" ' (by default : ON)
+
+
+
+4) Compile MMG3D :
+'make'
+
+
+
diff --git a/contrib/mmg3d/LICENCE.txt b/contrib/mmg3d/LICENCE.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e587591e143165eb560c2385f0652ac369fc6595
--- /dev/null
+++ b/contrib/mmg3d/LICENCE.txt
@@ -0,0 +1,621 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
\ No newline at end of file
diff --git a/contrib/mmg3d/README.txt b/contrib/mmg3d/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c296704020fbd14f7ffcac34bae3bf1d6ad50c27
--- /dev/null
+++ b/contrib/mmg3d/README.txt
@@ -0,0 +1,8 @@
+The terms under which this copy of the MMG3d 4.0 distribution
+is provided to you are described in file "LICENSE.txt", located
+in the same directory as this file.
+
+If you accept them, please refer to file "INSTALL.txt", also
+located in this directory, for the installation instructions.
+
+
diff --git a/contrib/mmg3d/build/CMakeLists.txt b/contrib/mmg3d/build/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1db395f1670b3a2093234817e386addf64e1117d
--- /dev/null
+++ b/contrib/mmg3d/build/CMakeLists.txt
@@ -0,0 +1,98 @@
+cmake_minimum_required (VERSION 2.6)
+project (MMG3D)     
+
+IF(APPLE) 
+   add_definitions(-static-libgcc -mmacosx-version-min=10.4 -arch ppc -arch i386)  
+
+   # determine if the processor supports 64bit execution
+   EXECUTE_PROCESS(
+      COMMAND sysctl hw.cpu64bit_capable
+      ERROR_QUIET
+      OUTPUT_VARIABLE 64_CMD
+      OUTPUT_STRIP_TRAILING_WHITESPACE
+   )
+   STRING(REGEX REPLACE "^hw.cpu64bit_capable: (.*)" "\\1" 64_BIT "${64_CMD}")
+   #otherwise pbs with linkage SCOTCH
+   SET(CMAKE_OSX_ARCHITECTURES ppc)   
+   
+   # display the results
+   MESSAGE(STATUS "CMAKE_OSX_ARCHITECTURES: " ${CMAKE_OSX_ARCHITECTURES})
+ENDIF(APPLE)  
+
+
+
+# should we use SCOTCH
+option (USE_SCOTCH 
+        "Use SCOTCH TOOL for renumbering" ON) 
+
+# configure a header file to pass some of the CMake settings
+# to the source code
+configure_file (
+  "sources/mmg3dConfig.h.in"
+  "sources/mmg3dConfig.h"
+  )
+
+# add SCOTCH library?
+#
+if (USE_SCOTCH)  
+  #Inclusion de SCOTCH
+  find_library(LIBS_SCOTCH scotch)
+  find_library(LIBS_SCOTCHERR scotcherr)
+  find_path(INCLUDE_SCOTCH scotch.h)
+  # IF(LIBS_SCOTCH_FOUND)
+  # 	MESSAGE(STATUS "Looking for SCOTCH - found")
+  # ELSE(SCOTCH_FOUND)
+  # 	MESSAGE(STATUS "Looking for SCOTCH - not found")
+  # ENDIF(SCOTCH_FOUND)   
+  include_directories(${INCLUDE_SCOTCH}) 
+endif (USE_SCOTCH)   
+
+#file sources
+file(
+	GLOB_RECURSE
+	source_files
+	sources/*
+)
+
+add_executable(mmg3d4.0 ${source_files})                                    
+
+option (COMPIL_STATIC_LIBRARY 
+        "Use tutorial provided math implementation" OFF) 
+if (COMPIL_STATIC_LIBRARY)  
+  add_library(mmg3dlib4.0 STATIC ${source_files})
+  target_link_libraries(mmg3dlib4.0 ${M_LIB} ${LIBS_SCOTCH} ${LIBS_SCOTCHERR})
+endif (COMPIL_STATIC_LIBRARY)   
+option (COMPIL_SHARED_LIBRARY 
+        "Use tutorial provided math implementation" OFF) 
+if (COMPIL_SHARED_LIBRARY)  
+  add_library(mmg3dlib4.0 SHARED ${source_files})
+  target_link_libraries(mmg3dlib4.0 ${M_LIB} ${LIBS_SCOTCH} ${LIBS_SCOTCHERR})
+endif (COMPIL_SHARED_LIBRARY)   
+
+find_library(M_LIB m)
+target_link_libraries(mmg3d4.0 ${M_LIB} ${LIBS_SCOTCH} ${LIBS_SCOTCHERR})    
+
+#add testlib   
+if (COMPIL_STATIC_LIBRARY) 
+  #file sources
+  file(
+  	GLOB_RECURSE
+  	source_testlib
+  	libexamples/*
+  )
+  add_executable(testlib ${source_testlib}) 
+  include_directories(sources/)                                    
+  target_link_libraries(testlib mmg3dlib4.0)    
+endif (COMPIL_STATIC_LIBRARY)   
+
+if (COMPIL_SHARED_LIBRARY) 
+  #file sources
+  file(
+  	GLOB_RECURSE
+  	source_testlib
+  	libexamples/*
+  )
+  add_executable(testlib ${source_testlib}) 
+  include_directories(sources/)                                    
+  target_link_libraries(testlib mmg3dlib4.0)    
+endif (COMPIL_SHARED_LIBRARY)
diff --git a/contrib/mmg3d/build/libexamples/main.c b/contrib/mmg3d/build/libexamples/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..f9e29257ec23d58a868ec2ad0fce6591b75618a1
--- /dev/null
+++ b/contrib/mmg3d/build/libexamples/main.c
@@ -0,0 +1,129 @@
+/*Authors Cécile Dobrzynski
+
+Example for using mmg3dlib
+
+*/
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#include <float.h>
+
+#include "libmmg3d.h"
+int main(int argc,char *argv[]) {
+  MMG_pMesh  mmgMesh;
+  MMG_pSol   mmgSol;
+	int        opt[9],k;
+  
+  fprintf(stdout,"  -- TEST MMG3DLIB \n");
+
+  mmgMesh = (MMG_pMesh)calloc(1,sizeof(MMG_Mesh));
+  assert(mmgMesh);
+
+  /* allocation */
+  mmgMesh->np     = 12;
+  mmgMesh->nt     = 0;
+  mmgMesh->ne     = 12;
+
+
+  mmgMesh->npmax  = 500000;
+  mmgMesh->ntmax  = 1000000;
+  mmgMesh->nemax  = 3000000;
+
+  mmgMesh->point = (MMG_pPoint)calloc(mmgMesh->npmax+1,sizeof(MMG_Point));
+  assert(mmgMesh->point);
+  mmgMesh->tetra = (MMG_pTetra)calloc(mmgMesh->nemax+1,sizeof(MMG_Tetra));
+  assert(mmgMesh->tetra);
+  mmgMesh->tria  = (MMG_pTria)calloc(mmgMesh->ntmax+1,sizeof(MMG_Tria));
+  assert(mmgMesh->tria);
+  mmgMesh->adja = (int*)calloc(4*mmgMesh->nemax+5,sizeof(int));
+  assert(mmgMesh->adja);
+  mmgMesh->disp = (MMG_pDispl)calloc(1,sizeof(MMG_Displ));
+  assert(mmgMesh->disp);
+  mmgMesh->disp->mv = (double*)calloc(3*(mmgMesh->npmax + 1),sizeof(double));
+  assert(mmgMesh->disp->mv);
+  mmgMesh->disp->alpha = (short*)calloc(mmgMesh->npmax+1,sizeof(short));
+  assert(mmgMesh->disp->alpha);
+ 
+  /*coordinates vertices*/ 
+	mmgMesh->point[1].c[0]  = 0.;  mmgMesh->point[1].c[1]  = 0.; mmgMesh->point[1].c[2]  = 0.; mmgMesh->point[1].ref  = 0; 
+	mmgMesh->point[2].c[0]  = 0.5; mmgMesh->point[2].c[1]  = 0;  mmgMesh->point[2].c[2]  = 0;  mmgMesh->point[2].ref  = 0; 
+	mmgMesh->point[3].c[0]  = 0.5; mmgMesh->point[3].c[1]  = 0;  mmgMesh->point[3].c[2]  = 1;  mmgMesh->point[3].ref  = 0; 
+	mmgMesh->point[4].c[0]  = 0;   mmgMesh->point[4].c[1]  = 0;  mmgMesh->point[4].c[2]  = 1;  mmgMesh->point[4].ref  = 0; 
+	mmgMesh->point[5].c[0]  = 0;   mmgMesh->point[5].c[1]  = 1;  mmgMesh->point[5].c[2]  = 0;  mmgMesh->point[5].ref  = 0; 
+	mmgMesh->point[6].c[0]  = 0.5; mmgMesh->point[6].c[1]  = 1;  mmgMesh->point[6].c[2]  = 0;  mmgMesh->point[6].ref  = 0; 
+	mmgMesh->point[7].c[0]  = 0.5; mmgMesh->point[7].c[1]  = 1;  mmgMesh->point[7].c[2]  = 1;  mmgMesh->point[7].ref  = 0; 
+	mmgMesh->point[8].c[0]  = 0;   mmgMesh->point[8].c[1]  = 1;  mmgMesh->point[8].c[2]  = 1;  mmgMesh->point[8].ref  = 0; 
+	mmgMesh->point[9].c[0]  = 1;   mmgMesh->point[9].c[1]  = 0;  mmgMesh->point[9].c[2]  = 0;  mmgMesh->point[9].ref  = 0; 
+	mmgMesh->point[10].c[0] = 1;   mmgMesh->point[10].c[1] = 1;  mmgMesh->point[10].c[2] = 0;  mmgMesh->point[10].ref = 0; 
+	mmgMesh->point[11].c[0] = 1;   mmgMesh->point[11].c[1] = 0;  mmgMesh->point[11].c[2] = 1;  mmgMesh->point[11].ref = 0; 
+	mmgMesh->point[12].c[0] = 1;   mmgMesh->point[12].c[1] = 1;  mmgMesh->point[12].c[2] = 1;  mmgMesh->point[12].ref = 0; 
+  
+  /*tetra*/
+	mmgMesh->tetra[1].v[0]  = 1;  mmgMesh->tetra[1].v[1]  = 2;  mmgMesh->tetra[1].v[2]  = 4;  mmgMesh->tetra[1].v[3]  = 8;  mmgMesh->tetra[1].ref  = 1; 
+	mmgMesh->tetra[2].v[0]  = 8;  mmgMesh->tetra[2].v[1]  = 3;  mmgMesh->tetra[2].v[2]  = 2;  mmgMesh->tetra[2].v[3]  = 7;  mmgMesh->tetra[2].ref  = 1; 
+	mmgMesh->tetra[3].v[0]  = 2;  mmgMesh->tetra[3].v[1]  = 5;  mmgMesh->tetra[3].v[2]  = 6;  mmgMesh->tetra[3].v[3]  = 8;  mmgMesh->tetra[3].ref  = 1; 
+	mmgMesh->tetra[4].v[0]  = 8;  mmgMesh->tetra[4].v[1]  = 5;  mmgMesh->tetra[4].v[2]  = 1;  mmgMesh->tetra[4].v[3]  = 2;  mmgMesh->tetra[4].ref  = 1; 
+	mmgMesh->tetra[5].v[0]  = 2;  mmgMesh->tetra[5].v[1]  = 7;  mmgMesh->tetra[5].v[2]  = 8;  mmgMesh->tetra[5].v[3]  = 6;  mmgMesh->tetra[5].ref  = 1; 
+	mmgMesh->tetra[6].v[0]  = 2;  mmgMesh->tetra[6].v[1]  = 4;  mmgMesh->tetra[6].v[2]  = 3;  mmgMesh->tetra[6].v[3]  = 8;  mmgMesh->tetra[6].ref  = 1; 
+	mmgMesh->tetra[7].v[0]  = 2;  mmgMesh->tetra[7].v[1]  = 9;  mmgMesh->tetra[7].v[2]  = 3;  mmgMesh->tetra[7].v[3]  = 7;  mmgMesh->tetra[7].ref  = 2; 
+	mmgMesh->tetra[8].v[0]  = 7;  mmgMesh->tetra[8].v[1]  = 11; mmgMesh->tetra[8].v[2]  = 9;  mmgMesh->tetra[8].v[3]  = 12; mmgMesh->tetra[8].ref  = 2; 
+	mmgMesh->tetra[9].v[0]  = 9;  mmgMesh->tetra[9].v[1]  = 6;  mmgMesh->tetra[9].v[2]  = 10; mmgMesh->tetra[9].v[3]  = 7;  mmgMesh->tetra[9].ref  = 2; 
+	mmgMesh->tetra[10].v[0] = 7;  mmgMesh->tetra[10].v[1] = 6;  mmgMesh->tetra[10].v[2] = 2;  mmgMesh->tetra[10].v[3] = 9;  mmgMesh->tetra[10].ref = 2;
+	mmgMesh->tetra[11].v[0] = 9;  mmgMesh->tetra[11].v[1] = 12; mmgMesh->tetra[11].v[2] = 7;  mmgMesh->tetra[11].v[3] = 10; mmgMesh->tetra[11].ref = 2; 
+	mmgMesh->tetra[12].v[0] = 9;  mmgMesh->tetra[12].v[1] = 3;  mmgMesh->tetra[12].v[2] = 11; mmgMesh->tetra[12].v[3] = 7;  mmgMesh->tetra[12].ref = 2;
+  
+  
+  /*metric*/
+  mmgSol           = (MMG_pSol)calloc(1,sizeof(MMG_Sol));
+  assert(mmgSol); 
+  mmgSol->offset = 1;
+
+  /*scalaire size*/
+	mmgSol->np = mmgMesh->np;
+	mmgSol->npmax = mmgMesh->npmax;
+  mmgSol->met    = (double*)calloc(mmgSol->npmax+1,(int)mmgSol->offset*sizeof(double));
+  assert(mmgSol->met);  
+  mmgSol->metold = (double*)calloc(mmgSol->npmax+1,mmgSol->offset*sizeof(double));
+  assert(mmgSol->metold);
+	for(k=1 ; k<=mmgMesh->np ; k++) {
+		mmgSol->met[k] = 0.5;           
+	}
+   
+  opt[0]=4; //splitting
+  opt[1]=0; //debug
+  opt[2]=64; //par default 64
+  opt[3]=0;//noswap
+  opt[4]=0;//noinsert
+  opt[5]=0;//nomove
+  opt[6]=5; //imprim
+	opt[7]=3;  //renum
+	opt[8]=500; //renum
+  
+  if(MMG_mmg3dlib(opt,mmgMesh,mmgSol)) {
+		fprintf(stdout,"BAD ENDING OF MMG3DLIB\n");
+  }
+
+  /*save result*/
+	MMG_saveMesh(mmgMesh,"result.mesh");
+
+  /*save metric*/
+	MMG_saveSol(mmgMesh,mmgSol,"result.sol");
+
+  /* free mem */
+  free(mmgMesh->point);
+  free(mmgMesh->disp->alpha);
+  free(mmgMesh->disp->mv);
+  free(mmgMesh->disp);
+  free(mmgMesh->tria);
+  free(mmgMesh->tetra);
+  free(mmgMesh);
+  if ( mmgSol->npfixe )  free(mmgSol->met);
+  free(mmgSol);
+
+
+  return(0);
+}
diff --git a/contrib/mmg3d/build/sources/analar.c b/contrib/mmg3d/build/sources/analar.c
new file mode 100644
index 0000000000000000000000000000000000000000..ee4aa1e5bbdbd24d175d6bb6bace98fefed68abb
--- /dev/null
+++ b/contrib/mmg3d/build/sources/analar.c
@@ -0,0 +1,357 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+
+
+
+#include "mesh.h"
+
+#define EPS4  1.e-04
+
+extern int MMG_npuiss,MMG_nvol,MMG_npres;
+extern int MMG_nlen,MMG_ncal,MMG_ntopo,MMG_nex;
+extern int MMG_npuisstot,MMG_nvoltot,MMG_nprestot;
+extern int MMG_npdtot;
+       int MMG_nplen,MMG_npref,MMG_bouffe;
+
+int MMG_interp_ani(double *ma,double *mb,double *mp,double t) {
+  double	dma[6],dmb[6],mai[6],mbi[6],mi[6];
+  int		i;
+
+  for (i=0; i<6; i++) {
+    dma[i] = ma[i];
+    dmb[i] = mb[i];
+  }
+  if ( !MMG_invmat(dma,mai) || !MMG_invmat(dmb,mbi) ) {
+    fprintf(stderr,"  ## INTERP INVALID METRIC.\n");
+    return(0);
+  }
+  for (i=0; i<6; i++)
+    mi[i] = (1.0-t)*mai[i] + t*mbi[i];
+    
+  if ( !MMG_invmat(mi,mai) ) {
+    fprintf(stderr,"  ## INTERP INVALID METRIC.\n");
+    return(0);
+  } 
+  
+  for (i=0; i<6; i++)  mp[i] = mai[i];
+
+  return(1);
+}
+
+int MMG_interplog(double *ma,double *mb,double *mp,double *mplog,double t) {
+  double	dma[6],dmb[6],mai[6],mi[6];
+  int		i,ii,jj,kk;
+  double	lambda[3],v[3][3];
+
+  for (i=0; i<6; i++) {
+    dma[i] = ma[i];
+    dmb[i] = mb[i];
+  }
+  
+  for (i=0; i<6; i++)
+    mi[i] = (1.0-t)*dma[i] + t*dmb[i];
+  
+  /*pour metrique log : extraction vp et exponentielle*/
+  if ( !eigenv(1,mi,lambda,v) ) {
+	     puts("pbs eigen interp"); 
+	     return(0);
+   }
+   for (i=0; i<3; i++) lambda[i] = exp(lambda[i]);
+   kk = 0;
+   for (ii=0; ii<3; ii++) {
+     for (jj=ii; jj<3; jj++) {
+       mai[kk] = lambda[0]*v[0][ii]*v[0][jj] + 
+	             lambda[1]*v[1][ii]*v[1][jj] +
+                 lambda[2]*v[2][ii]*v[2][jj]; 
+       kk = kk+1;
+    }                     
+  }
+  
+  /*if ( !MMG_invmat(mi,mai) ) {
+    fprintf(stderr,"  ## INTERP INVALID METRIC.\n");
+    return(0);
+  } */
+  
+  for (i=0; i<6; i++)  mplog[i] = mi[i];  
+  for (i=0; i<6; i++)  mp[i] = mai[i];
+
+  return(1);
+}
+int MMG_interp_iso(double *ma,double *mb,double *mp,double t) {
+
+  *mp = (1.0-t)*(*ma) + t*(*mb);
+  return(1);
+}
+//#define LLONG 1.1
+//#define LSHORT 0.9                          
+/* optimisation based on edge lengths */
+int MMG_analar(pMesh mesh,pSol sol,pBucket bucket,int *na,int *nd,int *nf,int *alert) {
+  pTetra	pt;
+  pPoint	pa,pb;
+  List		list;
+  double	len,coef,siz,t1,declic,*ma,*mb,*mip,*ca,*cb,mp[6],c[3]; 
+  //double  *malog,*mblog,mplog[6];
+  int		  i,k,lon,nad,ndd,npp,npd,ia,ib,ip,ipa,ipb,nedep,base,ifilt;
+  int		  *adja,adj,ret,vois[4],ref,tag,iadr,j,imax;
+  char		tabar,tagedg;
+  int     MMG_ncavity;
+    
+  /* for Delaunay cavity */
+  if ( !MMG_zaldy4(&list.hedg,3*LONMAX) ) {
+    fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM.\n");
+    return(0);
+  }
+
+MMG_npuiss=0;
+MMG_npres=0;
+MMG_nvol=0;    
+MMG_ncavity=0;
+MMG_nplen=0;
+MMG_npref=0;
+MMG_nlen = 0;
+MMG_ncal = 0;
+MMG_ntopo = 0;
+MMG_nex = 0;
+MMG_bouffe = 0;
+
+  npp = 0;
+  nad = 0;
+  ndd = 0;
+  npd = 0;
+  coef  = QDEGRAD;//1.;//QDEGRAD;
+  ifilt = 0;
+  nedep = mesh->ne;
+  base  = ++mesh->flag;
+
+  declic = 1.5/ALPHAD;// 60.*LLONG;
+  
+  for (k=1; k<=nedep; k++) {
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+    else if ( pt->flag != base-1 )  continue; 
+    if ( pt->qual < declic ) continue;
+    pt->flag = base-2;                
+        
+    /* mark internal edges */
+    tabar  = 0;
+    tagedg = 0;
+    iadr  = 4*(k-1) + 1;
+    adja  = &mesh->adja[iadr];
+    vois[0]  = adja[0] >> 2;
+    vois[1]  = adja[1] >> 2;
+    vois[2]  = adja[2] >> 2;
+    vois[3]  = adja[3] >> 2;
+    for (i=0; i<4; i++) {
+      adj    = vois[i];
+      ref    = mesh->tetra[adj].ref;
+      tag    = mesh->tetra[adj].flag;
+      if ( !adj || pt->ref != ref ) {
+        tabar |= 1 << MMG_iarf[i][0];
+        tabar |= 1 << MMG_iarf[i][1];
+        tabar |= 1 << MMG_iarf[i][2];
+      }
+      if ( adj && tag == base - 2 ) {
+        tagedg |= 1 << MMG_iarf[i][0];
+        tagedg |= 1 << MMG_iarf[i][1];
+        tagedg |= 1 << MMG_iarf[i][2];
+      }
+      
+    }
+    if ( (tabar == ALL_BDRY) || (tagedg == ALL_BDRY) )  continue;
+    
+    //imax = ((int) pt->qual)%6;
+    imax = 0;
+    
+    for (j=imax; j<imax+6; j++) {
+      i = j;
+      if ( (tabar & 1<<i) || (tagedg & 1<<i) )  continue;
+        
+        /* edge length */
+        ia  = MMG_iare[i][0];
+        ib  = MMG_iare[i][1];
+        ipa = pt->v[ia];
+        ipb = pt->v[ib];
+        
+        ca  = &mesh->point[ipa].c[0];
+        cb  = &mesh->point[ipb].c[0];
+        
+        iadr = (ipa-1)*sol->offset + 1;
+        ma  = &sol->met[iadr];
+        
+        iadr = (ipb-1)*sol->offset + 1;
+        mb  = &sol->met[iadr];        
+              
+        len = MMG_length(ca,cb,ma,mb);
+        
+        if ( len > LLONG && *alert != 1 ) {
+          npp++;
+        
+          siz=0.5;
+
+          /* metric interpolation */
+          if ( sol->offset==1 ) {   
+            if(!MMG_interp(ma,mb,mp,siz) ) continue;
+          }    
+          else {
+            iadr = (ipa-1)*sol->offset + 1;
+            //malog  = &sol->metold[iadr];
+          
+            iadr = (ipb-1)*sol->offset + 1;
+            //mblog  = &sol->metold[iadr];
+            //if ( !MMG_interplog(malog,mblog,mp,mplog,siz) ) continue; 
+            if ( !MMG_interp_ani(ma,mb,mp,siz) ) continue;      
+          }
+          
+          t1   = 1.0 - siz;
+          c[0] = t1*ca[0] +  siz*cb[0];
+          c[1] = t1*ca[1] +  siz*cb[1];
+          c[2] = t1*ca[2] +  siz*cb[2]; 
+          //printf("siz %e new len %e - %e (%e) %d %d\n", siz,MMG_length(ca,c,ma,mb),MMG_length(cb,c,ma,mb),len,(int)(len+0.5),nbp);
+          ip   = MMG_newPt(mesh,c);
+          if ( ip < 1 )  {
+    	    *alert = 1;
+            break;
+          }
+    	    else {
+            iadr = (ip-1)*sol->offset + 1;
+            //mipold  = &sol->metold[iadr];	  
+    	      //memcpy(mipold,mplog,sol->offset*sizeof(double));
+            mip  = &sol->met[iadr];	  
+    	      memcpy(mip,mp,sol->offset*sizeof(double));
+            
+            /* bucket filter */
+            if (!MMG_buckin(mesh,sol,bucket,ip) ) {
+              MMG_delPt(mesh,ip);
+              ifilt++;
+              continue;
+            }
+            
+    	      /* Delaunay kernel */
+            lon = MMG_coquil(mesh,k,i,&list);    
+            lon = MMG_cavity(mesh,sol,k,ip,&list,lon);
+            if ( lon < 1 ) {
+              MMG_delPt(mesh,ip);    
+    	        npd++;
+              if ( lon == -1 ) {  
+                MMG_ncavity++;                
+    				    //printf("cavity pete\n");
+                *alert = 2;
+              } else if ( lon < 0 ) {
+    	          *alert = 1;
+    	          break;
+    	        }
+              else {  	      
+    	          continue;
+    	        }
+    	      }
+    	      else {
+    	        ret = MMG_delone(mesh,sol,ip,&list,lon);
+    	        if ( ret > 0 ) {
+                MMG_addBucket(mesh,bucket,ip);
+                nad++;
+    	          *alert = 0;
+              }
+              else if ( ret == 0 ) {
+    	          MMG_delPt(mesh,ip);
+    	          npd++;
+                *alert = 1;
+                break;
+              }
+    	        else {
+    	          MMG_delPt(mesh,ip);
+    	          npd++;
+    	          MMG_bouffe++;
+    	        }
+    	      } 
+          }
+    	    break;
+        }
+
+        else if ( len < LSHORT ) {
+          npp++;
+    	    pa = &mesh->point[ipa];
+    	    pb = &mesh->point[ipb];
+    	    if ( MMG_colpoi(mesh,sol,k,ia,ib,coef) ) {
+    	      MMG_delBucket(mesh,bucket,ipb);
+            MMG_delPt(mesh,ipb);
+            ndd++; 
+    	      break;
+    	    }
+    	    else if ( MMG_colpoi(mesh,sol,k,ib,ia,coef) ) {
+    	      MMG_delBucket(mesh,bucket,ipa);
+            MMG_delPt(mesh,ipa);
+    	      ndd++;            
+    	      break;
+    	    } 
+        } 
+      }
+      if ( *alert == 1 )  break;
+    }
+
+  *na  = nad;
+  *nd  = ndd;
+  *nf += ifilt;
+  if ( abs(mesh->info.imprim) > 5 || mesh->info.ddebug ) {  
+    printf("analyzed %d \n",npp);
+    printf("rejected colpoi : cal %d  , len %d , topo %d , ex %d\n",MMG_ncal,MMG_nlen,MMG_ntopo,MMG_nex);
+    MMG_npdtot+=npd;
+    MMG_nvoltot+=MMG_nvol;
+    MMG_npuisstot+=MMG_npuiss;
+    MMG_nprestot+=MMG_npres;
+    if (npd>0) {
+      printf("rejected %d : cavity %d vol %d  , puiss %d , pres %d  bouffe %d\n",npd,MMG_ncavity,MMG_nvol,MMG_npuiss,MMG_npres,MMG_bouffe);
+    }
+  }
+
+  if ( *alert == 1 ) {
+    fprintf(stdout,"  ## UNABLE TO CREATE NEW ELEMENT %d , %d\n",
+            mesh->np,mesh->ne);
+  } else *alert = 0;
+  M_free(list.hedg.item);
+  return(1);
+}
+
+
diff --git a/contrib/mmg3d/build/sources/analarcutting.c b/contrib/mmg3d/build/sources/analarcutting.c
new file mode 100644
index 0000000000000000000000000000000000000000..e36ca1413466ddd2ce0daf96a7ce343d8ce8c019
--- /dev/null
+++ b/contrib/mmg3d/build/sources/analarcutting.c
@@ -0,0 +1,319 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+
+//#define LLLONG   3.//2.5
+
+int MMG_permar[12][4] = {{0,1,2,3},{0,2,3,1},{2,0,1,3},{0,3,1,2},{1,0,3,2},{3,2,1,0},
+                         {3,0,2,1},{1,2,0,3},
+                         {3,1,0,2},{2,3,0,1},{2,1,3,0},{1,3,2,0}};
+
+int MMG_pointar[64][2]  = {{-1,-1},
+  {0,1},
+  {2,1},
+  {4,22},
+  {6,1},
+  {6,22},
+  {2,22},
+  {10,31},
+  {7,1},  
+  {10,22},
+  {1,22},
+  {10,3},
+  {0,2},
+  {11,33},
+  {4,32},
+  {4,4},
+  {8,1},
+  {0,22},
+  {7,2},
+  {10,32},
+  {11,22},
+  {0,3},
+  {0,33},
+  {6,4},
+  {8,22},
+  {9,31},
+  {4,33},
+  {10,4},
+  {0,32},
+  {0,4},
+  {2,41},
+  {9,5}, 
+  {9,1},
+  {2,2},
+  {5,22},
+  {10,33},
+  {3,22},
+  {2,32},
+  {2,3},
+  {2,4},
+  {7,22},
+  {1,32},
+  {3,31},
+  {1,4},
+  {2,33},
+  {7,41},
+  {5,4},
+  {11,5},
+  {9,22},
+  {6,33},
+  {7,32},
+  {0,41},
+  {0,31},
+  {11,4},
+  {3,4},
+  {7,5},
+  {7,3},
+  {8,4},
+  {7,4},
+  {3,5},
+  {9,4},
+  {1,5},
+  {0,5},
+  {0,6}
+ };
+   
+int MMG_createPoint(pMesh mesh, pSol sol, int ipa, int ipb) { 
+  double    *ca,*cb,*ma,*mb,*mip,mp[6],*mipold,mplog[6],c[3];
+  //double    *malog,*mblog;
+  int       iadr,ip;
+
+  ca  = &mesh->point[ipa].c[0];
+  cb  = &mesh->point[ipb].c[0];
+
+  iadr = (ipa-1)*sol->offset + 1;
+  ma  = &sol->met[iadr];
+  iadr = (ipb-1)*sol->offset + 1;
+  mb  = &sol->met[iadr];        
+
+  c[0] = 0.5*(ca[0] + cb[0]);
+  c[1] = 0.5*(ca[1] + cb[1]);   
+  c[2] = 0.5*(ca[2] + cb[2]);   
+  
+  
+  ip = MMG_newPt(mesh,c);  
+
+  /* metric interpolation */
+  if ( sol->offset==1 ) {   
+    if ( !MMG_interp(ma,mb,mp,0.5) )  return(0);
+  }    
+  else { 
+    iadr = (ipa-1)*sol->offset + 1;
+    //malog  = &sol->metold[iadr];
+
+    iadr = (ipb-1)*sol->offset + 1;
+    //mblog  = &sol->metold[iadr];
+    //if ( !MMG_interplog(malog,mblog,mp,mplog,0.5) ) return(0);      
+    if ( !MMG_interp_ani(ma,mb,mp,0.5) ) return(0);      
+  }
+  iadr = (ip-1)*sol->offset + 1;
+  mipold  = &sol->metold[iadr];   
+  memcpy(mipold,mplog,sol->offset*sizeof(double));
+  mip  = &sol->met[iadr];   
+  memcpy(mip,mp,sol->offset*sizeof(double));
+
+  return(ip);  
+}
+
+extern int ddebug;
+int MMG_analarcutting(pMesh mesh,pSol sol,pHedge hash,int *alert,double* lmoy,double LLLONG) {
+  pTetra    pt;
+  int       k,i,ia,ib,ip,ipa,ipb,iadr,na,ncut;
+  double    *ca,*cb,len,*ma,*mb;  
+  int       nb[7],ne,base;
+  int       ned;
+  int       n1,n2,n3,n4,n5,n6,n22,n31,n32,n33,n41;
+  
+  n1 = n2 = n3 = n4 = n5 = n6 = n22 = n31 = n32 = n33 = n41 = 0;   
+  na     = 0;
+	*alert = 0; 
+  ne     = mesh->ne; 
+  base   = ++mesh->flag;  
+  
+  ned   = 0;
+  *lmoy = 0;
+  for (k=1; k<=ne; k++) {
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue; 
+    else if ( pt->flag == base ) continue; //attention si Delaunay avant on peut avoir des trous dans le tab des tets...
+    //normalement on devrait pouvoir juste traiter les tets à base-1... non ?    
+    pt->tabedg = 0; //because used by cendel
+    assert(!pt->tabedg);
+    
+    ncut  = 0;    
+    for (i=0; i<6; i++) {
+      ia  = MMG_iare[i][0];
+      ib  = MMG_iare[i][1];
+      ipa = pt->v[ia];
+      ipb = pt->v[ib];
+      /* already cutted ? */
+      nb[i] = MMG_edgePoint(hash,ipa,ipb);
+      if ( nb[i] ) {
+        //if(nb[i]==6992) printf("already cut %d %d : %d -- %d\n",ipa,ipb,nb[i],k); 
+        pt->tabedg |= 1 << i;
+        ncut++;
+        continue;
+      }
+      ca  = &mesh->point[ipa].c[0];
+      cb  = &mesh->point[ipb].c[0];
+  
+      iadr = (ipa-1)*sol->offset + 1;
+      ma  = &sol->met[iadr];
+      iadr = (ipb-1)*sol->offset + 1;
+      mb  = &sol->met[iadr];        
+
+      /* edge length */  
+      len = MMG_length(ca,cb,ma,mb); 
+      *lmoy += len;
+      ned++;
+      if ( len > LLLONG ) { 
+        ip = MMG_createPoint(mesh,sol,ipa,ipb);
+        //if(ip==6992) printf("on cree %d : %d -- %d %d %d %d\n",ip,k,pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
+        if ( !ip ) {
+          *alert = 1;
+          return(0);
+        }        
+        /*hash insertion*/ 
+        if ( !MMG_edgePut(hash,ipa,ipb,ip) ) {
+          printf("ahhhhhhhhhhhhhhhhh %d %d\n",ipa,ipb); 
+          exit(0);
+        }
+        nb[i] = ip;
+        pt->tabedg |= 1 << i;
+        na++; 
+        ncut++;                   
+      } 
+    }
+    //if(if(mesh->info.ddebug)) printf("tet %d ncut %d : %d %d\n",k,ncut,pt->tabedg,MMG_pointar[pt->tabedg][1]); 
+    //if(ddebug && ncut) printf("tet %d %d %d %d\n",pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
+    if (!ncut) continue;
+    else if ( MMG_pointar[pt->tabedg][1] > -1 ) {
+			if(mesh->info.ddebug){
+				printf("tet %d : %d\n",k,MMG_pointar[pt->tabedg][1]);
+			  printf("pour ce tet ref : %d %d %d %d\n",pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]);
+      }
+      switch(MMG_pointar[pt->tabedg][1]) {
+        case 1: 
+          n1++;
+          MMG_pattern1(mesh,sol,hash,k);
+          break;
+        case 2:
+          n2++;
+          MMG_pattern2(mesh,sol,hash,k);
+          break;
+        case 3:
+          n3++;
+          MMG_pattern3(mesh,sol,hash,k);
+          break;
+        case 4:
+          MMG_pattern4(mesh,sol,hash,k);
+          n4++;
+          break; 
+        case 5:
+          MMG_pattern5(mesh,sol,hash,k);
+          n5++;
+          break;
+        case -1:
+          puts("MMG_analar case -1");
+          exit(0);
+        case 6:
+          MMG_pattern6(mesh,sol,k,nb); 
+          n6++; 
+          break; 
+        case 22:
+          MMG_pattern22(mesh,sol,hash,k); 
+          n22++;
+          break;
+        case 31:
+          MMG_pattern31(mesh,sol,hash,k);  
+          n31++;
+          break;
+        case 32:
+          MMG_pattern32(mesh,sol,hash,k);  
+          n32++;
+          break;
+        case 33:
+          MMG_pattern33(mesh,sol,hash,k);   
+          n33++;
+          break;
+        case 41:
+          MMG_pattern41(mesh,sol,hash,k);   
+          n41++;
+          break;
+          
+      } 
+			//       if ( 1 ){printf("pointar tet 6545 : %d %d %d %d %d\n",
+			//                       MMG_pointar[pt->tabedg][1],mesh->tetra[6545].v[0],mesh->tetra[6545].v[1]
+			//                                         ,mesh->tetra[6545].v[2],mesh->tetra[6545].v[3]);
+			//        printf("bdry ref : %d %d %d %d\n",mesh->tetra[6545].bdryref[0],mesh->tetra[6545].bdryref[1]
+			//                                          ,mesh->tetra[6545].bdryref[2],mesh->tetra[6545].bdryref[3]);}
+  		//if(mesh->ne>=41495) {exit(0);  }
+    
+    }/*end if pointar > -1*/   
+  } 
+  *lmoy /= ned;
+  
+  /*puts("stats cut -------------------"); 
+  printf("1 cut : %8d\n",n1);
+  printf("2 cut : %8d %8d\n",n2,n22);
+  printf("3 cut : %8d %8d %8d %8d\n",n3,n31,n32,n33);
+  printf("4 cut : %8d %8d\n",n4,n41);
+  printf("5 cut : %8d\n",n5);
+  printf("6 cut : %8d\n",n6);
+  printf("---------------------------\n"); */  
+	if ( !na )  return(na);
+#warning check memory allocation
+  
+  //printf("%d cut init --- nb tet %d\n",na,mesh->ne);
+  return(na);
+}
+
+
+
+
+
diff --git a/contrib/mmg3d/build/sources/baryct.c b/contrib/mmg3d/build/sources/baryct.c
new file mode 100644
index 0000000000000000000000000000000000000000..138f158f9e55fcff6eaf17ed6e027657bbeb6d28
--- /dev/null
+++ b/contrib/mmg3d/build/sources/baryct.c
@@ -0,0 +1,112 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+#define EPST    -1.e-14
+#define EPSR     1.e+14
+
+
+/* compute barycentrics */
+int MMG_baryct(pMesh mesh,pTetra pt,double p[3],double cb[4]) {
+  pPoint	p0,p1,p2,p3;
+  double	bx,by,bz,cx,cy,cz,dx,dy,dz,vx,vy,vz,apx,apy,apz;
+  double	epsra,vol1,vol2,vol3,vol4,dd; 
+
+  p0 = &mesh->point[pt->v[0]];
+  p1 = &mesh->point[pt->v[1]];
+  p2 = &mesh->point[pt->v[2]];
+  p3 = &mesh->point[pt->v[3]];
+
+  /* barycentric */
+  bx  = p1->c[0] - p0->c[0];
+  by  = p1->c[1] - p0->c[1];
+  bz  = p1->c[2] - p0->c[2];
+  cx  = p2->c[0] - p0->c[0];
+  cy  = p2->c[1] - p0->c[1];
+  cz  = p2->c[2] - p0->c[2];
+  dx  = p3->c[0] - p0->c[0];
+  dy  = p3->c[1] - p0->c[1];
+  dz  = p3->c[2] - p0->c[2];
+
+  /* test volume */
+  vx  = cy*dz - cz*dy;
+  vy  = cz*dx - cx*dz;
+  vz  = cx*dy - cy*dx;
+
+  epsra = EPST*(bx*vx + by*vy + bz*vz);
+  apx = p[0] - p0->c[0];
+  apy = p[1] - p0->c[1];
+  apz = p[2] - p0->c[2];
+
+  /* p in 2 */
+  vol2  = apx*vx + apy*vy + apz*vz;
+  if ( epsra > vol2 )  return(0);
+
+  /* p in 3 */
+  vx  = by*apz - bz*apy;
+  vy  = bz*apx - bx*apz;
+  vz  = bx*apy - by*apx;
+  vol3 = dx*vx + dy*vy + dz*vz;
+  if ( epsra > vol3 )  return(0);
+    
+  /* p in 4 */
+  vol4 = -cx*vx - cy*vy - cz*vz;
+  if ( epsra > vol4 )  return(0);
+  
+  /* p in 1 */
+  vol1 = -epsra * EPSR - vol2 - vol3 - vol4;
+  if ( epsra > vol1 )  return(0);
+
+  dd = vol1+vol2+vol3+vol4;
+  if ( dd != 0.0 )  dd = 1.0 / dd;
+  cb[0] = vol1 * dd;
+  cb[1] = vol2 * dd;
+  cb[2] = vol3 * dd;
+  cb[3] = vol4 * dd; 
+
+  return(1);
+}
+
diff --git a/contrib/mmg3d/build/sources/boulep.c b/contrib/mmg3d/build/sources/boulep.c
new file mode 100644
index 0000000000000000000000000000000000000000..001bd54e92f114cba7d7e647e4ad911ed794c9df
--- /dev/null
+++ b/contrib/mmg3d/build/sources/boulep.c
@@ -0,0 +1,206 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+
+/* find all tets sharing P
+   in:  start : tetrahedron containing p 
+        ip    : index of p in start
+        list  : dynamic list structure (allocated outside)
+   out: list  : list of tets */
+int MMG_boulep(pMesh mesh,int start,int ip,pList list) {
+  pTetra	pt,pt1;
+  pPoint	ppt;
+  int		*adja,adj,i,j,indp,iel,iadr,base,ilist,nump;
+  int 		vois[4];
+
+  if ( start < 1 )  return(0);
+  pt   = &mesh->tetra[start];
+  if ( !pt->v[0] )  return(0);
+  nump = pt->v[ip];
+  ppt  = &mesh->point[nump];
+  if ( ppt->tag & M_BDRY || ppt->tag & M_UNUSED )  return(0);
+
+  /* store initial tet */
+  base     = ++mesh->mark;
+  pt->mark = base;
+  ilist    = 1;
+  list->tetra[ilist] = 4*start + ip;
+
+  /* store 3 neighbors sharing P */
+  iadr = (start-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  vois[0]  = adja[0] >> 2;
+  vois[1]  = adja[1] >> 2;
+  vois[2]  = adja[2] >> 2;
+  vois[3]  = adja[3] >> 2;
+  for (i=0; i<4; i++) {
+    if ( i == ip )  continue;
+    adj = vois[i];
+    if ( adj ) {
+      pt1 = &mesh->tetra[adj];
+      if ( pt1->mark != base ) {
+				pt1->mark = base;
+				for (j=0; j<4; j++)
+          if ( pt1->v[j] == nump )  break;
+        ilist++;
+        list->tetra[ilist] = 4*adj + j;
+      }
+    }
+  }
+  if ( ilist < 2 )  return(ilist);
+
+  /* explore list of neighbors */
+  indp = 2;
+  do {
+    iel  = list->tetra[indp] >> 2;
+    pt   = &mesh->tetra[iel];
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    vois[0]  = adja[0] >> 2;
+    vois[1]  = adja[1] >> 2;
+    vois[2]  = adja[2] >> 2;
+    vois[3]  = adja[3] >> 2;
+
+    for (i=0; i<4; i++) {
+      if ( pt->v[i] == nump )  continue;
+      adj = vois[i];
+      if ( adj ) {
+        pt1 = &mesh->tetra[adj];
+        if ( pt1->mark != base ) {
+	  			pt1->mark = base;
+	  			for (j=0; j<4; j++)
+            if ( pt1->v[j] == nump )  break;
+	  			ilist++;
+          list->tetra[ilist] = 4*adj + j;
+       }
+      }
+    }
+    /* overflow */
+    if ( ilist > LONMAX-3 )  return(-ilist);
+  }
+  while ( ++indp <= ilist );
+
+  return(ilist);
+}
+
+
+/* idem boulep for any vertex */
+int MMG_bouleg(pMesh mesh,int start,int ip,pList list) {
+  pTetra	pt,pt1;
+  pPoint	ppt;
+  int		*adja,adj,i,j,indp,iel,iadr,base,ilist,nump;
+  int		vois[4];
+  
+  if ( start < 1 )  return(0);
+  pt   = &mesh->tetra[start];
+  if ( !pt->v[0] )  return(0);
+  nump = pt->v[ip];
+  ppt  = &mesh->point[nump];
+  if ( ppt->tag & M_UNUSED )  return(0);
+
+  /* store initial tet */
+  base     = ++mesh->mark;
+  pt->mark = base;
+  ilist    = 1;
+  list->tetra[ilist] = 4*start + ip;
+
+  /* store 3 neighbors sharing P */
+  iadr = (start-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  vois[0]  = adja[0] >> 2;
+  vois[1]  = adja[1] >> 2;
+  vois[2]  = adja[2] >> 2;
+  vois[3]  = adja[3] >> 2;
+  for (i=0; i<4; i++) {
+    if ( i == ip )  continue;
+    adj = vois[i];
+    if ( adj ) {
+      pt1 = &mesh->tetra[adj];
+      if ( pt1->mark != base ) {
+	pt1->mark = base;
+	for (j=0; j<4; j++)
+          if ( pt1->v[j] == nump )  break;
+        ilist++;
+        list->tetra[ilist] = 4*adj + j;
+      }
+    }
+  }
+  if ( ilist < 2 )  return(ilist);
+
+  /* explore list of neighbors */
+  indp = 2;
+  do {
+    iel  = list->tetra[indp] >> 2;
+    pt   = &mesh->tetra[iel];
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    vois[0]  = adja[0] >> 2;
+    vois[1]  = adja[1] >> 2;
+    vois[2]  = adja[2] >> 2;
+    vois[3]  = adja[3] >> 2;
+
+    for (i=0; i<4; i++) {
+      if ( pt->v[i] == nump )  continue;
+      adj = vois[i];
+      if ( adj ) {
+        pt1 = &mesh->tetra[adj];
+        if ( pt1->mark != base ) {
+	  pt1->mark = base;
+	  for (j=0; j<4; j++)
+            if ( pt1->v[j] == nump )  break;
+	  ilist++;
+          list->tetra[ilist] = 4*adj + j;
+       }
+      }
+    }
+    /* overflow */
+    if ( ilist > LONMAX-3 )  return(-ilist);
+  }
+  while ( ++indp <= ilist );
+
+  return(ilist);
+}
diff --git a/contrib/mmg3d/build/sources/bucket.c b/contrib/mmg3d/build/sources/bucket.c
new file mode 100644
index 0000000000000000000000000000000000000000..7b8938b8dbe571e9d4b3727792000cdeb500cb21
--- /dev/null
+++ b/contrib/mmg3d/build/sources/bucket.c
@@ -0,0 +1,385 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+/* create bucket structure and store initial vertices */
+pBucket MMG_newBucket(pMesh mesh,int nmax) {
+  pPoint	ppt;
+  pBucket	bucket;
+  double	dd;
+  int		k,ic,ii,jj,kk;
+
+  /* memory alloc */
+  bucket = (Bucket*)M_malloc(sizeof(Bucket),"newBucket");
+  assert(bucket);
+  bucket->size = nmax;
+  bucket->head = (int*)M_calloc(nmax*nmax*nmax+1,sizeof(int),"newBucket.head");
+  assert(bucket->head);
+  bucket->link = (int*)M_calloc(mesh->npmax+1,sizeof(int),"newBucket.link");
+  assert(bucket->link);
+
+  /* insert vertices */
+  dd = nmax / (double)PRECI;
+  for (k=1; k<=mesh->np; k++) {
+    ppt = &mesh->point[k];
+    if ( ppt->tag & M_UNUSED )  continue;
+    ii = M_MAX(0,(int)(dd * ppt->c[0])-1);
+    jj = M_MAX(0,(int)(dd * ppt->c[1])-1);
+    kk = M_MAX(0,(int)(dd * ppt->c[2])-1);
+    ic = (kk*nmax + jj)*nmax + ii;
+
+    if ( !bucket->head[ic] )
+      bucket->head[ic] = k;
+    else {
+      bucket->link[k]  = bucket->head[ic];
+      bucket->head[ic] = k;
+    }
+  }
+
+  return(bucket);
+}
+
+
+void MMG_freeBucket(pBucket bucket) {
+  M_free(bucket->head);
+  M_free(bucket->link);
+  M_free(bucket);
+}
+
+
+/* check and eventually insert vertex */
+int MMG_buckin_ani(pMesh mesh,pSol sol,pBucket bucket,int ip) {
+  pPoint	ppt,pp1;
+  double	dd,d2,det,ux,uy,uz,dmi,m1,m2,m3,dx,dy,dz;
+  double	*ma,*mb;
+  int		i,j,k,ii,jj,kk,ic,icc,siz,ip1;
+  int 		iadr,imin,imax,jmin,jmax,kmin,kmax;
+
+  ppt = &mesh->point[ip];
+  siz = bucket->size;
+  dd  = siz / (double)PRECI;
+
+  iadr = (ip-1)*sol->offset + 1;
+  ma   = &sol->met[iadr];
+  dmi  = LFILT*LFILT;
+
+  ii = M_MAX(0,(int)(dd * ppt->c[0])-1);
+  jj = M_MAX(0,(int)(dd * ppt->c[1])-1);
+  kk = M_MAX(0,(int)(dd * ppt->c[2])-1);
+  ic = (kk*siz + jj)*siz + ii;
+
+  /* check current cell */
+  if ( bucket->head[ic] ) {
+    ip1 = bucket->head[ic];
+    pp1 = &mesh->point[ip1];
+    ux = pp1->c[0] - ppt->c[0];
+    uy = pp1->c[1] - ppt->c[1];
+    uz = pp1->c[2] - ppt->c[2];
+    d2 =      ma[0]*ux*ux + ma[3]*uy*uy + ma[5]*uz*uz \
+       + 2.0*(ma[1]*ux*uy + ma[2]*ux*uz + ma[4]*uy*uz);
+    if ( d2 < dmi ) {
+      iadr = (ip1-1)*sol->offset + 1;
+      mb = &sol->met[iadr];
+      d2 =      mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \
+         + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz);
+      if ( d2 < dmi )  return(0);
+    }
+
+    while ( bucket->link[ip1] ) {
+      ip1 = bucket->link[ip1];
+      pp1 = &mesh->point[ip1];
+      ux = pp1->c[0] - ppt->c[0];
+      uy = pp1->c[1] - ppt->c[1];
+      uz = pp1->c[2] - ppt->c[2];
+      d2 =      ma[0]*ux*ux + ma[3]*uy*uy + ma[5]*uz*uz \
+         + 2.0*(ma[1]*ux*uy + ma[2]*ux*uz + ma[4]*uy*uz);
+      if ( d2 < dmi ) {
+        iadr = (ip1-1)*sol->offset + 1;
+        mb = &sol->met[iadr];
+        d2 =      mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \
+           + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz);
+        if ( d2 < dmi )  return(0);
+      }
+    }
+  }
+
+  /* bounding box */
+  det = ma[0] * (ma[3]*ma[5] - ma[4]*ma[4]) \
+      - ma[1] * (ma[1]*ma[5] - ma[2]*ma[4]) \
+      + ma[2] * (ma[1]*ma[4] - ma[3]*ma[2]);
+  det = 1.0 / det;
+  m1 = ma[3]*ma[5] - ma[4]*ma[4];
+  m2 = ma[0]*ma[5] - ma[2]*ma[2];
+  m3 = ma[0]*ma[3] - ma[1]*ma[1];
+  if ( det < 0.0 || m1 < 0.0 )
+    return(1);
+  else {
+    dx = LFILT * sqrt(m1 * det) ;
+    dy = LFILT * sqrt(m2 * det) ;
+    dz = LFILT * sqrt(m3 * det) ;
+  }
+
+  imin = (int)(dd * (ppt->c[0]-dx))-1;
+  jmin = (int)(dd * (ppt->c[1]-dy))-1;
+  kmin = (int)(dd * (ppt->c[2]-dz))-1;
+  imax = (int)(dd * (ppt->c[0]+dx))-1;
+  jmax = (int)(dd * (ppt->c[1]+dy))-1;
+  kmax = (int)(dd * (ppt->c[2]+dz))-1;
+
+  imin = M_MAX(0,M_MIN(imin,siz-1));
+  imax = M_MIN(siz-1,M_MAX(0,imax));
+  jmin = M_MAX(0,M_MIN(jmin,siz-1));
+  jmax = M_MIN(siz-1,M_MAX(0,jmax));
+  kmin = M_MAX(0,M_MIN(kmin,siz-1));
+  kmax = M_MIN(siz-1,M_MAX(0,kmax));
+  if ( imin == imax && jmin == jmax && kmin == kmax )  return(1);
+
+  /* explore neighbours */
+  for (k=kmin; k<=kmax; k++)
+    for (j=jmin; j<=jmax; j++) 
+      for (i=imin; i<=imax; i++) {
+        icc = (k*siz + j)*siz + i;
+        ip1 = bucket->head[icc];
+        if ( !ip1 )  continue;
+        pp1 = &mesh->point[ip1];
+        ux = pp1->c[0] - ppt->c[0];
+        uy = pp1->c[1] - ppt->c[1];
+        uz = pp1->c[2] - ppt->c[2];
+        d2 =      ma[0]*ux*ux + ma[3]*uy*uy + ma[5]*uz*uz \
+           + 2.0*(ma[1]*ux*uy + ma[2]*ux*uz + ma[4]*uy*uz);
+        if ( d2 < dmi ) {
+          iadr = (ip1-1)*sol->offset + 1;
+          mb = &sol->met[iadr];
+          d2 =      mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \
+             + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz);
+          if ( d2 < dmi )  return(0);
+        }
+
+        while ( bucket->link[ip1] ) {
+          ip1 = bucket->link[ip1];
+          pp1 = &mesh->point[ip1];
+          ux = pp1->c[0] - ppt->c[0];
+          uy = pp1->c[1] - ppt->c[1];
+          uz = pp1->c[2] - ppt->c[2];
+          d2 =      ma[0]*ux*ux + ma[3]*uy*uy + ma[5]*uz*uz \
+             + 2.0*(ma[1]*ux*uy + ma[2]*ux*uz + ma[4]*uy*uz);
+          if ( d2 < dmi ) {
+            iadr = (ip1-1)*sol->offset + 1;
+            mb = &sol->met[iadr];
+            d2 =      mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \
+               + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz);
+            if ( d2 < dmi )  return(0);
+          }
+        }
+      }
+
+  return(1);
+}
+
+
+int MMG_buckin_iso(pMesh mesh,pSol sol,pBucket bucket,int ip) {
+  pPoint	ppt,pp1;
+  double	dd,d2,ux,uy,uz,hpi,hp1,hp2;
+  int		i,j,k,ii,jj,kk,ic,icc,siz,ip1;
+  int 		imin,imax,jmin,jmax,kmin,kmax;
+
+  ppt = &mesh->point[ip];
+  siz = bucket->size;
+  dd  = siz / (double)PRECI;
+  hpi = LFILT * sol->met[ip];
+  hp1 = hpi*hpi;
+
+  ii = M_MAX(0,(int)(dd * ppt->c[0])-1);
+  jj = M_MAX(0,(int)(dd * ppt->c[1])-1);
+  kk = M_MAX(0,(int)(dd * ppt->c[2])-1);
+  ic = (kk*siz + jj)*siz + ii;
+
+  /* check current cell */
+  if ( bucket->head[ic] ) {
+    ip1 = bucket->head[ic];
+    pp1 = &mesh->point[ip1];
+    hp2 = LFILT * sol->met[ip1];
+    ux = pp1->c[0] - ppt->c[0];
+    uy = pp1->c[1] - ppt->c[1];
+    uz = pp1->c[2] - ppt->c[2];
+    d2 = ux*ux + uy*uy + uz*uz;
+    if ( d2 < hp1 || d2 < hp2*hp2 )  {
+//printf("filtre current %d : %e %e %e %e\n",ip1,d2,hp1,d2,hp2*hp2);
+      return(0);
+    }
+
+    while ( bucket->link[ip1] ) {
+      ip1 = bucket->link[ip1];
+      pp1 = &mesh->point[ip1];
+      hp2 = LFILT * sol->met[ip1];
+      ux = pp1->c[0] - ppt->c[0];
+      uy = pp1->c[1] - ppt->c[1];
+      uz = pp1->c[2] - ppt->c[2];
+      d2 = ux*ux + uy*uy + uz*uz;
+      if ( d2 < hp1 || d2 < hp2*hp2 )  {
+//printf("filtre link %d : %e %e %e %e\n",ip1,d2,hp1,d2,hp2*hp2);
+        return(0);
+      }
+    }
+  }
+
+  /* explore neighbors */
+  imin = (int)(dd * (ppt->c[0]-hpi))-1;
+  jmin = (int)(dd * (ppt->c[1]-hpi))-1;
+  kmin = (int)(dd * (ppt->c[2]-hpi))-1;
+  imax = (int)(dd * (ppt->c[0]+hpi))-1;
+  jmax = (int)(dd * (ppt->c[1]+hpi))-1;
+  kmax = (int)(dd * (ppt->c[2]+hpi))-1;
+
+  imin = M_MAX(0,M_MIN(imin,siz-1));
+  imax = M_MIN(siz-1,M_MAX(0,imax));
+  jmin = M_MAX(0,M_MIN(jmin,siz-1));
+  jmax = M_MIN(siz-1,M_MAX(0,jmax));
+  kmin = M_MAX(0,M_MIN(kmin,siz-1));
+  kmax = M_MIN(siz-1,M_MAX(0,kmax));
+  if ( imin == imax && jmin == jmax && kmin == kmax )  return(1);
+
+  for (k=kmin; k<=kmax; k++)
+    for (j=jmin; j<=jmax; j++) 
+      for (i=imin; i<=imax; i++) {
+        icc = (k*siz + j)*siz + i;
+        ip1 = bucket->head[icc];
+        if ( !ip1 )  continue;
+        pp1 = &mesh->point[ip1];
+        hp2 = LFILT * sol->met[ip1];
+        ux = pp1->c[0] - ppt->c[0];
+        uy = pp1->c[1] - ppt->c[1];
+        uz = pp1->c[2] - ppt->c[2];
+        d2 = ux*ux + uy*uy + uz*uz;
+        if ( d2 < hp1 || d2 < hp2*hp2 ) {
+/*	 printf("other cell %d %e < %e -- %e < %e \n",ip1,d2,MMG_length(mesh,sol,ip,ip1),d2,hp2*hp2);
+	 printf("on filtre avec %d : %e %e %e\n",ip1,pp1->c[0],pp1->c[1],pp1->c[2]);
+	*/ return(0);
+	}
+
+        while ( bucket->link[ip1] ) {
+          ip1 = bucket->link[ip1];
+          pp1 = &mesh->point[ip1];
+          hp2 = LFILT * sol->met[ip1];
+          ux = pp1->c[0] - ppt->c[0];
+          uy = pp1->c[1] - ppt->c[1];
+          uz = pp1->c[2] - ppt->c[2];
+          d2 = ux*ux + uy*uy + uz*uz;
+          if ( d2 < hp1 || d2 < hp2*hp2 )  {
+//	    printf("link cell %d %e < %e -- %e < %e \n",ip1,d2,hp1,d2,hp2*hp2);
+	    return(0);
+	  }
+        }
+      }
+
+  return(1);
+}
+
+
+int MMG_addBucket(pMesh mesh,pBucket bucket,int ip) {
+  pPoint	ppt;
+  double	dd;
+  int		ic,ii,jj,kk,siz;
+
+  ppt = &mesh->point[ip];
+  siz = bucket->size;
+  dd  = siz / (double)PRECI;
+
+  ii = M_MAX(0,(int)(dd * ppt->c[0])-1);
+  jj = M_MAX(0,(int)(dd * ppt->c[1])-1);
+  kk = M_MAX(0,(int)(dd * ppt->c[2])-1);
+  ic = (kk*siz + jj)*siz + ii;
+
+  /* store new point */
+  if ( !bucket->head[ic] ) {
+    bucket->head[ic] = ip;
+    bucket->link[ip] = 0;
+  }
+  else {
+    bucket->link[ip] = bucket->head[ic];
+    bucket->head[ic] = ip;
+    assert(ip!=bucket->link[ip]);
+  }
+
+  return(1);
+}
+
+
+int MMG_delBucket(pMesh mesh,pBucket bucket,int ip) {
+  pPoint	ppt;
+  double	dd;
+  int		ic,ii,jj,kk,siz,ip1;
+
+  ppt = &mesh->point[ip];
+  siz = bucket->size;
+  dd  = siz / (double)PRECI;
+
+  ii = M_MAX(0,(int)(dd * ppt->c[0])-1);
+  jj = M_MAX(0,(int)(dd * ppt->c[1])-1);
+  kk = M_MAX(0,(int)(dd * ppt->c[2])-1);
+  ic = (kk*siz + jj)*siz + ii;
+
+  /* remove vertex from cell */
+  if ( bucket->head[ic] ) {
+    if ( bucket->head[ic] == ip ) {
+      bucket->head[ic] = bucket->link[ip];
+      bucket->link[ip] = 0;
+    }
+    else {
+      ip1 = bucket->head[ic];
+      while ( ip1 && bucket->link[ip1] != ip ) {
+        ip1 = bucket->link[ip1];
+      }
+      if ( bucket->link[ip1] == ip ) {
+        bucket->link[ip1] = bucket->link[ip];
+        bucket->link[ip] = 0;
+      }
+    }
+  }
+
+  return(1);
+}
+
diff --git a/contrib/mmg3d/build/sources/cendel.c b/contrib/mmg3d/build/sources/cendel.c
new file mode 100644
index 0000000000000000000000000000000000000000..41eab921bb762dfdfd1b3d6df1780d83ddbeafb7
--- /dev/null
+++ b/contrib/mmg3d/build/sources/cendel.c
@@ -0,0 +1,222 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+#define SCRIT    0.95
+
+
+int MMG_cendel(pMesh mesh,pSol sol,double declic,int base) {
+  pTetra	pt,pt1;
+  pQueue	queue;
+  List		list;
+  double	crit;
+  int		*adja,adj,iadr,ier,i,j,k,jel,lon,ns,np;
+  int		vois[4],ref,tag;
+  char		tabar,done;
+
+  /* queue on quality */
+  queue = MMG_kiuini(mesh,mesh->nemax,declic,base - 1);
+  assert(queue);
+
+  ns = np = 0;
+  do {
+    k = MMG_kiupop(queue);
+    if ( !k )  break;
+    np++;
+
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+    else if ( pt->flag < base - 1) continue;
+    else if ( pt->qual < declic ) continue;
+    
+    /* mark internal edges */
+    tabar  = 0;
+    iadr  = 4*(k-1) + 1;
+    adja  = &mesh->adja[iadr];
+    vois[0]  = adja[0] >> 2;
+    vois[1]  = adja[1] >> 2;
+    vois[2]  = adja[2] >> 2;
+    vois[3]  = adja[3] >> 2;
+    for (i=0; i<4; i++) {
+      adj = vois[i];
+      ref    = mesh->tetra[adj].ref;
+      tag    = mesh->tetra[adj].flag;
+      if ( !adj || pt->ref != ref ) {
+        tabar |= 1 << MMG_iarf[i][0];
+        tabar |= 1 << MMG_iarf[i][1];
+        tabar |= 1 << MMG_iarf[i][2];
+      }
+    }
+    if ( (tabar == ALL_BDRY) )  continue;
+    
+    /* swap for anisotropy */
+    done = 0;  
+    for (i=0; i<6; i++) { 
+      if ( (tabar & 1<<i) )  continue;
+
+      lon  = MMG_coquil(mesh,k,i,&list);
+      if ( lon < 3 || lon > 7 )  continue;
+
+      /* qual crit */
+      crit = pt->qual;
+      for (j=2; j<=lon; j++) {
+        jel  = list.tetra[j] / 6;
+        pt1  = &mesh->tetra[jel];
+        crit = M_MAX(crit,pt1->qual);
+      }
+      crit *= SCRIT; 
+      
+      ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,declic); 
+      if ( ier > 0 ) {
+        ns++;
+        break;
+      }
+      else if ( ier < 0 ) {
+        fprintf(stdout,"     %7d PROPOSED  %7d SWAPPED\n",np,ns);
+        fprintf(stdout,"  ## UNABLE TO SWAP.\n");
+        MMG_kiufree(queue);
+	    return(-ns);
+      } 
+    }
+  }
+  while ( k );
+
+  if ( mesh->info.imprim < - 4 )
+    fprintf(stdout,"     %7d PROPOSED  %7d SWAPPED\n",np,ns);
+
+  MMG_kiufree(queue);
+  return(ns);
+}
+
+int MMG_cendellong(pMesh mesh,pSol sol,double declic,int base) {
+  pTetra	pt,pt1;
+  pQueue	queue;
+  List		list;
+  double	crit,cal;
+  int		*adja,adj,iadr,ier,i,j,k,jel,lon,ns,np;
+  int		vois[4],ref,tag;
+  char		tabar,done;
+  int imin,jj;
+  /* queue on quality */
+  queue = MMG_kiuini(mesh,mesh->nemax,declic,base - 1);
+  assert(queue);
+
+  ns = np = 0;
+  do {
+    k = MMG_kiupop(queue);
+    if ( !k )  break;
+    np++;
+
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+    else if ( pt->flag < base - 1) continue;
+    else if ( pt->qual < declic ) continue;
+    
+    /* mark internal edges */
+    tabar  = 0;
+    iadr  = 4*(k-1) + 1;
+    adja  = &mesh->adja[iadr];
+    vois[0]  = adja[0] >> 2;
+    vois[1]  = adja[1] >> 2;
+    vois[2]  = adja[2] >> 2;
+    vois[3]  = adja[3] >> 2;
+    for (i=0; i<4; i++) {
+      adj = vois[i];
+      ref    = mesh->tetra[adj].ref;
+      tag    = mesh->tetra[adj].flag;
+      if ( !adj || pt->ref != ref ) {
+        tabar |= 1 << MMG_iarf[i][0];
+        tabar |= 1 << MMG_iarf[i][1];
+        tabar |= 1 << MMG_iarf[i][2];
+      }
+    }
+    if ( (tabar == ALL_BDRY) )  continue;
+    
+    /* swap for anisotropy */
+    done = 0;  
+    imin = ((int) pt->qual)%6;
+    for (jj=imin; jj<imin+6; jj++) { 
+      i=jj%6;
+      if ( (tabar & 1<<i) )  continue;
+
+      lon  = MMG_coquil(mesh,k,i,&list);
+      if ( lon < 3 || lon > 7 )  continue;
+      //printf("on essaie de swapper %d\n",k); 
+
+      /* qual crit */
+      crit = ( sol->offset==6 ) ? MMG_caltet_ani(mesh,sol,k):MMG_caltet_iso(mesh,sol,k) ; //pt->qual;
+      for (j=2; j<=lon; j++) {
+        jel  = list.tetra[j] / 6;
+        pt1  = &mesh->tetra[jel]; 
+        cal  = ( sol->offset==6 ) ? MMG_caltet_ani(mesh,sol,jel):MMG_caltet_iso(mesh,sol,jel) ;
+        crit = M_MAX(crit,cal);
+      }
+      crit *= SCRIT; 
+      //printf("$$$$$$$$$$$$$ crit %e %e\n",crit,crit/60.); 
+      
+      ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,declic); 
+      //printf("swap ? %d\n",ier);
+      if ( ier > 0 ) {
+        ns++;
+        break;
+      }
+      else if ( ier < 0 ) {
+        fprintf(stdout,"     %7d PROPOSED  %7d SWAPPED\n",np,ns);
+        fprintf(stdout,"  ## UNABLE TO SWAP.\n");
+        MMG_kiufree(queue);
+	    return(-ns);
+      } 
+    }
+  }
+  while ( k );
+
+  if ( mesh->info.imprim < - 4 )
+    fprintf(stdout,"     %7d PROPOSED  %7d SWAPPED\n",np,ns);
+
+  MMG_kiufree(queue);
+  return(ns);
+}
+
diff --git a/contrib/mmg3d/build/sources/cenrad.c b/contrib/mmg3d/build/sources/cenrad.c
new file mode 100644
index 0000000000000000000000000000000000000000..3a3921eaaacb10d7e887ec55a425c9cf02fca9ad
--- /dev/null
+++ b/contrib/mmg3d/build/sources/cenrad.c
@@ -0,0 +1,182 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+/* compute circumradius and center */
+int MMG_cenrad_iso(pMesh mesh,double *ct,double *c,double *rad) {
+  double      dd,ux,uy,uz,n1[3],n2[3],n3[3],*c1,*c2,*c3,*c4,pl1,pl2,pl3;
+  double      cc1,cc2,cc3;
+
+  c1 = &ct[0];
+  c2 = &ct[3];
+  c3 = &ct[6];
+  c4 = &ct[9];
+
+  ux = c4[0] - c1[0];
+  uy = c4[1] - c1[1];
+  uz = c4[2] - c1[2];
+  dd = 1.0 / sqrt(ux*ux + uy*uy + uz*uz);
+  n1[0] = ux*dd;
+  n1[1] = uy*dd;
+  n1[2] = uz*dd;
+
+  /* plan: vecteur directeur passant par milieu(1,4) */
+  pl1 = n1[0]*(c4[0]+c1[0]) \
+      + n1[1]*(c4[1]+c1[1]) + n1[2]*(c4[2]+c1[2]);
+
+  ux = c4[0] - c2[0];
+  uy = c4[1] - c2[1];
+  uz = c4[2] - c2[2];
+  dd = 1.0 / sqrt(ux*ux + uy*uy + uz*uz);
+  n2[0] = ux*dd;
+  n2[1] = uy*dd;
+  n2[2] = uz*dd;
+  pl2 = n2[0]*(c4[0]+c2[0]) \
+      + n2[1]*(c4[1]+c2[1]) + n2[2]*(c4[2]+c2[2]);
+
+  ux = c4[0] - c3[0];
+  uy = c4[1] - c3[1];
+  uz = c4[2] - c3[2];
+  dd = 1.0 / sqrt(ux*ux + uy*uy + uz*uz);
+  n3[0] = ux*dd;
+  n3[1] = uy*dd;
+  n3[2] = uz*dd;
+  pl3 = n3[0]*(c4[0]+c3[0]) \
+      + n3[1]*(c4[1]+c3[1]) + n3[2]*(c4[2]+c3[2]);
+
+  /* center = intersection of 3 planes */
+  ux = n2[1]*n3[2] - n2[2]*n3[1];
+  uy = n1[2]*n3[1] - n1[1]*n3[2];
+  uz = n1[1]*n2[2] - n1[2]*n2[1];
+
+  dd = n1[0]*ux + n2[0]*uy + n3[0]*uz;
+  dd = 0.5 / dd;
+
+  cc1 = ux*pl1 + uy*pl2 + uz*pl3;
+  cc2 = pl1 * (n2[2]*n3[0] - n2[0]*n3[2]) \
+     + pl2 * (n1[0]*n3[2] - n3[0]*n1[2]) \
+     + pl3 * (n2[0]*n1[2] - n2[2]*n1[0]);
+  cc3 = pl1 * (n2[0]*n3[1] - n2[1]*n3[0]) \
+     + pl2 * (n3[0]*n1[1] - n3[1]*n1[0]) \
+     + pl3 * (n1[0]*n2[1] - n2[0]*n1[1]);
+
+  c[0] = dd * cc1;
+  c[1] = dd * cc2;
+  c[2] = dd * cc3;
+
+  /* radius (squared) */
+  *rad = (c[0] - c4[0]) * (c[0] - c4[0]) \
+       + (c[1] - c4[1]) * (c[1] - c4[1]) \
+       + (c[2] - c4[2]) * (c[2] - c4[2]);
+
+  return(1);
+}
+
+
+int MMG_cenrad_ani(pMesh mesh,double *ct,double *m,double *c,double *rad) {
+  double      d1,d2,d3,det,dd,ux,uy,uz,vx,vy,vz,wx,wy,wz;
+  double      ax,ay,az,bx,by,bz,cx,cy,cz;
+
+
+  dd =      m[0]*ct[0]*ct[0] + m[3]*ct[1]*ct[1] + m[5]*ct[2]*ct[2] \
+     + 2.0*(m[1]*ct[0]*ct[1] + m[2]*ct[0]*ct[2] + m[4]*ct[1]*ct[2]);
+
+  /* MMG_lengths */
+  d1 =      m[0]*ct[3]*ct[3] + m[3]*ct[4]*ct[4] + m[5]*ct[5]*ct[5] \
+     + 2.0*(m[1]*ct[3]*ct[4] + m[2]*ct[3]*ct[5] + m[4]*ct[4]*ct[5]) - dd;
+
+  d2 =      m[0]*ct[6]*ct[6] + m[3]*ct[7]*ct[7] + m[5]*ct[8]*ct[8] \
+     + 2.0*(m[1]*ct[6]*ct[7] + m[2]*ct[6]*ct[8] + m[4]*ct[7]*ct[8]) - dd;
+
+  d3 =      m[0]*ct[9]*ct[9] + m[3]*ct[10]*ct[10] + m[5]*ct[11]*ct[11] \
+     + 2.0*(m[1]*ct[9]*ct[10] + m[2]*ct[9]*ct[11] + m[4]*ct[10]*ct[11]) - dd;
+
+  ux = ct[3] - ct[0];
+  uy = ct[4] - ct[1];
+  uz = ct[5] - ct[2];
+
+  vx = ct[6] - ct[0];
+  vy = ct[7] - ct[1];
+  vz = ct[8] - ct[2];
+
+  wx = ct[9] - ct[0];
+  wy = ct[10] - ct[1];
+  wz = ct[11] - ct[2];
+
+  /* M.u */
+  ax = m[0]*ux + m[1]*uy + m[2]*uz;
+  ay = m[1]*ux + m[3]*uy + m[4]*uz;
+  az = m[2]*ux + m[4]*uy + m[5]*uz;
+
+  bx = m[0]*vx + m[1]*vy + m[2]*vz;
+  by = m[1]*vx + m[3]*vy + m[4]*vz;
+  bz = m[2]*vx + m[4]*vy + m[5]*vz;
+
+  cx = m[0]*wx + m[1]*wy + m[2]*wz;
+  cy = m[1]*wx + m[3]*wy + m[4]*wz;
+  cz = m[2]*wx + m[4]*wy + m[5]*wz;
+
+  /* center */
+  c[0] = d1 *(by*cz - bz*cy) - d2 * (ay*cz - az*cy) + d3 * (ay*bz - az*by); 
+  c[1] = d1 *(bz*cx - bx*cz) - d2 * (az*cx - ax*cz) + d3 * (az*bx - ax*bz);
+  c[2] = d1 *(bx*cy - by*cx) - d2 * (ax*cy - ay*cx) + d3 * (ax*by - ay*bx);
+
+  det = ax * (by*cz - bz*cy) - ay * (bx*cz - bz*cx) + az * (bx*cy - cx*by);
+  det = 1.0 / (2.0*det);
+
+  c[0] *= det;
+  c[1] *= det;
+  c[2] *= det;
+
+  /* radius (squared) */
+  ux = ct[0] - c[0];
+  uy = ct[1] - c[1];
+  uz = ct[2] - c[2];
+  *rad =      m[0]*ux*ux + m[3]*uy*uy + m[5]*uz*uz \
+       + 2.0*(m[1]*ux*uy + m[2]*ux*uz + m[4]*uy*uz);
+
+  return(1);
+}
diff --git a/contrib/mmg3d/build/sources/chkmsh.c b/contrib/mmg3d/build/sources/chkmsh.c
new file mode 100644
index 0000000000000000000000000000000000000000..1b492fdb88a83daed2b805f31581786335b70ed4
--- /dev/null
+++ b/contrib/mmg3d/build/sources/chkmsh.c
@@ -0,0 +1,182 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+#define  EPSLOC   1.00005
+
+
+int MMG_chkmsh(pMesh mesh,int severe,int base) {
+  pPoint	ppt;
+  pTetra	pt1,pt2;
+  List		list;
+  int		*adja,*adja1,adj,adj1,k,kk,l,nk,i,j,ip,iadr,lon,len;
+  unsigned char	voy,voy1;
+
+  for (k=1; k<=mesh->ne; k++) {
+    pt1 = &mesh->tetra[k];
+    if ( !pt1->v[0] )  continue;
+    iadr = (k-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    for (i=0; i<4; i++) {
+      adj = adja[i] / 4;
+      voy = adja[i] % 4;
+      if ( !adj )  continue;
+
+      if ( adj == k ) {
+        fprintf(stdout,"  1. Wrong adjacency %d %d\n",k,adj);
+	printf("k %d: %d %d %d %d\n",k,pt1->v[0],pt1->v[1],pt1->v[2],pt1->v[3]);
+	printf("adj (%d): %d %d %d %d\n",
+	       k,adja[0]/4,adja[1]/4,adja[2]/4,adja[3]/4);
+	exit(1);
+      }
+      pt2 = &mesh->tetra[adj];
+      if ( !pt2->v[0] ) {
+        fprintf(stdout,"  4. Invalid adjacent %d %d\n",adj,k);
+	printf("sommets k   %d: %d %d %d %d\n",
+	       k,pt1->v[0],pt1->v[1],pt1->v[2],pt1->v[3]);
+	printf("sommets adj %d: %d %d %d %d\n",
+	adj,pt2->v[0],pt2->v[1],pt2->v[2],pt2->v[3]);
+	printf("numeros adj %d: %d %d %d %d\n",k,adja[0]/4,adja[1]/4,adja[2]/4,adja[3]/4);
+	exit(1);
+      }
+      iadr  = (adj-1)*4 + 1;
+      adja1 = &mesh->adja[iadr];   
+      adj1  = adja1[voy] / 4;
+      voy1  = adja1[voy] % 4;
+      if ( adj1 != k || voy1 != i ) {
+        fprintf(stdout,"  2. Wrong adjacency %d %d\n",k,adj1);
+	printf("k %d: %d %d %d %d\n",k,pt1->v[0],pt1->v[1],pt1->v[2],pt1->v[3]);
+	printf("a %d: %d %d %d %d\n",
+	       adj,pt2->v[0],pt2->v[1],pt2->v[2],pt2->v[3]);
+	printf("adj(%d): %d %d %d %d\n",
+	       k,adja[0]/4,adja[1]/4,adja[2]/4,adja[3]/4);
+	printf("adj(%d): %d %d %d %d\n",
+	      adj,adja1[0]/4,adja1[1]/4,adja1[2]/4,adja1[3]/4);
+	exit(1);
+      }
+    }
+  }
+  
+  /* Delaunay criterion */
+/*
+  for (k=1; k<=mesh->ne; k++) {
+    pt1 = &mesh->tetra[k];
+    if ( !pt1->v[0] )  continue;
+    iadr = (k-1)*4 + 1; 
+    adja = &mesh->adja[iadr];
+    if ( !cenrad(mesh,k,c,&ray) )  continue;
+
+    for (i=0; i<4; i++) {
+      if ( !adja[i] )  continue;
+      adj = adja[i] / 4;
+      voy = adja[i] % 4;
+      pt2 = &mesh->tetra[adj];
+
+      ppt = &mesh->point[ pt2->v[voy] ];
+      dd = (ppt->c[0] - c[0]) * (ppt->c[0] - c[0]) \
+         + (ppt->c[1] - c[1]) * (ppt->c[1] - c[1]) \
+         + (ppt->c[2] - c[2]) * (ppt->c[2] - c[2]);
+      if ( EPSLOC*EPSLOC*dd < ray ) {
+        fprintf(stdout,"  ## Non-Delaunay mesh:  %.14f < %.14f\n",dd,ray);
+	exit(1);
+      }
+    }
+  }
+*/
+  
+  if ( !severe )  return(1);
+
+  for (k=1; k<=mesh->ne; k++) {
+    pt1 = &mesh->tetra[k];
+    if ( !pt1->v[0] )  continue;
+    else if (pt1->flag < base )  continue;
+    iadr = 4*(k-1) + 1;
+    adja = &mesh->adja[iadr];
+
+    for (i=0; i<4; i++) {
+      adj = (adja[i]-1) / 4 + 1;
+      voy = (adja[i]-1) % 4;
+      if ( !adj )  continue;
+
+      ip  = pt1->v[i];
+      ppt = &mesh->point[ip];
+      if ( ppt->tag & M_UNUSED ) {
+        fprintf(stdout,"  6. Unused vertex %d  %d\n",k,ip);
+	printf("%d %d %d %d\n",pt1->v[0],pt1->v[1],pt1->v[2],pt1->v[3]);
+	exit(1);
+      }
+      lon = MMG_boulep(mesh,k,i,&list);
+      for (l=1; l<=lon; l++) {
+        kk  = list.tetra[l] / 4;
+	nk  = list.tetra[l] % 4;
+	pt2 = &mesh->tetra[kk];
+	if ( pt2->v[nk] != ip ) {
+	  fprintf(stdout,"  5. Wrong ball %d, %d\n",ip,pt2->v[nk]);
+	  exit(1);
+	}
+      }
+      if ( lon < 1 )  continue;
+      len = 0;
+      for (kk=1; kk<=mesh->ne; kk++) {
+        pt2 = &mesh->tetra[kk];
+	if ( !pt2->v[0] )  continue;
+	for (j=0; j<4; j++)
+	  if ( pt2->v[j] == ip ) {
+	    len++;
+	    break;
+	  }
+      }
+      if ( len != lon ) {
+        fprintf(stdout,"  7. Incorrect ball %d: %d %d\n",pt1->v[i],lon,len);
+        exit(1);
+      }
+    }
+  }
+
+  /*fprintf(stdout,"  ** MESH STRUCTURE IS OK\n");*/
+  return(1);
+}
diff --git a/contrib/mmg3d/build/sources/chrono.c b/contrib/mmg3d/build/sources/chrono.c
new file mode 100644
index 0000000000000000000000000000000000000000..ba4482e177621116c9f4e9f2f0f0ceebe5fb0bae
--- /dev/null
+++ b/contrib/mmg3d/build/sources/chrono.c
@@ -0,0 +1,142 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+/* 
+ *  simulation of a chronograph
+ *  in : tim
+ *  out: tim.dtim = elapsed time in micro-secs
+ *       tim.ptim = elapsed time in secs
+ *       tim.call = number of calls
+ *
+ *  Written by Pascal J. Frey
+ *  email: Pascal.Frey@inria.fr, 1999
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <math.h>
+#include <stdlib.h>
+#include "chrono.h"
+
+
+/* return elapsed time in secs. */
+static double diftim(time_t t2,time_t t1) {
+  struct  tm  *ptm;
+  double  tim;
+  int     hh1,mm1,ss1,hh2,mm2,ss2;
+
+  ptm = localtime(&t1);
+  hh1 = ptm->tm_hour;
+  mm1 = ptm->tm_min;
+  ss1 = ptm->tm_sec;
+
+  ptm = localtime(&t2);
+  hh2 = ptm->tm_hour;
+  mm2 = ptm->tm_min;
+  ss2 = ptm->tm_sec;
+  if ( hh2 < hh1 )  hh2 += 24;
+  
+  tim  = 3600.0*(hh2-hh1);
+  tim += 60.0*(mm2-mm1);
+  tim += ss2-ss1;
+
+  return(tim);
+}
+
+
+/* get system and user times in micro-seconds */
+void  TIM_chrono(int cmode,TIM_mytime *ptt) {
+  time_t tt;
+
+  if ( cmode == RESET ) {
+    ptt->dtim  = clock();
+    ptt->ctim  = 0.0f;
+    ptt->ptim  = 0;
+    ptt->call  = 0;
+  }
+  else {
+    ptt->dtim = difftime(clock(),ptt->dtim);  /* in secs */
+    if ( cmode == ON ) {
+      ptt->ptim = time(NULL);
+      ptt->call++;
+    }
+    else if ( cmode == OFF ) {
+      tt = time(NULL);
+      ptt->ctim += diftim(tt,ptt->ptim);
+      ptt->ptim  = 0;
+    }
+  }
+}
+
+
+/* return time (converted in secs */
+double TIM_gttime(TIM_mytime t) {
+
+  if ( t.ctim < MAXCLK )
+    return(t.dtim / (double)CLOCKS_PER_SEC);
+  else
+    return(t.ctim);
+}
+
+
+/* initialize time table */
+void  TIM_tminit(TIM_mytime *t,int maxtim) {
+  int     k;
+
+  for (k=0; k<maxtim; k++) {
+    t[k].dtim = clock();
+    t[k].ptim = 0;
+    t[k].ctim = 0.0;
+    t[k].call = 0;
+  }
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/contrib/mmg3d/build/sources/chrono.h b/contrib/mmg3d/build/sources/chrono.h
new file mode 100644
index 0000000000000000000000000000000000000000..2df3774828a411dc353b775dd1c0dd0dc658a783
--- /dev/null
+++ b/contrib/mmg3d/build/sources/chrono.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <time.h>
+
+#ifndef  ON
+#define  RESET  0
+#define  ON     1
+#define  OFF    2
+#endif
+
+#define  TIMEMAX   16
+#define  MAXCLK    ( 1073741823. / (double)CLOCKS_PER_SEC )
+
+
+typedef struct TIM_mytime {
+  double    ctim,dtim;
+  time_t    ptim;
+  short     call;
+} TIM_mytime;
+
+
+/* prototypes */
+void   TIM_chrono(int cmode,TIM_mytime *ptt);
+double TIM_gttime(TIM_mytime t);
+void   TIM_tminit(TIM_mytime *t,int maxtim);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/contrib/mmg3d/build/sources/colpoi.c b/contrib/mmg3d/build/sources/colpoi.c
new file mode 100644
index 0000000000000000000000000000000000000000..52c23ad3c52599f3196cdd8cfc32d9eadb4958af
--- /dev/null
+++ b/contrib/mmg3d/build/sources/colpoi.c
@@ -0,0 +1,523 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+#define LLONG1  1.41//1.9//1.41
+
+int MMG_nlen,MMG_ncal,MMG_ntopo,MMG_nex;
+
+
+/* collapse edge b->a (i.e. remove b) */
+int MMG_colpoi(pMesh mesh,pSol sol,int iel,int ia,int ib,double coef) {
+  pTetra        pt,pt1;
+  pPoint        pa,pb,ppt;
+  double        coor[3],crit,cal;
+  double        solu[6],len,*ca,*cb,*ma,*mb;
+  int          *adja,*adja1,base,i,j,l,kk,nk,adj,voy,iadr,ik,ielv,lon,na,nb;
+  int           adj1,voy1,s1,iadb,iada,ipb,vois[4],vois1[4],ii,jj,iare1,iare2;
+  static List   list;
+
+  pt  = &mesh->tetra[iel];
+  lon = MMG_boulep(mesh,iel,ib,&list);
+  if ( lon < 1 )  return(0);
+  /* topological-geometric checks */
+  base = ++mesh->mark;
+  na = pt->v[ia];
+  nb = pt->v[ib];        
+  pa = &mesh->point[na];
+  pb = &mesh->point[nb];
+  ca = &pa->c[0];
+  
+  crit =  pt->qual;
+  for (l=2; l<=lon; l++) {
+    kk   = list.tetra[l] >> 2;
+    cal  = mesh->tetra[kk].qual;//(sol->offset==6) ? MMG_caltet_ani(mesh,sol,kk) : MMG_caltet_iso(mesh,sol,kk);
+    if ( cal > crit )  crit = cal;
+  }
+  crit *= coef; 
+  //assert(crit < 1e20);
+        
+  /* change coords of pb */
+  iada = (na-1)*sol->offset + 1;
+  ma   = &sol->met[iada];
+  iadb = (nb-1)*sol->offset + 1;
+  memcpy(coor, pb->c,3*sizeof(double));
+  memcpy(pb->c,pa->c,3*sizeof(double));
+  memcpy(solu,&sol->met[iadb],sol->offset*sizeof(double));
+  memcpy(&sol->met[iadb],&sol->met[iada],sol->offset*sizeof(double));
+
+  /* avoid recreating existing elt */
+  for (l=1; l<=lon; l++) {
+    if ( list.tetra[l] < 0 )  continue;
+    kk = list.tetra[l] >> 2;
+    nk = list.tetra[l] % 4;
+
+    pt1 = &mesh->tetra[kk];
+    s1  = pt1->v[0];
+
+    iadr = (kk-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adj  = adja[nk] >> 2;
+    if ( !adj )  continue;
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    vois[0]  = adja[0] >> 2;
+    vois[1]  = adja[1] >> 2;
+    vois[2]  = adja[2] >> 2;
+    vois[3]  = adja[3] >> 2;
+    for (j=0; j<4; j++) 
+      if ( vois[j] == kk ) {
+        pt1 = &mesh->tetra[adj];
+	      s1  = pt1->v[j];
+	      break;
+      }
+    if ( s1 == na ) {
+      MMG_nex++;
+      memcpy(pb->c,coor,3*sizeof(double));
+      memcpy(&sol->met[iadb],solu,sol->offset*sizeof(double));
+      return(0);
+    }
+  }
+
+  /* topological check */
+  for (l=1; l<=lon; l++) {
+    kk = list.tetra[l] >> 2;
+    nk = list.tetra[l] % 4;
+    /* mark elts of shell a-b */
+    pt1 = &mesh->tetra[kk];
+    for (i=0; i<4; i++) {
+      if ( pt1->v[i] == na ) {
+        list.tetra[l] = -list.tetra[l];
+	    pt1->mark     = base;
+	    break;
+      }
+    }
+    
+
+    if ( pt1->mark == base )   continue;
+    /* check lengths */
+    for (i=0; i<3; i++) {
+      ipb  = pt1->v[ MMG_idir[nk][i] ];
+      ppt  = &mesh->point[ipb];
+      cb   = &ppt->c[0];
+      iadr = (ipb-1)*sol->offset + 1;
+      mb   = &sol->met[iadr];   
+      // if(cal < 1e-10) printf("(%e) long %d : %e\n",cal,i,MMG_length(ca,cb,ma,mb),crit/60.);
+      if ( ppt->mark < base ) {
+        len = MMG_length(ca,cb,ma,mb);   
+        if ( len > crit/60. ) {
+          MMG_nlen++;
+          memcpy(pb->c,coor,3*sizeof(double));
+          memcpy(&sol->met[iadb],solu,sol->offset*sizeof(double));
+          //printf("len reject %e %e\n",len,LLONG1);
+          return(0);
+        }
+        ppt->mark = base;
+      }
+    }
+
+    /* check volume of remaining elt */
+    cal =  MMG_voltet(mesh,kk);//(sol->offset==6) ? MMG_caltet_ani(mesh,sol,iel) : MMG_caltet_iso(mesh,sol,iel); 
+    list.qual[l] = MMG_caltet(mesh,sol,kk); 
+    //if( cal < 1e-10 && cal >= 1e-15) printf("cal : %e %e\n",cal,MMG_caltet_ani(mesh,sol,kk));
+    if ( cal < 1e-10/*crit*/ ) {
+      MMG_ncal++;
+      memcpy(pb->c,coor,3*sizeof(double));
+      memcpy(&sol->met[iadb],solu,sol->offset*sizeof(double));  
+//printf("cal reject\n");
+      return(0);
+    }
+    
+  }
+  /* verif topo */ 
+  for (l=1; l<=lon; l++) {
+    ik  = abs(list.tetra[l]);
+    kk  = ik >> 2;
+    nk  = ik % 4;
+    pt1 = &mesh->tetra[kk];
+    if ( pt1->mark != base )  continue;
+
+    iadr = (kk-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    ielv = adja[nk] >> 2;
+    vois[0]  = adja[0] >> 2;
+    vois[1]  = adja[1] >> 2;
+    vois[2]  = adja[2] >> 2;
+    vois[3]  = adja[3] >> 2;
+
+    for (i=0; i<4; i++) {
+      if ( i == nk )  continue;
+      adj = vois[i];
+      pt1 = &mesh->tetra[adj];
+      if ( pt1->mark == base )  continue;
+      adja1 = &mesh->adja[ (adj-1)*4 + 1 ];
+      vois1[0]  = adja1[0] >> 2;
+      vois1[1]  = adja1[1] >> 2;
+      vois1[2]  = adja1[2] >> 2;
+      vois1[3]  = adja1[3] >> 2;
+      for (j=0; j<4; j++) {
+        adj1 = vois1[j];
+        if ( pt1->v[j] == nb && adj1 == ielv ) {
+	        MMG_ntopo++;
+          memcpy(pb->c,coor,3*sizeof(double));
+          memcpy(&sol->met[iadb],solu,sol->offset*sizeof(double));
+	        return(0);
+	      }
+      }
+    }
+  }
+   
+  /* update topo: shell */
+  for (l=1; l<=lon; l++) {
+    if ( list.tetra[l] > 0 )  continue;
+
+    kk = -list.tetra[l] >> 2;
+    nk = -list.tetra[l] % 4;
+
+    pt1 = &mesh->tetra[kk];
+    pt1->qual = list.qual[l];
+    iadr = (kk-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adj  = adja[nk] >> 2;
+    voy  = adja[nk] % 4;
+    adj1 = 0;
+    voy1 = 0;
+    for (j=0; j<4; j++) {
+      if ( pt1->v[j] == na ) {
+        adj1 = adja[j] >> 2;
+	      voy1 = adja[j] % 4;
+        if ( adj1 ) {
+	        iadr = (adj1-1)*4 + 1;
+          adja = &mesh->adja[iadr];
+          adja[voy1] = 4*adj + voy;
+          mesh->tetra[adj1].bdryref[voy1] = pt1->bdryref[nk]; 
+          for(ii=0 ; ii<3 ; ii++) {
+						if(!pt1->bdryinfo[MMG_iarf[nk][ii]]) continue;    
+						iare1 = pt1->v[MMG_iare[MMG_iarf[nk][ii]][0]];
+						iare2 = pt1->v[MMG_iare[MMG_iarf[nk][ii]][1]]; 
+						if(iare1==na) {
+							iare1=nb;  
+						} else if(iare2==na) {
+							iare2=nb;         
+						}
+						else {
+						  continue;
+						}
+						for(jj=0 ; jj<3 ; jj++) {  
+							// printf("iare %d %d -- %d %d\n",iare1,iare2,mesh->tetra[adj1].v[MMG_iare[MMG_iarf[voy1][jj]][0]],
+							// 	mesh->tetra[adj1].v[MMG_iare[MMG_iarf[voy1][jj]][1]]);
+							if((iare1==mesh->tetra[adj1].v[MMG_iare[MMG_iarf[voy1][jj]][0]] &&
+								  iare2==mesh->tetra[adj1].v[MMG_iare[MMG_iarf[voy1][jj]][1]]) ||
+								 (iare2==mesh->tetra[adj1].v[MMG_iare[MMG_iarf[voy1][jj]][0]] &&
+									iare1==mesh->tetra[adj1].v[MMG_iare[MMG_iarf[voy1][jj]][1]])) {
+										mesh->tetra[adj1].bdryinfo[MMG_iarf[voy1][jj]] = pt1->bdryinfo[MMG_iarf[nk][ii]];     
+										break; 		
+							}
+						}
+						assert(jj<3);
+					}
+					
+	      }
+	      break;
+      }
+    }
+    if ( adj ) {
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[voy] = 4*adj1 + voy1;
+      if(!adj1) { 
+        mesh->tetra[adj].bdryref[voy] = pt1->bdryref[j];
+        for(ii=0 ; ii<3 ; ii++) {
+			  	if(!pt1->bdryinfo[MMG_iarf[j][ii]]) continue;
+			  	iare1 = pt1->v[MMG_iare[MMG_iarf[j][ii]][0]];
+			  	iare2 = pt1->v[MMG_iare[MMG_iarf[j][ii]][1]]; 
+			  	if(iare1==na) {
+			  		iare1=nb;  
+			  	} else if(iare2==na)
+			  		iare2=nb;
+			  	else
+			  	  continue; 
+			  	for(jj=0 ; jj<3 ; jj++) {  
+			  		// printf("iare %d %d -- %d %d\n",iare1,iare2,mesh->tetra[adj1].v[MMG_iare[MMG_iarf[voy1][jj]][0]],
+			  		// 	mesh->tetra[adj1].v[MMG_iare[MMG_iarf[voy1][jj]][1]]);
+			  		if((iare1==mesh->tetra[adj].v[MMG_iare[MMG_iarf[voy][jj]][0]] &&
+			  			  iare2==mesh->tetra[adj].v[MMG_iare[MMG_iarf[voy][jj]][1]]) ||
+			  			 (iare2==mesh->tetra[adj].v[MMG_iare[MMG_iarf[voy][jj]][0]] &&
+			  				iare1==mesh->tetra[adj].v[MMG_iare[MMG_iarf[voy][jj]][1]])) {
+			  					mesh->tetra[adj1].bdryinfo[MMG_iarf[voy1][jj]] = pt1->bdryinfo[j];    
+			  					break; 		
+			  		}
+			  	}
+			  	assert(jj<3);
+			  }  
+			}  
+		}
+    MMG_delElt(mesh,kk);
+  }
+
+  /* update topo: ball */
+  for (l=1; l<=lon; l++) {
+    if ( list.tetra[l] < 0 )  continue;
+    kk  = list.tetra[l] >> 2;
+    nk  = list.tetra[l] % 4;
+    pt1 = &mesh->tetra[kk];  
+    pt1->v[nk] = na;
+    pt1->flag  = mesh->flag;
+    pt1->qual  = list.qual[l];
+    pt1->edge &= ~(1 << MMG_arpt[nk][0]);
+    pt1->edge &= ~(1 << MMG_arpt[nk][1]);
+    pt1->edge &= ~(1 << MMG_arpt[nk][2]);
+  }
+
+  /* delete vertex */
+  memcpy(pb->c,coor,3*sizeof(double));
+  pa->mark = mesh->flag;
+
+  return(1);
+}
+/* collapse edge b->a (i.e. remove b) */
+int MMG_colpoi2(pMesh mesh,pSol sol,int iel,int ia,int ib,double coef) {
+  pTetra        pt,pt1;
+  pPoint        pa,pb,ppt;
+  double        coor[3],crit,cal,len;
+  double         solu[6],*ca,*cb,*ma,*mb;
+  int          *adja,*adja1,base,i,j,l,kk,nk,adj,voy,iadr,ik,ielv,lon,na,nb;
+  int           adj1,voy1,s1,ipb,iadb,iada;
+  static List   list;
+
+  pt  = &mesh->tetra[iel];
+  lon = MMG_boulep(mesh,iel,ib,&list);
+  if ( lon < 1 )  return(0);
+
+  /* topological-geometric checks */
+  base = ++mesh->mark;
+  na = pt->v[ia];
+  nb = pt->v[ib];
+  pa = &mesh->point[na];
+  pb = &mesh->point[nb];
+  ca = &pa->c[0];
+
+  crit = pt->qual;
+  for (l=2; l<=lon; l++) {
+    kk   = list.tetra[l] >> 2;
+    cal  = MMG_caltet(mesh,sol,kk);
+    if ( cal > crit )  crit = cal;
+  }
+  crit *= coef;
+
+  /* change coords of pb */
+  iada = (na-1)*sol->offset + 1;
+  ma   = &sol->met[iada];
+  iadb = (nb-1)*sol->offset + 1;
+  memcpy(coor, pb->c,3*sizeof(double));
+  memcpy(pb->c,pa->c,3*sizeof(double));
+  memcpy(solu,&sol->met[iadb],sol->offset*sizeof(double));
+  memcpy(&sol->met[iadb],&sol->met[iada],sol->offset*sizeof(double));
+
+  /* avoid recreating existing elt */
+  for (l=1; l<=lon; l++) {
+    if ( list.tetra[l] < 0 )  continue;
+    kk = list.tetra[l] >> 2;
+    nk = list.tetra[l] % 4;
+
+    pt1 = &mesh->tetra[kk];
+    s1  = pt1->v[0];
+
+    iadr = (kk-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adj  = adja[nk] >> 2;
+    if ( !adj )  continue;
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    for (j=0; j<4; j++) 
+      if ( adja[j]/4 == kk ) {
+        pt1 = &mesh->tetra[adj];
+	      s1  = pt1->v[j];
+	      break;
+      }
+    if ( s1 == na ) {
+      MMG_nex++;
+      memcpy(pb->c,coor,3*sizeof(double));
+      memcpy(&sol->met[iadb],solu,sol->offset*sizeof(double));
+      return(0);
+    }
+  }
+
+  /* topological check */
+  for (l=1; l<=lon; l++) {
+    kk = list.tetra[l] >> 2;
+    nk = list.tetra[l] % 4;
+
+    /* mark elts of shell a-b */
+    pt1 = &mesh->tetra[kk];
+    for (i=0; i<4; i++) {
+      if ( pt1->v[i] == na ) {
+        list.tetra[l] = -list.tetra[l];
+	      pt1->mark     = base;
+	      break;
+      }
+    }
+    /* check volume of remaining elt */
+    if ( pt1->mark == base )   continue;
+    cal = MMG_caltet(mesh,sol,kk);
+    list.qual[l] = cal;
+    if ( cal > crit ) {
+      MMG_ncal++;
+      memcpy(pb->c,coor,3*sizeof(double));
+      memcpy(&sol->met[iadb],solu,sol->offset*sizeof(double));
+//printf("bad quality : %f > %f\n",cal,crit);
+      return(0);
+    }
+    
+    /* check lengths */
+    for (i=0; i<3; i++) {
+      ipb = pt1->v[ MMG_idir[nk][i] ];
+      ppt = &mesh->point[ipb];
+      cb   = &ppt->c[0];
+      iadr = (ipb-1)*sol->offset + 1;
+      mb   = &sol->met[iadr];
+       if ( ppt->mark < base ) {
+        len = MMG_length(ca,cb,ma,mb);
+	      if ( len > 1.51 ) {
+	        MMG_nlen++;
+          memcpy(pb->c,coor,3*sizeof(double));
+          memcpy(&sol->met[iadb],solu,sol->offset*sizeof(double));
+//printf("bad MMG_length : %f > %f\n",len,1.51);
+          return(0);
+        }
+        ppt->mark = base;
+      }
+    }
+  }
+
+  /* verif topo */
+  for (l=1; l<=lon; l++) {
+    ik  = abs(list.tetra[l]);
+    kk  = ik >> 2;
+    nk  = ik % 4;
+    pt1 = &mesh->tetra[kk];
+    if ( pt1->mark != base )  continue;
+
+    iadr = (kk-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    ielv = adja[nk] >> 2;
+
+    for (i=0; i<4; i++) {
+      if ( i == nk )  continue;
+      adj = adja[i] >> 2;
+      pt1 = &mesh->tetra[adj];
+      if ( pt1->mark == base )  continue;
+      adja1 = &mesh->adja[ (adj-1)*4 + 1 ];
+      for (j=0; j<4; j++) {
+        adj1 = adja1[j] >> 2;
+        if ( pt1->v[j] == nb && adj1 == ielv ) {
+	        MMG_ntopo++;
+          memcpy(pb->c,coor,3*sizeof(double));
+          memcpy(&sol->met[iadb],solu,sol->offset*sizeof(double));
+	        return(0);
+	      }
+      }
+    }
+  }
+
+  /* update topo: shell */
+  for (l=1; l<=lon; l++) {
+    if ( list.tetra[l] > 0 )  continue;
+
+    kk = -list.tetra[l] >> 2;
+    nk = -list.tetra[l] % 4;
+
+    pt1 = &mesh->tetra[kk];
+    pt1->qual = list.qual[l];
+    iadr = (kk-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adj  = adja[nk] >> 2;
+    voy  = adja[nk] % 4;
+    adj1 = 0;
+    voy1 = 0;
+    for (j=0; j<4; j++) {
+      if ( pt1->v[j] == na ) {
+        adj1 = adja[j] >> 2;
+	      voy1 = adja[j] % 4;
+        if ( adj1 ) {
+	        iadr = (adj1-1)*4 + 1;
+          adja = &mesh->adja[iadr];
+          adja[voy1] = 4*adj + voy;  
+          mesh->tetra[adj1].bdryref[voy1] = pt1->bdryref[nk];
+	      }
+	      break;
+      }
+    }
+    if ( adj ) {
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[voy] = 4*adj1 + voy1;
+      if(!adj1)  
+        mesh->tetra[adj].bdryref[voy] = pt1->bdryref[j];
+    }
+    MMG_delElt(mesh,kk);
+  }
+
+  /* update topo: ball */
+  for (l=1; l<=lon; l++) {
+    if ( list.tetra[l] < 0 )  continue;
+    kk  = list.tetra[l] >> 2;
+    nk  = list.tetra[l] % 4;
+    pt1 = &mesh->tetra[kk];
+    pt1->v[nk] = na;
+    pt1->flag  = mesh->flag;
+    pt1->qual  = list.qual[l];
+    pt1->edge &= ~(1 << MMG_arpt[nk][0]);
+    pt1->edge &= ~(1 << MMG_arpt[nk][1]);
+    pt1->edge &= ~(1 << MMG_arpt[nk][2]);
+  }
+
+  /* delete vertex */
+  memcpy(pb->c,coor,3*sizeof(double));
+  pa->mark = mesh->flag;
+
+  return(1);
+}
diff --git a/contrib/mmg3d/build/sources/coquil.c b/contrib/mmg3d/build/sources/coquil.c
new file mode 100644
index 0000000000000000000000000000000000000000..c351552e47d09e2e099d41dde6a293f7e045cf6e
--- /dev/null
+++ b/contrib/mmg3d/build/sources/coquil.c
@@ -0,0 +1,106 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+/* find all tets sharing edge ia of iel */
+int MMG_coquil(pMesh mesh,int iel,int ia,pList list) {
+  pTetra      pt;
+  int        *adja,i,iadr,adj,base,na,nb,ipa,ipb,piv,ilist,kref;
+
+  if ( iel < 1 )  return(0);
+  pt   = &mesh->tetra[iel];
+  if ( !pt->v[0] )  return(0);
+
+  base     = ++mesh->mark;
+  pt->mark = base; 
+	kref     = pt->ref;
+  ilist = 1;
+  list->tetra[ilist] = 6*iel + ia;
+
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adj  = adja[ MMG_ifar[ia][0] ] >> 2;
+  piv  = pt->v[ MMG_ifar[ia][1] ];
+  if ( !adj )  return(0);
+
+  na   = pt->v[ MMG_iare[ia][0] ];
+  nb   = pt->v[ MMG_iare[ia][1] ];
+
+  while ( adj != iel ) {
+    pt = &mesh->tetra[adj];
+    pt->mark = base; 
+		if (kref!=pt->ref) return(0);
+		
+    /* identify edge */
+    for (i=0; i<6; i++) {
+      ipa = MMG_iare[i][0];
+      ipb = MMG_iare[i][1];
+      if ( (pt->v[ipa] == na && pt->v[ipb] == nb) ||
+           (pt->v[ipa] == nb && pt->v[ipb] == na))  break;
+    }
+    if(i==6) printf("tetra %d : %d %d %d %d -- %e\n",iel,pt->v[0],pt->v[1],pt->v[2],pt->v[3],pt->qual);
+    assert(i<6);
+
+    ++ilist;
+    if ( ilist > LONMAX-1 )  return(-ilist);
+    list->tetra[ilist] = 6*adj + i;
+
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    if ( pt->v[ MMG_ifar[i][0] ] == piv ) {
+      adj = adja[ MMG_ifar[i][0] ] >> 2;
+      piv = pt->v[ MMG_ifar[i][1] ];
+    }
+    else {
+      adj = adja[ MMG_ifar[i][1] ] >> 2;
+      piv = pt->v[ MMG_ifar[i][0] ];
+    }
+
+    if ( !adj )  return(0);
+  }
+
+  return(ilist);
+}
diff --git a/contrib/mmg3d/build/sources/cutelt.c b/contrib/mmg3d/build/sources/cutelt.c
new file mode 100644
index 0000000000000000000000000000000000000000..54480498fa19f7234d41321c7ea2811bb806bd62
--- /dev/null
+++ b/contrib/mmg3d/build/sources/cutelt.c
@@ -0,0 +1,544 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+int MMG_cutadd(pMesh mesh,pHedge hed,int icas,int k,int p0,int p1,int p2,int p3,int p4,int p5, int ref) {
+	pTetra		pt;
+	pPoint		ppt,pp0,pp1,pp2,pp3,pp4,pp5;
+
+	pp0 = &mesh->point[p0];
+	pp1 = &mesh->point[p1];
+	pp2 = &mesh->point[p2];
+	pp3 = &mesh->point[p3];
+	pp4 = &mesh->point[p4];
+	pp5 = &mesh->point[p5];
+	mesh->np++;
+	ppt = &mesh->point[mesh->np]; 
+	ppt->c[2] = (1./6.)*(pp0->c[2]+pp1->c[2]+pp2->c[2]+pp3->c[2]+pp4->c[2]+pp5->c[2]);
+	ppt->c[1] = (1./6.)*(pp0->c[1]+pp1->c[1]+pp2->c[1]+pp3->c[1]+pp4->c[1]+pp5->c[1]);
+	ppt->c[0] = (1./6.)*(pp0->c[0]+pp1->c[0]+pp2->c[0]+pp3->c[0]+pp4->c[0]+pp5->c[0]);
+	ppt->ref = pp0->ref;
+	//printf("prisme : %d %d %d %d %d %d + %d\n",p0,p1,p2,p3,p4,p5,mesh->np);
+	if(icas & 1) {
+		//printf("icas %d --> 0 ?\n",icas);
+		pt = &mesh->tetra[k + 1];
+	  pt->v[0] = p0;
+    pt->v[1] = p4;
+	  pt->v[2] = p3;
+	  pt->v[3] = mesh->np;
+	  pt->ref  = ref;
+		pt = &mesh->tetra[k + 2];
+	  pt->v[0] = p0;
+    pt->v[1] = p1;
+	  pt->v[2] = p4;
+	  pt->v[3] = mesh->np;
+	  pt->ref  = ref;
+	} else {
+		if(icas & 4) {
+			//printf("icas %d --> 2 ?\n",icas);
+			
+		} else {
+			MMG_edgePut(hed,p1,p3,2);
+		}   
+		pt = &mesh->tetra[k + 1];
+	  pt->v[0] = p0;
+    pt->v[1] = p1;
+	  pt->v[2] = p3;
+	  pt->v[3] = mesh->np;
+	  pt->ref  = ref;
+		pt = &mesh->tetra[k + 2];
+	  pt->v[0] = p1;
+    pt->v[1] = p4;
+	  pt->v[2] = p3;
+	  pt->v[3] = mesh->np;
+	  pt->ref  = ref;		
+	}
+	
+	if(icas & 8) {
+		//printf("icas %d --> 3 ?\n",icas);
+		pt = &mesh->tetra[k + 3];
+	  pt->v[0] = p1;
+    pt->v[1] = p2;
+	  pt->v[2] = p5;
+	  pt->v[3] = mesh->np;
+	  pt->ref  = ref;
+		pt = &mesh->tetra[k + 4];
+	  pt->v[0] = p1;
+    pt->v[1] = p5;
+	  pt->v[2] = p4;
+	  pt->v[3] = mesh->np;
+	  pt->ref  = ref;
+	} else {
+		if(icas & 32) {
+			//printf("icas %d --> 5 ?\n",icas);
+			
+		} else {
+			MMG_edgePut(hed,p2,p4,2);
+		}   
+		pt = &mesh->tetra[k + 3];
+	  pt->v[0] = p1;
+    pt->v[1] = p2;
+	  pt->v[2] = p4;
+	  pt->v[3] = mesh->np;
+	  pt->ref  = ref;
+		pt = &mesh->tetra[k + 4];
+	  pt->v[0] = p4;
+    pt->v[1] = p2;
+	  pt->v[2] = p5;
+	  pt->v[3] = mesh->np;
+	  pt->ref  = ref;		
+	}
+
+	if(icas & 2) {
+		//printf("icas %d --> 1 ?\n",icas);
+		pt = &mesh->tetra[k + 5];
+	  pt->v[0] = p0;
+    pt->v[1] = p5;
+	  pt->v[2] = p3;
+	  pt->v[3] = mesh->np;
+	  pt->ref  = ref;
+		pt = &mesh->tetra[k + 6];
+	  pt->v[0] = p0;
+    pt->v[1] = p5;
+	  pt->v[2] = p2;
+	  pt->v[3] = mesh->np;
+	  pt->ref  = ref;
+	} else {
+		if(icas & 16) {
+			//printf("icas %d --> 4 ?\n",icas);
+			
+		} else {
+			MMG_edgePut(hed,p2,p3,2);
+		}   
+		pt = &mesh->tetra[k + 5];
+	  pt->v[0] = p0;
+    pt->v[1] = p2;
+	  pt->v[2] = p3;
+	  pt->v[3] = mesh->np;
+	  pt->ref  = ref;
+		pt = &mesh->tetra[k + 6];
+	  pt->v[0] = p2;
+    pt->v[1] = p3;
+	  pt->v[2] = p5;
+	  pt->v[3] = mesh->np;
+	  pt->ref  = ref;		
+	}
+
+	pt = &mesh->tetra[k + 7];
+  pt->v[0] = p3;
+  pt->v[1] = p4;
+  pt->v[2] = p5;
+  pt->v[3] = mesh->np;
+  pt->ref  = ref;
+	pt = &mesh->tetra[k + 8];
+  pt->v[0] = p0;
+  pt->v[1] = p1;
+  pt->v[2] = p2;
+  pt->v[3] = mesh->np;
+  pt->ref  = ref;		
+	
+	return(1);
+}           
+
+int MMG_cuthex(pMesh mesh,pHedge hed,int k,int p0,int p1,int p2,int p3,int p4,int p5,int p6,int p7, int ref) { 
+	pTetra		pt;
+	int				i,nu1,nu2;
+	
+	
+	pt = &mesh->tetra[k+1];
+  pt->v[0] = p0;
+  pt->v[1] = p1;
+  pt->v[2] = p3;
+  pt->v[3] = p7;
+  pt->ref  = ref;
+	for(i=0 ; i<6 ; i++) {
+		nu1 = pt->v[MMG_iare[i][0]];
+		nu2 = pt->v[MMG_iare[i][1]];
+		MMG_edgePut(hed,nu1,nu2,2);
+	}
+  //if((netmp+(k-1)*6+1 ) == 2924) printf("i) %d tet %d %d %d %d\n",k,pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
+  pt = &mesh->tetra[k+2];
+  pt->v[0] = p7;
+  pt->v[1] = p2;
+  pt->v[2] = p1;
+  pt->v[3] = p6;
+  pt->ref  = ref;
+	for(i=0 ; i<6 ; i++) {
+		nu1 = pt->v[MMG_iare[i][0]];
+		nu2 = pt->v[MMG_iare[i][1]];
+		MMG_edgePut(hed,nu1,nu2,2);
+	}
+  //if((netmp+(k-1)*6+1 + 1) == 2924) printf("ii) tet %d %d %d %d\n",pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
+  pt = &mesh->tetra[k+3];  
+  pt->v[0] = p1;
+  pt->v[1] = p4;
+  pt->v[2] = p5;
+  pt->v[3] = p7; 
+	for(i=0 ; i<6 ; i++) {
+		nu1 = pt->v[MMG_iare[i][0]];
+		nu2 = pt->v[MMG_iare[i][1]];
+		MMG_edgePut(hed,nu1,nu2,2);
+	}
+  //if((netmp+(k-1)*6+1 + 2) == 2924) printf("iii) tet %d %d %d %d\n",pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
+  pt->ref  = ref;
+  pt = &mesh->tetra[k+4];
+  pt->v[0] = p7;
+  pt->v[1] = p4;
+  pt->v[2] = p0;
+  pt->v[3] = p1;
+  pt->ref  = ref;
+	for(i=0 ; i<6 ; i++) {
+		nu1 = pt->v[MMG_iare[i][0]];
+		nu2 = pt->v[MMG_iare[i][1]];
+		MMG_edgePut(hed,nu1,nu2,2);
+	}
+  //if((netmp+(k-1)*6+1 + 3) == 2924) printf("iv) tet %d %d %d %d\n",pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
+  pt = &mesh->tetra[k+5];
+  pt->v[0] = p1;
+  pt->v[1] = p6;
+  pt->v[2] = p7;
+  pt->v[3] = p5;
+  pt->ref  = ref;
+	for(i=0 ; i<6 ; i++) {
+		nu1 = pt->v[MMG_iare[i][0]];
+		nu2 = pt->v[MMG_iare[i][1]];
+		MMG_edgePut(hed,nu1,nu2,2);
+	}
+  pt = &mesh->tetra[k+6];
+  pt->v[0] = p1;
+  pt->v[1] = p3;
+  pt->v[2] = p2;
+  pt->v[3] = p7;
+  pt->ref  = ref;
+	for(i=0 ; i<6 ; i++) {
+		nu1 = pt->v[MMG_iare[i][0]];
+		nu2 = pt->v[MMG_iare[i][1]];
+		MMG_edgePut(hed,nu1,nu2,2);
+	}
+	return(1);
+}
+
+int MMG_cutprism(pMesh mesh,pHedge hed,int k,int p0,int p1,int p2,int p3,int p4,int p5,int ref) {
+	pTetra 	pt;  
+	double	vol;
+	int			t0,t1,t2;
+	char   	icas; 
+	int ddebug;
+ 
+	vol= MMG_quickvol(mesh->point[p0].c,mesh->point[p1].c,mesh->point[p2].c,mesh->point[p3].c);  
+	if(vol<0) {
+		printf("inversion"); 
+		t0 = p0;
+		t1 = p1;
+		t2 = p2;
+		p0 = p3;
+		p1 = p4;
+		p2 = p5;
+		p3 = t0;
+		p4 = t1;
+		p5 = t2;
+	} 
+	if(k==606 || k==605 || k==604 || k==609 || k==608 || k==607) ddebug=1; 
+	else ddebug=0; 
+	ddebug=0;
+	if(ddebug) printf("k = %d : %d %d %d %d %d %d\n",k,p0,p1,p2,p3,p4,p5,p5);      
+	
+	icas = 0;
+
+	//find edge 2 : p1-p3 then edge 0 : 0 4
+	if(!MMG_edgePoint(hed,p1,p3)) {
+		if(MMG_edgePoint(hed,p0,p4))
+			icas |= 1;
+	} else {
+		icas |= 4;
+	}
+	//find edge 5 : p2-p4 then edge 3 : 1 5
+	if(!MMG_edgePoint(hed,p2,p4)) {
+		if(MMG_edgePoint(hed,p1,p5))
+			icas |= 8;
+	} else {
+		icas |= 32;
+	}
+	//find edge 4 : p2-p3 then edge 1 : 0 5
+	if(!MMG_edgePoint(hed,p2,p3)) {
+		if(MMG_edgePoint(hed,p0,p5))
+		icas |= 2;
+	} else {
+		icas |= 16;
+	}
+	if(icas > 55) {
+		fprintf(stdout,"grosgros bug %d\n",icas);
+		exit(0);
+	} 
+	if(ddebug) printf("on trouve %d\n",icas);
+	
+	switch(icas) {
+		case 0: 
+		  if(ddebug) printf("on rajoute %d %d -- %d %d -- %d %d\n",p0,p4,p1,p5,p0,p5);
+	    MMG_edgePut(hed,p2,p4,2);
+	    MMG_edgePut(hed,p1,p3,2);
+	    MMG_edgePut(hed,p3,p2,2);//MMG_edgePut(hed,p2,p3,2);
+		  icas = 52;
+	    break;
+		case 1:
+		  MMG_edgePut(hed,p1,p5,2);
+		  MMG_edgePut(hed,p0,p5,2);
+			icas = 11;//25;
+		  break;
+		case 2:
+	    MMG_edgePut(hed,p1,p5,2);
+	    MMG_edgePut(hed,p0,p4,2);
+	    icas = 11;//14
+	    break;
+		case 3:
+		  MMG_edgePut(hed,p1,p5,2);
+			icas = 11;//35;
+		  break;
+		case 4:
+	    MMG_edgePut(hed,p2,p4,2);//MMG_edgePut(hed,p1,p5,2);
+		  MMG_edgePut(hed,p2,p3,2);//MMG_edgePut(hed,p0,p5,2);
+			icas = 52;//14;
+		  break;
+		case 6:
+		  MMG_edgePut(hed,p1,p5,2);
+		  icas = 14;
+		  break;
+		case 8:
+		  MMG_edgePut(hed,p0,p5,2);
+		  MMG_edgePut(hed,p0,p4,2);
+			icas = 11;//14;
+		  break;
+		case 9:
+		  MMG_edgePut(hed,p0,p5,2);
+			icas = 11;//25;
+		  break;
+		case 10:
+		  MMG_edgePut(hed,p0,p4,2);
+			icas = 11;//14;
+		  break;
+		case 12:
+		  MMG_edgePut(hed,p0,p5,2);
+		  icas = 14;
+		  break;
+		case 16:
+		  MMG_edgePut(hed,p2,p4,2);//MMG_edgePut(hed,p1,p5,2);
+		  MMG_edgePut(hed,p3,p1,2);//MMG_edgePut(hed,p1,p3,2);
+			icas = 52;//28;
+		  break;
+		case 17:
+		  MMG_edgePut(hed,p4,p2,2); 
+			icas = 49;//25;
+		  break;
+		case 20:
+		  MMG_edgePut(hed,p2,p4,2);    //MMG_edgePut(hed,p1,p5,2);
+			icas = 52;//28;
+		  break;
+	  case 24:
+	    MMG_edgePut(hed,p1,p3,2);
+			icas = 28;//25;
+	    break;
+		case 32:
+		  MMG_edgePut(hed,p1,p3,2);//MMG_edgePut(hed,p0,p4,2);
+		  MMG_edgePut(hed,p2,p3,2);//MMG_edgePut(hed,p0,p5,2); 
+			icas = 52;//35;
+		  break;
+		case 33:
+		  MMG_edgePut(hed,p0,p5,2);
+		  icas = 35;
+		  break;
+		case 34:
+		  MMG_edgePut(hed,p0,p4,2);
+		  icas = 35;
+		  break;
+		case 36:
+		  MMG_edgePut(hed,p3,p2,2);
+		  icas = 52;
+		  break;
+		case 48:
+		  MMG_edgePut(hed,p1,p3,2);//MMG_edgePut(hed,p0,p4,2);
+			icas = 52;//49;
+		  break;
+		default:
+			//5,7,11,13,15,18,19,21,22,23,26,27,29,30,31,37,39,40,41,42,43,44,45,46,47,50,51,52,53,54,55: 
+		  //printf("icas imposssss %d\n",icas);
+		  //exit(0);
+		  break;
+		    
+	} 
+	if(ddebug) printf("du coup %d\n",icas);
+	switch(icas) {
+	  case 14: 
+		  pt = &mesh->tetra[k + 1];
+		  pt->v[0] = p5;
+	    pt->v[1] = p1;
+		  pt->v[2] = p2;
+		  pt->v[3] = p0;
+		  pt->ref  = ref;//1;//ref;
+	    pt = &mesh->tetra[k + 2];
+	    pt->v[0] = p3;
+		  pt->v[1] = p5;
+		  pt->v[2] = p1;
+		  pt->v[3] = p0;
+		  pt->ref  = ref;//1;//ref;
+	    pt = &mesh->tetra[k + 3];
+	    pt->v[0] = p3;
+	    pt->v[1] = p4;
+		  pt->v[2] = p1;
+		  pt->v[3] = p5;  
+			pt->ref  = ref;//1;//ref;
+		  break;
+	  case 11://25:    //D3  --> bug!     
+		if(ddebug) printf("on create %d %d %d %d -- %d %d %d %d -- %d %d %d %d\n",p0,p4,p3,p5,p0,p1,p4,p5,p5,p1,p2,p0);
+	   	pt = &mesh->tetra[k + 1];
+			pt->v[0] = p0;
+		  pt->v[1] = p4;
+			pt->v[2] = p3;
+			pt->v[3] = p5;
+			pt->ref  = ref;//3;//ref;
+		  pt = &mesh->tetra[k + 2];
+		  pt->v[0] = p0;
+			pt->v[1] = p1;
+			pt->v[2] = p4;
+			pt->v[3] = p5;
+			pt->ref  = ref;//3;//ref;
+		  pt = &mesh->tetra[k + 3];
+		  pt->v[0] = p5;
+		  pt->v[1] = p1;
+			pt->v[2] = p2;
+			pt->v[3] = p0;
+			pt->ref  = ref;//3;//ref;
+			break;
+		case 28:    //D2
+		 	pt = &mesh->tetra[k + 1];
+			pt->v[0] = p4;
+		  pt->v[1] = p5;
+			pt->v[2] = p1;
+			pt->v[3] = p3;
+			pt->ref  = ref;//2;//ref;
+		  pt = &mesh->tetra[k + 2];
+		  pt->v[0] = p1;
+			pt->v[1] = p2;
+			pt->v[2] = p5;
+			pt->v[3] = p3;
+			pt->ref  = ref;//2;//ref;
+		  pt = &mesh->tetra[k + 3];
+		  pt->v[0] = p2;
+		  pt->v[1] = p3;
+			pt->v[2] = p1;
+			pt->v[3] = p0;
+			pt->ref  = ref;//2;//ref;
+			break;
+		case 35:    //D4 --> ok
+		 	pt = &mesh->tetra[k + 1];
+			pt->v[0] = p0;
+		  pt->v[1] = p4;
+			pt->v[2] = p3;
+			pt->v[3] = p5;
+			pt->ref  = ref;//4;//ref;
+		  pt = &mesh->tetra[k + 2];
+		  pt->v[0] = p0;
+			pt->v[1] = p4;
+			pt->v[2] = p5;
+			pt->v[3] = p2;
+			pt->ref  = ref;//4;//ref;
+		  pt = &mesh->tetra[k + 3];  
+		  pt->v[0] = p0;
+		  pt->v[1] = p2;
+			pt->v[2] = p4;
+			pt->v[3] = p1;
+			pt->ref  = ref;//4;//ref;
+			break;
+		case 52:    
+		 	pt = &mesh->tetra[k + 1];
+			pt->v[0] = p2;
+		  pt->v[1] = p4;
+			pt->v[2] = p5;
+			pt->v[3] = p3;
+			pt->ref  = ref;//6;//ref;
+		  pt = &mesh->tetra[k + 2];
+		  pt->v[0] = p2;
+			pt->v[1] = p4;
+			pt->v[2] = p1;
+			pt->v[3] = p3;
+			pt->ref  = ref;//6;//ref;
+		  pt = &mesh->tetra[k + 3];
+		  pt->v[0] = p3;
+		  pt->v[1] = p0;
+			pt->v[2] = p1;
+			pt->v[3] = p2;
+			pt->ref  = ref;//6;//ref;
+			break;
+		case 49:    //D5
+   	  pt = &mesh->tetra[k + 1];
+		  pt->v[0] = p0;
+	    pt->v[1] = p4;
+		  pt->v[2] = p3;
+		  pt->v[3] = p2;
+		  pt->ref  = ref;//5;//ref;
+	    pt = &mesh->tetra[k + 2];
+	    pt->v[0] = p3;
+		  pt->v[1] = p2;
+		  pt->v[2] = p4;
+		  pt->v[3] = p5;
+		  pt->ref  = ref;//5;//ref;
+	    pt = &mesh->tetra[k + 3];
+	    pt->v[0] = p0;
+	    pt->v[1] = p2;
+		  pt->v[2] = p1;
+		  pt->v[3] = p4;
+			pt->ref  = ref;//5;//ref;
+			break;
+	  default:
+			//5,7,11,13,15,18,19,21,22,23,26,27,29,30,31,37,39,40,41,42,43,44,45,46,47,50,51,52,53,54,55:  
+		  MMG_cutadd(mesh,hed,icas,k,p0,p1,p2,p3,p4,p5,ref);
+		 
+		  //printf("icas imposssss %d\n",icas); 
+			return(0);
+		  //exit(0);
+		  break;
+	}	  	
+	return(1);
+}
\ No newline at end of file
diff --git a/contrib/mmg3d/build/sources/defines.h b/contrib/mmg3d/build/sources/defines.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d71e945a9aa5c2f98be6e6396e7bc4ffd3a5651
--- /dev/null
+++ b/contrib/mmg3d/build/sources/defines.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#define EPS      1.e-06
+#define EPS1     1.e-9
+#define EPS2     1.e-12
+#define EPSOK    1.e-18
+#define EPS30    1.e-30
+
+#define ALPHAC   0.20412415      /* sqrt(6)/12 */  
+#define ALPHAD   0.04811252      /* 1.0/(12*sqrt(3)) */
+#define BETAC    0.03928371      /* sqrt(2)/36 */
+
+#define LLONG    1.3
+#define LSHORT   0.72
+#define LFILT    0.7
+#define QDEGRAD  2.45
+
+#define LONMAX     4096
+#define NPMAX    500000
+#define NTMAX   1000000
+#define NEMAX   3000000
+
+#define PRECI       1
+#define BUCKSIZ    64
+
+#define min(a,b) ( (a) < (b) ? (a) : (b) )
+#define max(a,b) ( (a) < (b) ? (b) : (a) )
+
+#define M_NOTAG    (0)
+#define M_UNUSED   (1 << 0)
+#define M_BDRY     (1 << 1)
+#define M_MOVE     (1 << 2)
+#define M_CAVITY   (1 << 3)
+//#define M_CORNER   (1 << 4)
+//#define M_REQUIRED (1 << 5)
+//#define M_RIDGE_GEO(1 << 6)
+//#define M_RIDGE_REF(1 << 7)
+#define ALL_BDRY   63
+
+#ifdef INT_MAX
+#undef INT_MAX
+#undef SHORT_MAX
+#endif
+#define INT_MAX      0x7fffffff
+#define SHORT_MAX    0x7fff
+
+
+extern unsigned char MMG_idir[4][3];
+extern unsigned char MMG_inxt[7];
+extern unsigned char MMG_iarf[4][3];
+extern unsigned char MMG_iare[6][2];
+extern unsigned char MMG_ifar[6][2];
+extern unsigned char MMG_isar[6][2];
+extern unsigned char MMG_arpt[4][3];
diff --git a/contrib/mmg3d/build/sources/delaunay.c b/contrib/mmg3d/build/sources/delaunay.c
new file mode 100644
index 0000000000000000000000000000000000000000..e53a0e6a0cd32127f9633bda8eeab7cda24dd9e4
--- /dev/null
+++ b/contrib/mmg3d/build/sources/delaunay.c
@@ -0,0 +1,813 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "eigenv.h"
+#include "mesh.h"
+
+#define  EPSRAD       1.00005
+#define  EPSCON       5.0e-4//1.e-4//1.0e-3
+#define  VOLMIN       1.e-10//1.0e-15  --> vol negatif qd on rejoue
+
+
+int MMG_cas;
+extern int MMG_npuiss,MMG_nvol,MMG_npres;
+
+
+/* cavity -> ball */
+int MMG_delone(pMesh mesh,pSol sol,int ip,pList list,int ilist) {
+  pPoint    ppt;
+  pTetra    pt,pt1;
+  int      *adja,*adjb,i,j,k,l,m,iel,jel,old,v[3],iadr,base,size;
+  int       vois[4],ii,kk,iare1,iare2;
+  short     i1;
+  char      alert;       
+  int tref;  
+  if ( mesh->ne + 2*ilist > mesh->nemax )  return(0);
+  base = mesh->mark; 
+  /* external faces */
+  size = 0;
+  for (k=1; k<=ilist; k++) {
+    old  = list->tetra[k];
+    pt1  = &mesh->tetra[old];
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    vois[0]  = adja[0] >> 2;
+    vois[1]  = adja[1] >> 2;
+    vois[2]  = adja[2] >> 2;
+    vois[3]  = adja[3] >> 2;
+    for (i=0; i<4; i++) {
+      jel = vois[i];
+      if ( !jel || mesh->tetra[jel].mark != base ) {
+        for (j=0; j<3; j++) {
+	      i1  = MMG_idir[i][j];
+	      ppt = &mesh->point[ pt1->v[i1] ];
+	      ppt->tag |= M_CAVITY;
+	    }
+	    size++;
+      }
+    }
+  }
+
+  /* check isolated vertex */
+  alert = 0;
+  for (k=1; k<=ilist; k++) {
+    old  = list->tetra[k];
+    pt1  = &mesh->tetra[old]; 
+    for (i=0; i<4; i++) {
+      ppt = &mesh->point[ pt1->v[i] ]; 
+      if ( !(ppt->tag & M_CAVITY) )  alert = 1;
+    }
+  }
+  /* reset tag */
+  for (k=1; k<=ilist; k++) {
+    old  = list->tetra[k];
+    pt1  = &mesh->tetra[old];
+    for (i=0; i<4; i++) {
+      ppt = &mesh->point[ pt1->v[i] ];
+      ppt->tag &= ~M_CAVITY;
+    }
+  }     
+  if ( alert )  return(-1);
+  /* hash table params */
+  if ( size > 3*LONMAX )  return(0);
+  list->hedg.size  = size;
+  list->hedg.nhmax = 3*size+1;
+  list->hedg.hnxt  = size;
+  memset(list->hedg.item,0,list->hedg.nhmax*sizeof(hedge));
+  for (k=size; k<list->hedg.nhmax; k++)
+    list->hedg.item[k].nxt = k+1;
+
+  for (k=1; k<=ilist; k++) {
+    old  = list->tetra[k];
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    vois[0]  = adja[0];
+    vois[1]  = adja[1];
+    vois[2]  = adja[2];
+    vois[3]  = adja[3];
+    pt   = &mesh->tetra[old];
+
+    for (i=0; i<4; i++) {
+      jel = vois[i] >> 2;
+      j   = vois[i] % 4;
+
+      /* external face */
+      if ( !jel || (mesh->tetra[jel].mark != base) ) {
+        iel = MMG_newElt(mesh);
+        if ( iel < 1 )  return(0);
+        pt1 = &mesh->tetra[iel];
+	      memcpy(pt1,pt,sizeof(Tetra));
+        pt1->v[i] = ip;
+        pt1->qual = MMG_caltet(mesh,sol,iel);   
+        pt1->ref = mesh->tetra[old].ref;
+        if(pt1->qual > 1e+18) {printf("argggg (%d) %d : %e\n",ip,iel,pt1->qual); 
+        printf("pt1 : %d %d %d %d\n",pt1->v[0],pt1->v[1],pt1->v[2],pt1->v[3]);/*exit(0);*/}      
+        pt1->flag = mesh->flag;
+        pt1->edge = 0;     
+				for(ii=0 ; ii<4 ; ii++)
+          pt1->bdryref[ii] = -1; 
+				/*MAJ bdryinfo */
+				for(ii=0 ; ii<6 ; ii++)
+					pt1->bdryinfo[ii] = 0;
+				for(ii=0 ; ii<3 ; ii++) {  
+					if(!pt->bdryinfo[MMG_iarf[i][ii]]) continue;
+					iare1 = pt->v[MMG_iare[MMG_iarf[i][ii]][0]];
+					iare2 = pt->v[MMG_iare[MMG_iarf[i][ii]][1]]; 
+					for(kk=0 ; kk<3 ; kk++) {  
+					  if(((iare1==pt->v[MMG_iare[MMG_iarf[i][kk]][0]]) && (iare2==pt->v[MMG_iare[MMG_iarf[i][kk]][1]]))
+					  || ((iare2==pt->v[MMG_iare[MMG_iarf[i][kk]][0]]) && (iare1==pt->v[MMG_iare[MMG_iarf[i][kk]][1]])) ) {
+					  		pt1->bdryinfo[MMG_iarf[i][kk]] = pt->bdryinfo[MMG_iarf[i][ii]];
+								break;
+					  }        
+				  }          
+					assert(kk<3);
+				}
+        if(!jel || (mesh->tetra[jel].ref != pt1->ref)) {
+          pt1->bdryref[i] = mesh->tetra[old].bdryref[i];
+          if(pt1->bdryref[i]<0) {
+	          printf("delone : pbs sd %d : %d %d %d\n",iel,pt1->v[MMG_idir[i][0]]
+                     ,pt1->v[MMG_idir[i][1]],pt1->v[MMG_idir[i][2]]);exit(0);  
+           }
+        } 				
+        iadr = (iel-1)*4 + 1;
+        adjb = &mesh->adja[iadr];
+        adjb[i] = adja[i];
+        if ( jel ) {
+          iadr = (jel-1)*4 + 1;
+          adjb = &mesh->adja[iadr];
+          adjb[j] = iel*4 + i;
+    	  }
+
+        /* internal faces (p1,p2,ip) */
+        for (j=0; j<4; j++) {
+	        if ( j != i ) {
+            m = 0;
+	          for (l=0; l<3; l++)
+              if ( pt1->v[ MMG_idir[j][l] ] != ip ) {
+	              v[m] = pt1->v[ MMG_idir[j][l] ];
+		            m++;
+	            }
+	          MMG_hashEdge(mesh,&list->hedg,iel,j,v);
+	        }
+	      }
+      }
+    }
+  }
+
+  /* remove old tetra */ 
+  tref = mesh->tetra[list->tetra[1]].ref;
+  for (k=1; k<=ilist; k++) {    
+    if(tref!=mesh->tetra[list->tetra[k]].ref) 
+          printf("arg ref ???? %d %d\n",tref,mesh->tetra[list->tetra[k]].ref);
+    MMG_delElt(mesh,list->tetra[k]);
+  }
+
+  ppt = &mesh->point[ip];
+  ppt->flag = mesh->flag;
+  return(1);
+}
+
+
+/* clone of delone */
+int MMG_delons(pMesh mesh,pSol sol,pQueue queue,int ip,pList list,int ilist,double declic) {
+  pPoint    ppt;
+  pTetra    pt,pt1;
+  int      *adja,*adjb,i,j,k,l,m,iel,jel,old,v[3],iadr,base,size;
+  int       vois[4],ii,kk,iare1,iare2,tref;
+  short     i1;
+  char      alert;
+
+  if ( mesh->ne + 2*ilist > mesh->nemax )  return(0);
+  base = mesh->mark;
+
+  /* external faces */
+  size = 0;
+  for (k=1; k<=ilist; k++) {
+    old  = list->tetra[k];
+    pt1  = &mesh->tetra[old];
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    for (i=0; i<4; i++) {
+      jel = adja[i] >> 2;   
+      if ( !jel || mesh->tetra[jel].mark != base ) { 
+        for (j=0; j<3; j++) {
+          i1  = MMG_idir[i][j];
+          ppt = &mesh->point[ pt1->v[i1] ];
+          ppt->tag |= M_CAVITY;
+	      }
+	     size++;
+       } 
+    }
+  }
+
+  /* check isolated vertex */
+  alert = 0;
+  for (k=1; k<=ilist; k++) {
+    old  = list->tetra[k];
+    pt1  = &mesh->tetra[old];
+    for (i=0; i<4; i++) {
+      ppt = &mesh->point[ pt1->v[i] ];
+      if ( !(ppt->tag & M_CAVITY) )  alert = 1;
+    }
+  }
+  /* reset tag */
+  for (k=1; k<=ilist; k++) {
+    old  = list->tetra[k];
+    pt1  = &mesh->tetra[old];
+    for (i=0; i<4; i++) {
+      ppt = &mesh->point[ pt1->v[i] ];
+      ppt->tag &= ~M_CAVITY;
+    }
+  }
+  if ( alert )  return(-1);
+
+  /* hash table params */
+  if ( size > 3*LONMAX )  return(0);
+  list->hedg.size  = size;
+  list->hedg.nhmax = 3*size+1;
+  list->hedg.hnxt  = size;
+  memset(list->hedg.item,0,list->hedg.nhmax*sizeof(hedge));
+  for (k=size; k<list->hedg.nhmax; k++)
+    list->hedg.item[k].nxt = k+1;
+
+  for (k=1; k<=ilist; k++) {
+    old  = list->tetra[k];
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    vois[0]  = adja[0];
+    vois[1]  = adja[1];
+    vois[2]  = adja[2];
+    vois[3]  = adja[3];
+    pt   = &mesh->tetra[old];
+
+    for (i=0; i<4; i++) {
+      jel = vois[i] >> 2;
+      j   = vois[i] % 4;
+
+      /* external face */
+      if ( !jel || mesh->tetra[jel].mark != base ) {
+        iel = MMG_newElt(mesh);
+        if ( iel < 1 )  return(0);
+        pt1 = &mesh->tetra[iel];
+        pt1->ref = mesh->tetra[old].ref;
+        mesh->point[ip].tmp = iel;
+	    memcpy(pt1,pt,sizeof(Tetra));
+        pt1->v[i] = ip;
+        pt1->qual = MMG_caltet(mesh,sol,iel);
+        pt1->flag = mesh->flag;
+        pt1->edge = 0;
+				for(ii=0 ; ii<4 ; ii++)
+          pt1->bdryref[ii] = -1; 
+				/*MAJ bdryinfo */
+				for(ii=0 ; ii<6 ; ii++)
+					pt1->bdryinfo[ii] = 0;
+				for(ii=0 ; ii<3 ; ii++) {  
+					if(!pt->bdryinfo[MMG_iarf[i][ii]]) continue;
+					iare1 = pt->v[MMG_iare[MMG_iarf[i][ii]][0]];
+					iare2 = pt->v[MMG_iare[MMG_iarf[i][ii]][1]]; 
+					for(kk=0 ; kk<3 ; kk++) {  
+					  if(((iare1==pt->v[MMG_iare[MMG_iarf[i][kk]][0]]) && (iare2==pt->v[MMG_iare[MMG_iarf[i][kk]][1]]))
+					  || ((iare2==pt->v[MMG_iare[MMG_iarf[i][kk]][0]]) && (iare1==pt->v[MMG_iare[MMG_iarf[i][kk]][1]])) ) {
+					  		pt1->bdryinfo[MMG_iarf[i][kk]] = pt->bdryinfo[MMG_iarf[i][ii]];
+								break;
+					  }        
+				  }          
+					assert(kk<3);
+				}
+        if(!jel || (mesh->tetra[jel].ref != pt1->ref)) {
+          pt1->bdryref[i] = mesh->tetra[old].bdryref[i];
+          if(pt1->bdryref[i]<0) {puts("delone : pbs sd");exit(0);  }
+        }
+        iadr = (iel-1)*4 + 1;
+        adjb = &mesh->adja[iadr];
+        adjb[i] = adja[i];
+        if ( jel ) {
+          iadr = (jel-1)*4 + 1;
+          adjb = &mesh->adja[iadr];
+          adjb[j] = iel*4 + i;
+    	}
+        if ( pt1->qual >= declic )
+          MMG_kiuput(queue,iel);
+
+        /* internal faces (p1,p2,ip) */
+        for (j=0; j<4; j++) {
+	      if ( j != i ) {
+            m = 0;
+	        for (l=0; l<3; l++)
+              if ( pt1->v[ MMG_idir[j][l] ] != ip ) {
+	            v[m] = pt1->v[ MMG_idir[j][l] ];
+		        m++;
+	          }
+	        MMG_hashEdge(mesh,&list->hedg,iel,j,v);
+	      }
+	    }
+      }
+    }
+  }
+
+  /* remove old tetra */
+  for (k=1; k<=ilist; k++) {
+    old = list->tetra[k];
+    MMG_delElt(mesh,old);
+    MMG_kiudel(queue,old);
+  }
+
+  ppt = &mesh->point[ip];
+  ppt->flag = mesh->flag;
+  return(1);
+}
+
+
+/* cavity correction for quality */
+int MMG_correction_ani(pMesh mesh,pSol sol,int ip,pList list,int ilist,int nedep) {
+  pPoint	ppt,p1,p2,p3;
+  pTetra	pt;
+  double	dd,det,nn,eps,eps2,ux,uy,uz,vx,vy,vz,v1,v2,v3;
+  double	*ma,*mb,*mc,*md,mm[6],h1,h2,h3;
+  int		*adja,i,j,ipil,iel,lon,iadr,adj,ib,ic,id,base,ncor;
+  int		vois[4];
+
+  ppt  = &mesh->point[ip];
+  if ( ppt->tag & M_UNUSED )  return(ilist);
+  base = mesh->mark;
+  lon  = ilist;
+  eps  = EPSCON;
+  eps2 = eps*eps;
+
+  /* average metric */
+  memset(mm,0,6*sizeof(double));
+  iadr = (ip-1)*sol->offset + 1;
+  ma   = &sol->met[iadr];
+
+  do {
+    ipil = lon;
+    ncor = 0;
+
+    while ( ipil > 0 ) {
+      iel  = list->tetra[ipil];
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      vois[0]  = adja[0] >> 2;
+      vois[1]  = adja[1] >> 2;
+      vois[2]  = adja[2] >> 2;
+      vois[3]  = adja[3] >> 2;
+      pt   = &mesh->tetra[iel];
+
+MMG_cas=0;
+      for (i=0; i<4; i++) {
+        adj = vois[i];
+MMG_cas = 0;
+        if ( adj && mesh->tetra[adj].mark == base)  continue;
+
+        ib = pt->v[ MMG_idir[i][0] ];
+        ic = pt->v[ MMG_idir[i][1] ];
+        id = pt->v[ MMG_idir[i][2] ];
+
+        p1 = &mesh->point[ib];
+        p2 = &mesh->point[ic];
+        p3 = &mesh->point[id];
+
+        ux = p2->c[0] - p1->c[0];
+        uy = p2->c[1] - p1->c[1];
+        uz = p2->c[2] - p1->c[2];
+
+        vx = p3->c[0] - p1->c[0];
+        vy = p3->c[1] - p1->c[1];
+        vz = p3->c[2] - p1->c[2];
+
+        /* volume PABC */
+        v1 = uz*vy - uy*vz;
+        v2 = ux*vz - uz*vx;
+        v3 = uy*vx - ux*vy;
+        dd = v1*(ppt->c[0]-p1->c[0]) + v2*(ppt->c[1]-p1->c[1]) \
+           + v3*(ppt->c[2]-p1->c[2]);
+MMG_cas=1;
+	   //if ( dd < VOLMIN )  break;  
+	   /*test sur le volume avec un eps local*/
+       h1 = ux*ux + uy*uy + uz*uz;
+       h2 = vx*vx + vy*vy + vz*vz;
+       h3 = (p2->c[0] - p3->c[0])*(p2->c[0] - p3->c[0]) + (p2->c[1] - p3->c[1])*(p2->c[1] - p3->c[1])
+          + (p2->c[2] - p3->c[2])*(p2->c[2] - p3->c[2]);
+	     if ( dd < VOLMIN*sqrt(h1*h2*h3) )  break;   
+
+        /* average metric */
+        iadr = (ib-1)*sol->offset + 1;
+        mb   = &sol->met[iadr];
+        iadr = (ic-1)*sol->offset + 1;
+        mc   = &sol->met[iadr];
+        iadr = (id-1)*sol->offset + 1;
+        md   = &sol->met[iadr];
+        for (j=0; j<6; j++)
+          mm[j] = 0.25 * (ma[j]+mb[j]+mc[j]+md[j]);
+          
+        det = mm[0] * ( mm[3]*mm[5] - mm[4]*mm[4]) \
+            - mm[1] * ( mm[1]*mm[5] - mm[2]*mm[4]) \
+            + mm[2] * ( mm[1]*mm[4] - mm[2]*mm[3]);
+        if ( det < EPSOK )  break;
+
+	/* point close to face */
+	/*nn = (v1*v1 + v2*v2 + v3*v3);*/
+MMG_cas=2;
+        nn = mm[0]*v1*v1 + mm[3]*v2*v2 + mm[5]*v3*v3 \
+           + 2.0*(mm[1]*v1*v2 + mm[2]*v1*v3 + mm[4]*v2*v3);
+        /*if ( det*dd*dd*dd*dd*dd*dd < nn * nn * nn * eps2 * eps2 * eps2 )  break;*/
+	/*//prendre le min des valeurs propres
+	eigenv(1,mm,lambda,vv);
+	det = max(lambda[0],max(lambda[1],lambda[2]));
+	if ( det*dd*dd < nn * eps2 )  break;
+	*//*if ( pow(det,1./3.)*dd*dd < nn * eps2 )  break;*/
+	if ( det*dd*dd < nn * eps2 )  break;
+	/*if ( dd*dd < nn * eps2 ) {
+	  printf("en iso      : %e %e    %e %e\n",dd,nn,dd*dd,nn*eps2);
+	  printf("en iso sqrt : %e %e    %e %e\n",dd,nn,dd/sqrt(nn),(sqrt(mm[0]))*(dd/sqrt(nn)));
+
+	  dd1 = mm[0]*v1*v1 + mm[3]*v2*v2 + mm[5]*v3*v3 \
+           + 2.0*(mm[1]*v1*v2 + mm[2]*v1*v3 + mm[4]*v2*v3);
+	   //len carre = (dd*dd/norm(v1v2v3)^2)*dd1/(norm(v1v2v3)^2 
+	  printf("aniso      : %e %e %e %e %e\n",(dd*dd/nn)*dd1/(nn),sqrt(dd*dd*dd1/(nn*sqrt(nn))),det,det*dd*dd,dd1*eps2);
+	  
+	  nn = sqrt(nn);
+	  ph = dd/nn;
+	  v1 /= nn;
+	  v2 /= nn;
+	  v3 /= nn;
+	  xh = ph*v1 + ppt->c[0];
+	  yh = ph*v2 + ppt->c[1];
+	  zh = ph*v3 + ppt->c[2];
+	  
+	  //dist PH dans la met/
+	  ux = xh - ppt->c[0];
+          uy = yh - ppt->c[1];
+          uz = zh - ppt->c[2];
+          dd = ux*ux + uy*uy + uz*uz;
+
+          dd2 =      mm[0]*ux*ux + mm[3]*uy*uy + mm[5]*uz*uz \
+               + 2.0*(mm[1]*ux*uy + mm[2]*ux*uz + mm[4]*uy*uz);
+          if ( dd2 <= 0.0 )  dd2 = 0.0;
+
+          len = sqrt(dd2);
+	  
+	  printf("on trouve len : %e %e %e\n",len,sqrt(eps2)*sqrt(mm[0]),pow(sqrt(eps2)*sqrt(det),1./3.));
+	  printf("len carre %e %e\n",mm[0]*v1*v1*ph*ph + mm[3]*v2*v2*ph*ph + mm[5]*v3*v3*ph*ph,dd2);
+	 exit(0);
+	 break;
+	 }*/
+MMG_cas=0;	
+      }
+      if ( i < 4 ) {
+        if ( ipil <= nedep )  return(0);
+        /* remove iel from list */
+	    pt->mark = base-1;
+	    list->tetra[ipil] = list->tetra[lon];
+        lon--;
+	    ncor = 1;
+	    break;
+      }
+      else
+        ipil--;
+    }
+  }
+  while ( ncor > 0 && lon >= nedep );
+
+  return(lon);
+}
+
+
+/* cavity correction for quality */
+int MMG_correction_iso(pMesh mesh,int ip,pList list,int ilist,int nedep) {
+  pPoint   ppt,p1,p2,p3;
+  pTetra   pt;
+  double   dd,nn,eps,eps2,ux,uy,uz,vx,vy,vz,v1,v2,v3;
+  int     *adja,i,ipil,iel,lon,iadr,adj,ib,ic,id,base,ncor;
+  int	   vois[4];
+  
+  ppt  = &mesh->point[ip];
+  if ( ppt->tag & M_UNUSED )  return(ilist);
+  base = mesh->mark;
+  lon  = ilist;
+  eps  = EPSCON;
+  eps2 = eps*eps;
+  do {
+    ipil = lon;
+    ncor = 0;
+
+    while ( ipil > 0 ) {
+      iel  = list->tetra[ipil];
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      vois[0]  = adja[0] >> 2;
+      vois[1]  = adja[1] >> 2;
+      vois[2]  = adja[2] >> 2;
+      vois[3]  = adja[3] >> 2;
+      pt   = &mesh->tetra[iel];
+MMG_cas=0;
+      for (i=0; i<4; i++) {
+        adj = vois[i];
+MMG_cas = 0;
+        if ( adj && mesh->tetra[adj].mark == base )  continue;
+
+        ib = pt->v[ MMG_idir[i][0] ];
+        ic = pt->v[ MMG_idir[i][1] ];
+        id = pt->v[ MMG_idir[i][2] ];
+
+        p1 = &mesh->point[ib];
+        p2 = &mesh->point[ic];
+        p3 = &mesh->point[id];
+
+        ux = p2->c[0] - p1->c[0];
+        uy = p2->c[1] - p1->c[1];
+        uz = p2->c[2] - p1->c[2];
+
+        vx = p3->c[0] - p1->c[0];
+        vy = p3->c[1] - p1->c[1];
+        vz = p3->c[2] - p1->c[2];
+
+        /* volume PABC */
+        v1 = uz*vy - uy*vz;
+        v2 = ux*vz - uz*vx;
+        v3 = uy*vx - ux*vy;
+        dd = v1*(ppt->c[0]-p1->c[0]) + v2*(ppt->c[1]-p1->c[1]) \
+           + v3*(ppt->c[2]-p1->c[2]);
+MMG_cas=1;   
+//printf("on trouve vol %e <? %e\n",dd,VOLMIN);
+	      if ( dd < VOLMIN )  break;
+
+        /* point close to face */
+        nn = (v1*v1 + v2*v2 + v3*v3);
+MMG_cas=2;                         
+//printf("on trouve close ? %e %e\n",dd*dd,nn*eps2);
+        if ( dd*dd < nn * eps2 )  break;
+MMG_cas=0;	
+      }
+      if ( i < 4 ) {
+        if ( ipil <= nedep )  {/*printf("on veut tout retirer ? %d %d\n",ipil,nedep);*/return(0);   }
+        /* remove iel from list */
+        pt->mark = base-1;
+        list->tetra[ipil] = list->tetra[lon];
+        lon--;
+        ncor = 1;
+        break;
+      }
+      else
+        ipil--;
+    }
+  }
+  while ( ncor > 0 && lon >= nedep );
+
+  return(lon);
+}
+
+
+/* mark elements in cavity */
+int MMG_cavity_ani(pMesh mesh,pSol sol,int iel,int ip,pList list,int lon) {
+  pPoint    ppt;
+  pTetra    pt,pt1,ptc;
+  double    c[3],eps,dd,ray,ux,uy,uz,crit;
+  double    *mj,*mp,ct[12];
+  int       *adja,*adjb,k,adj,adi,voy,i,j,ia,ilist,ipil,jel,iadr,base;
+  int	    vois[4],l;
+  
+  if ( lon < 1 )  return(0);
+  ppt = &mesh->point[ip];
+  if ( ppt->tag & M_UNUSED )  return(0);
+
+  for (k=1; k<=lon; k++)
+    list->tetra[k] = list->tetra[k] / 6;
+
+  /* grow cavity by adjacency */
+  base  = mesh->mark;
+  eps   = EPSRAD * EPSRAD;
+  ilist = lon;
+  ipil  = 1;
+  iadr  = (ip-1)*sol->offset + 1;
+  mp    = &sol->met[iadr];
+
+  do {
+    jel  = list->tetra[ipil];
+    iadr = (jel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    vois[0]  = adja[0];
+    vois[1]  = adja[1];
+    vois[2]  = adja[2];
+    vois[3]  = adja[3];
+    ptc  = &mesh->tetra[jel];
+
+    for (i=0; i<4; i++) {
+      adj = vois[i] >> 2;
+      voy = vois[i] % 4;
+      if ( !adj )  continue;
+      pt  = &mesh->tetra[adj];
+      /* boundary face */
+      if ( pt->mark == base || pt->ref != ptc->ref )  continue;
+      for (j=0,l=0; j<4; j++,l+=3) {
+        memcpy(&ct[l],mesh->point[pt->v[j]].c,3*sizeof(double));      
+      }
+
+
+      /* Delaunay kernel */
+      if ( !MMG_cenrad_ani(mesh,ct,mp,c,&ray) )  continue;
+
+      ux = ppt->c[0] - c[0];
+      uy = ppt->c[1] - c[1];
+      uz = ppt->c[2] - c[2];
+      dd =      mp[0]*ux*ux + mp[3]*uy*uy + mp[5]*uz*uz \
+         + 2.0*(mp[1]*ux*uy + mp[2]*ux*uz + mp[4]*uy*uz);
+      crit = eps * ray;
+      if ( dd > crit )  continue;
+
+      /* mixed metrics */
+      crit = sqrt(dd/ray);
+      for (j=0; j<4; j++) {
+        ia   = pt->v[j];
+        iadr = (ia-1)*sol->offset + 1;
+        mj   = &sol->met[iadr];
+        if ( !MMG_cenrad_ani(mesh,ct,mj,c,&ray) )  continue;
+        ux = ppt->c[0] - c[0];
+        uy = ppt->c[1] - c[1];
+        uz = ppt->c[2] - c[2];
+        dd =      mj[0]*ux*ux + mj[3]*uy*uy + mj[5]*uz*uz \
+           + 2.0*(mj[1]*ux*uy + mj[2]*ux*uz + mj[4]*uy*uz);
+        crit += sqrt(dd/ray);
+      }
+      crit *= EPSRAD;
+      if ( crit > 5.0 ) continue;
+
+      /* lost face(s) */
+      iadr = (adj-1)*4 + 1;
+      adjb = &mesh->adja[iadr];
+
+      for (j=0; j<4; j++) {
+        if ( j == voy )  continue;
+	      adi = adjb[j] >> 2;
+	      if ( !adi )  continue;
+	      pt1 = &mesh->tetra[adi];
+        if ( pt1->mark == base && adi != jel ) {
+          if ( !adi || pt1->ref != mesh->tetra[adi].ref )  break;
+        }
+      }
+      /* store tetra */
+      if ( j == 4 ) {
+        pt->mark = base;
+        ++ilist;
+        list->tetra[ilist] = adj;
+      }
+    }
+    if ( ilist > LONMAX - 3 )  return(-1);
+    ++ipil;
+  }
+  while ( ipil <= ilist );
+
+  /* global overflow */
+  if ( mesh->ne + 2*ilist >= mesh->nemax )
+    ilist = -ilist;
+  else
+    ilist = MMG_correction_ani(mesh,sol,ip,list,ilist,lon);
+
+if(MMG_cas==1) MMG_nvol++;
+else if(MMG_cas==2 || MMG_cas>20) {
+  MMG_npuiss++;
+  if(MMG_cas>20) MMG_npres++;
+}
+
+  return(ilist);
+}
+
+
+int MMG_cavity_iso(pMesh mesh,pSol sol,int iel,int ip,pList list,int lon) {
+  pPoint    ppt;
+  pTetra    pt,pt1,ptc;
+  double    c[3],crit,dd,eps,ray,ct[12];
+  int      *adja,*adjb,k,adj,adi,voy,i,j,ilist,ipil,jel,iadr,base;
+  int       vois[4],l;
+  int tref;
+    
+  if ( lon < 1 )  return(0);
+  ppt = &mesh->point[ip];
+  if ( ppt->tag & M_UNUSED )  return(0);
+
+  tref = mesh->tetra[list->tetra[1]/6].ref;
+#warning remove this test
+  for (k=1; k<=lon; k++)
+    if(tref!=mesh->tetra[list->tetra[k]/6].ref) 
+       printf("pbs coquil %d %d tet %d\n",tref,mesh->tetra[list->tetra[k]/6].ref,list->tetra[k]/6);
+  
+  for (k=1; k<=lon; k++)
+    list->tetra[k] = list->tetra[k] / 6;
+
+  /* grow cavity by adjacency */
+  base  = mesh->mark;
+  eps   = EPSRAD*EPSRAD;
+  ilist = lon;
+  ipil  = 1;
+
+  do {
+    jel  = list->tetra[ipil]; 
+    iadr = (jel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    vois[0]  = adja[0];
+    vois[1]  = adja[1];
+    vois[2]  = adja[2];
+    vois[3]  = adja[3];
+    ptc  = &mesh->tetra[jel];
+
+    for (i=0; i<4; i++) {
+      adj = vois[i] >> 2;
+      voy = vois[i] % 4;
+      if ( !adj )  continue;
+      pt  = &mesh->tetra[adj];
+      /* boundary face */
+      if ( pt->mark == base || pt->ref != ptc->ref )  continue;
+
+      for (j=0,l=0; j<4; j++,l+=3) {
+        memcpy(&ct[l],mesh->point[pt->v[j]].c,3*sizeof(double));      
+      }
+
+      if ( !MMG_cenrad_iso(mesh,ct,c,&ray) )  continue;
+      crit = eps * ray;
+
+      /* Delaunay criterion */
+      dd = (ppt->c[0] - c[0]) * (ppt->c[0] - c[0]) \
+         + (ppt->c[1] - c[1]) * (ppt->c[1] - c[1]) \
+         + (ppt->c[2] - c[2]) * (ppt->c[2] - c[2]);
+      if ( dd > crit )  continue;
+
+      /* lost face(s) */
+      iadr = (adj-1)*4 + 1;
+      adjb = &mesh->adja[iadr];
+
+      for (j=0; j<4; j++) {
+        if ( j == voy )  continue;
+        adi = adjb[j] >> 2;
+        if ( !adi )  continue;
+        pt1 = &mesh->tetra[adi];
+        if ( pt1->mark == base && adi != jel ) {
+          if ( !adi || pt1->ref != mesh->tetra[adi].ref )  break;
+        }
+      }
+      /* store tetra */
+      if ( j == 4 ) {
+        pt->mark = base;
+        ++ilist;
+        list->tetra[ilist] = adj;
+      }
+    }
+    if ( ilist > LONMAX - 3 )  return(-1);
+    ++ipil;
+  }
+  while ( ipil <= ilist );
+  /* global overflow */
+  if ( mesh->ne + 2*ilist >= mesh->nemax )  
+    ilist = -ilist;
+  else
+    ilist = MMG_correction_iso(mesh,ip,list,ilist,lon);
+
+if(MMG_cas==1) MMG_nvol++;
+else if(MMG_cas==2 || MMG_cas>20) {
+  MMG_npuiss++;
+  if(MMG_cas>20) MMG_npres++;
+}
+
+  return(ilist);
+}
diff --git a/contrib/mmg3d/build/sources/eigenv.c b/contrib/mmg3d/build/sources/eigenv.c
new file mode 100644
index 0000000000000000000000000000000000000000..8a75bd32b24001c5cf92da39a9c062deba91cbd3
--- /dev/null
+++ b/contrib/mmg3d/build/sources/eigenv.c
@@ -0,0 +1,666 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+/* seeking 1.e-05 accuracy */
+#define  EPSD           1.e-15
+#define  EPSD2          1.e-10
+#define  EPS6           5.e-06
+#define  EPS            1.e-06
+#define  EPSX2          2.e-06
+#define  MAXTOU         50
+
+/* check if numbers are equal */ 
+#define egal(x,y)   ( \
+  (  ((x) == 0.0f) ? (fabs(y) < EPS) : \
+   ( ((y) == 0.0f) ? (fabs(x) < EPS) : \
+     (fabs((x)-(y)) / (fabs(x) + fabs(y)) < EPSX2) )  ) )
+
+
+static double Id[3][3] = { 
+  {1.0, 0.0, 0.0},
+  {0.0, 1.0, 0.0},
+  {0.0, 0.0, 1.0} };
+
+
+/* find root(s) of polynomial:  P(x)= x^3+bx^2+cx+d 
+   return 1: 3 roots,  2: 2 roots,  3: 1 root */
+static int newton3(double p[4],double x[3]) {
+  double     b,c,d,da,db,dc,epsd;
+  double     delta,fx,dfx,dxx;
+  double     fdx0,fdx1,dx0,dx1,x1,x2;
+  int        it,n;
+
+  /* coeffs polynomial, a=1 */
+  b = p[2];
+  c = p[1];
+  d = p[0];
+  n = 1;
+
+  /* 1st derivative of f */
+  da = 3.0;
+  db = 2.0*b;
+
+  /* solve 2nd order eqn */
+  delta = db*db - 4.0*da*c;
+  epsd  = db*db*EPSD2;
+
+  /* inflexion (f'(x)=0, x=-b/2a) */
+  x1 = -db / 6.0f;
+
+  n = 1;
+  if ( delta > epsd ) {
+    delta = sqrt(delta);
+    dx0   = (-db + delta) / 6.0;
+    dx1   = (-db - delta) / 6.0;
+    /* Horner */
+    fdx0 = d + dx0*(c+dx0*(b+dx0));
+    fdx1 = d + dx1*(c+dx1*(b+dx1));
+
+    if ( fabs(fdx0) < EPSD ) {
+      /* dx0: double root, compute single root */
+      n = 2;
+      x[0] = dx0;
+      x[1] = dx0;
+      x[2] = -b - 2.0*dx0;
+      /* check if P(x) = 0 */
+      fx = d + x[2]*(c+x[2]*(b+x[2]));
+      if ( fabs(fx) > EPSD2 ) {
+#ifdef DEBUG
+        fprintf(stderr,"  ## ERR 9100, newton3: fx= %E\n",fx);
+#endif
+        return(0);
+      }
+      return(n);
+    }
+    else if ( fabs(fdx1) < EPSD ) {
+      /* dx1: double root, compute single root */
+      n = 2;
+      x[0] = dx1;
+      x[1] = dx1;
+      x[2] = -b - 2.0*dx1;
+      /* check if P(x) = 0 */
+      fx = d + x[2]*(c+x[2]*(b+x[2]));
+      if ( fabs(fx) > EPSD2 ) {
+#ifdef DEBUG
+        fprintf(stderr,"  ## ERR 9100, newton3: fx= %E\n",fx);
+#endif
+        return(0);
+      }
+      return(n);
+    }
+  }
+
+  else if ( fabs(delta) < epsd ) {
+    /* triple root */
+    n = 3;
+    x[0] = x1;
+    x[1] = x1;
+    x[2] = x1;
+    /* check if P(x) = 0 */
+    fx = d + x[0]*(c+x[0]*(b+x[0]));
+    if ( fabs(fx) > EPSD2 ) {
+#ifdef DEBUG
+      fprintf(stderr,"  ## ERR 9100, newton3: fx= %E\n",fx);
+#endif
+      return(0);
+    }
+    return(n);
+  }
+  
+  else {
+#ifdef DEBUG
+    fprintf(stderr,"  ## ERR 9101, newton3: no real roots\n");
+#endif
+    return(0);
+  }
+
+  /* Newton method: find one root (middle)
+     starting point: P"(x)=0 */
+  x1  = -b / 3.0;
+  dfx =  c + b*x1;
+  fx  = d + x1*(c -2.0*x1*x1);
+  it  = 0;
+  do {
+    x2 = x1 - fx / dfx;
+    fx = d + x2*(c+x2*(b+x2));
+    if ( fabs(fx) < EPSD ) {
+      x[0] = x2;
+      break;
+    }
+    dfx = c + x2*(db + da*x2);
+
+    /* check for break-off condition */
+    dxx = fabs((x2-x1) / x2);
+    if ( dxx < 1.0e-10 ) {
+      x[0] = x2;
+      if ( fabs(fx) > EPSD2 ) {
+        fprintf(stderr,"  ## ERR 9102, newton3, no root found (fx %E).\n",fx);
+        return(0);
+      }
+      break;
+    }
+    else
+      x1 = x2;
+  }
+  while ( ++it < MAXTOU );
+
+  if ( it == MAXTOU ) {
+    x[0] = x1;
+    fx   = d + x1*(c+(x1*(b+x1)));
+    if ( fabs(fx) > EPSD2 ) {
+      fprintf(stderr,"  ## ERR 9102, newton3, no root found (fx %E).\n",fx);
+      return(0);
+    }
+  }
+
+  /* solve 2nd order equation
+     P(x) = (x-sol(1))* (x^2+bb*x+cc)  */
+  db    = b + x[0];
+  dc    = c + x[0]*db;
+  delta = db*db - 4.0*dc;
+  
+  if ( delta <= 0.0 ) {
+    fprintf(stderr,"  ## ERR 9103, newton3, det = 0.\n");
+    return(0);
+  }
+
+  delta = sqrt(delta);
+  x[1] = 0.5 * (-db+delta);
+  x[2] = 0.5 * (-db-delta);
+
+#ifdef DEBUG  
+    /* check for root accuracy */
+    fx = d + x[1]*(c+x[1]*(b+x[1]));
+    if ( fabs(fx) > EPSD2 ) {
+      fprintf(stderr,"  ## ERR 9104, newton3: fx= %E  x= %E\n",fx,x[1]);
+      return(0);
+    }
+    fx = d + x[2]*(c+x[2]*(b+x[2]));
+    if ( fabs(fx) > EPSD2 ) {
+      fprintf(stderr,"  ## ERR 9104, newton3: fx= %E  x= %E\n",fx,x[2]);
+      return(0);
+    }
+  }
+#endif
+
+  return(n);
+}
+
+
+/* find eigenvalues and vectors of a 3x3 symmetric definite
+ * positive matrix 
+ * return order of eigenvalues (1,2,3) or 0 if failed */
+int eigenv(int symmat,double *mat,double lambda[3],double v[3][3]) {
+  double    a11,a12,a13,a21,a22,a23,a31,a32,a33;
+  double    aa,bb,cc,dd,ee,ii,vx1[3],vx2[3],vx3[3],dd1,dd2,dd3;
+  double    maxd,maxm,valm,p[4],w1[3],w2[3],w3[3];
+  int       k,n;
+
+  /* default */
+  memcpy(v,Id,9*sizeof(double));
+  if ( symmat ) {
+    lambda[0] = (double)mat[0];
+    lambda[1] = (double)mat[3];
+    lambda[2] = (double)mat[5];
+
+    maxm = fabs(mat[0]);
+    for (k=1; k<6; k++) {
+      valm = fabs(mat[k]);
+      if ( valm > maxm )  maxm = valm;
+    }
+    /* single float accuracy */
+    if ( maxm < EPS6 )  return(1);
+
+    /* normalize matrix */
+    dd  = 1.0 / maxm;
+    a11 = mat[0] * dd;
+    a12 = mat[1] * dd;
+    a13 = mat[2] * dd;
+    a22 = mat[3] * dd;
+    a23 = mat[4] * dd;
+    a33 = mat[5] * dd;
+
+    /* diagonal matrix */
+    maxd = fabs(a12);
+    valm = fabs(a13);
+    if ( valm > maxd )  maxd = valm;
+    valm = fabs(a23);
+    if ( valm > maxd )  maxd = valm;
+    if ( maxd < EPSD )  return(1);
+
+    a21  = a12;
+    a31  = a13;
+    a32  = a23;
+    
+    /* build characteristic polynomial
+       P(X) = X^3 - trace X^2 + (somme des mineurs)X - det = 0 */
+    aa = a11*a22;
+    bb = a23*a32;
+    cc = a12*a21;
+    dd = a13*a31;
+    p[0] =  a11*bb + a33*(cc-aa) + a22*dd -2.0*a12*a13*a23;
+    p[1] =  a11*(a22 + a33) + a22*a33 - bb - cc - dd;
+    p[2] = -a11 - a22 - a33;
+    p[3] =  1.0;
+  }
+  else {
+    lambda[0] = (double)mat[0];
+    lambda[1] = (double)mat[4];
+    lambda[2] = (double)mat[8];
+
+    maxm = fabs(mat[0]);
+    for (k=1; k<9; k++) {
+      valm = fabs(mat[k]);
+      if ( valm > maxm )  maxm = valm;
+    }
+    if ( maxm < EPS6 )  return(1);
+
+    /* normalize matrix */
+    dd  = 1.0 / maxm;
+    a11 = mat[0] * dd;
+    a12 = mat[1] * dd;
+    a13 = mat[2] * dd;
+    a21 = mat[3] * dd;
+    a22 = mat[4] * dd;
+    a23 = mat[5] * dd;
+    a31 = mat[6] * dd;
+    a32 = mat[7] * dd;
+    a33 = mat[8] * dd;
+
+    /* diagonal matrix */
+    maxd = fabs(a12);
+    valm = fabs(a13);
+    if ( valm > maxd )  maxd = valm;
+    valm = fabs(a23);
+    if ( valm > maxd )  maxd = valm;
+    valm = fabs(a21);
+    if ( valm > maxd )  maxd = valm;
+    valm = fabs(a31);
+    if ( valm > maxd )  maxd = valm;
+     valm = fabs(a32);
+    if ( valm > maxd )  maxd = valm;
+    if ( maxd < EPSD )  return(1);
+
+    /* build characteristic polynomial
+       P(X) = X^3 - trace X^2 + (somme des mineurs)X - det = 0 */
+    aa = a22*a33 - a23*a32;
+    bb = a23*a31 - a21*a33;
+    cc = a21*a32 - a31*a22;
+    ee = a11*a33 - a13*a31;
+    ii = a11*a22 - a12*a21;
+    
+    p[0] =  -a11*aa - a12*bb - a13*cc;
+    p[1] =  aa + ee + ii;
+    p[2] = -a11 - a22 - a33;
+    p[3] =  1.0;
+  }
+
+  /* solve polynomial (find roots using newton) */
+  n = newton3(p,lambda);
+  if ( n <= 0 )  return(0);
+
+  /* compute eigenvectors:
+     an eigenvalue belong to orthogonal of Im(A-lambda*Id) */
+  v[0][0] = 1.0; v[0][1] = v[0][2] = 0.0;
+  v[1][1] = 1.0; v[1][0] = v[1][2] = 0.0;
+  v[2][2] = 1.0; v[2][0] = v[2][1] = 0.0;
+
+  w1[1] = a12;  w1[2] = a13;
+  w2[0] = a21;  w2[2] = a23;
+  w3[0] = a31;  w3[1] = a32;
+
+  if ( n == 1 ) {
+    /* vk = crsprd(wi,wj) */
+    for (k=0; k<3; k++) {
+      w1[0] = a11 - lambda[k];
+      w2[1] = a22 - lambda[k];
+      w3[2] = a33 - lambda[k];
+
+      /* cross product vectors in (Im(A-lambda(i) Id) ortho */
+      vx1[0] = w1[1]*w3[2] - w1[2]*w3[1];
+      vx1[1] = w1[2]*w3[0] - w1[0]*w3[2];
+      vx1[2] = w1[0]*w3[1] - w1[1]*w3[0];
+      dd1    = vx1[0]*vx1[0] + vx1[1]*vx1[1] + vx1[2]*vx1[2];
+
+      vx2[0] = w1[1]*w2[2] - w1[2]*w2[1];
+      vx2[1] = w1[2]*w2[0] - w1[0]*w2[2];
+      vx2[2] = w1[0]*w2[1] - w1[1]*w2[0];
+      dd2    = vx2[0]*vx2[0] + vx2[1]*vx2[1] + vx2[2]*vx2[2];
+
+      vx3[0] = w2[1]*w3[2] - w2[2]*w3[1];
+      vx3[1] = w2[2]*w3[0] - w2[0]*w3[2];
+      vx3[2] = w2[0]*w3[1] - w2[1]*w3[0];
+      dd3    = vx3[0]*vx3[0] + vx3[1]*vx3[1] + vx3[2]*vx3[2];
+
+      /* find vector of max norm */
+      if ( dd1 > dd2 ) {
+        if ( dd1 > dd3 ) {
+          dd1 = 1.0 / sqrt(dd1);
+          v[k][0] = vx1[0] * dd1;
+          v[k][1] = vx1[1] * dd1;
+          v[k][2] = vx1[2] * dd1;
+        }
+	else {
+          dd3 = 1.0 / sqrt(dd3);
+          v[k][0] = vx3[0] * dd3;
+          v[k][1] = vx3[1] * dd3;
+          v[k][2] = vx3[2] * dd3;
+	}
+      }
+      else {
+        if ( dd2 > dd3 ) { 
+          dd2 = 1.0 / sqrt(dd2);
+          v[k][0] = vx2[0] * dd2;
+          v[k][1] = vx2[1] * dd2;
+          v[k][2] = vx2[2] * dd2;
+        }
+        else {
+          dd3 = 1.0 / sqrt(dd3);
+          v[k][0] = vx3[0] * dd3;
+          v[k][1] = vx3[1] * dd3;
+          v[k][2] = vx3[2] * dd3;
+        }  
+      }
+    }
+  }
+
+  /* (vp1,vp2) double,  vp3 simple root */
+  else if ( n == 2 ) {
+    w1[0] = a11 - lambda[2];
+    w2[1] = a22 - lambda[2];
+    w3[2] = a33 - lambda[2];
+
+    /* cross product */
+    vx1[0] = w1[1]*w3[2] - w1[2]*w3[1];
+    vx1[1] = w1[2]*w3[0] - w1[0]*w3[2];
+    vx1[2] = w1[0]*w3[1] - w1[1]*w3[0];
+    dd1 = vx1[0]*vx1[0] + vx1[1]*vx1[1] + vx1[2]*vx1[2];
+ 
+    vx2[0] = w1[1]*w2[2] - w1[2]*w2[1];
+    vx2[1] = w1[2]*w2[0] - w1[0]*w2[2];
+    vx2[2] = w1[0]*w2[1] - w1[1]*w2[0];
+    dd2 = vx2[0]*vx2[0] + vx2[1]*vx2[1] + vx2[2]*vx2[2];
+
+    vx3[0] = w2[1]*w3[2] - w2[2]*w3[1];
+    vx3[1] = w2[2]*w3[0] - w2[0]*w3[2];
+    vx3[2] = w2[0]*w3[1] - w2[1]*w3[0];
+    dd3 = vx3[0]*vx3[0] + vx3[1]*vx3[1] + vx3[2]*vx3[2];
+
+    /* find vector of max norm */
+    if ( dd1 > dd2 ) {
+      if ( dd1 > dd3 ) {
+        dd1 = 1.0 / sqrt(dd1);
+        v[2][0] = vx1[0] * dd1;
+        v[2][1] = vx1[1] * dd1;
+        v[2][2] = vx1[2] * dd1;
+      }
+      else {
+        dd3 = 1.0 / sqrt(dd3);
+        v[2][0] = vx3[0] * dd3;
+        v[2][1] = vx3[1] * dd3;
+        v[2][2] = vx3[2] * dd3;
+      }
+    }
+    else {
+      if ( dd2 > dd3 ) {
+        dd2 = 1.0 / sqrt(dd2);
+        v[2][0] = vx2[0] * dd2;
+        v[2][1] = vx2[1] * dd2;
+        v[2][2] = vx2[2] * dd2;
+      }
+      else {
+        dd3 = 1.0 / sqrt(dd3);
+        v[2][0] = vx3[0] * dd3;
+        v[2][1] = vx3[1] * dd3;
+        v[2][2] = vx3[2] * dd3;
+      }
+    }
+
+    /* compute v1 and v2 in Im(A-vp3*Id) */
+    dd1 = w1[0]*w1[0] + w1[1]*w1[1] + w1[2]*w1[2];
+    dd2 = w2[0]*w2[0] + w2[1]*w2[1] + w2[2]*w2[2];
+    if ( dd1 > dd2 ) {
+      dd1 = 1.0 / sqrt(dd1);
+      v[0][0] = w1[0]*dd1;
+      v[0][1] = w1[1]*dd1;
+      v[0][2] = w1[2]*dd1;
+    }
+    else {
+      dd2 = 1.0 / sqrt(dd2);
+      v[0][0] = w2[0]*dd2;
+      v[0][1] = w2[1]*dd2;
+      v[0][2] = w2[2]*dd2;
+    }
+
+    /* 3rd vector orthogonal */
+    v[1][0] = v[2][1]*v[0][2] - v[2][2]*v[0][1];
+    v[1][1] = v[2][2]*v[0][0] - v[2][0]*v[0][2];
+    v[1][2] = v[2][0]*v[0][1] - v[2][1]*v[0][0];
+    dd1 = v[1][0]*v[1][0] + v[1][1]*v[1][1] + v[1][2]*v[1][2];
+    dd1 = 1.0 / sqrt(dd1);
+    v[1][0] *= dd1;
+    v[1][1] *= dd1;
+    v[1][2] *= dd1;
+  }
+
+  lambda[0] *= maxm;
+  lambda[1] *= maxm;
+  lambda[2] *= maxm;
+
+  /* check accuracy */
+  /*-------------------------------------------------------------------
+  if ( ddebug && symmat ) {
+    double  err,tmpx,tmpy,tmpz;
+    float   m[6];
+    int     i,j;
+
+    k = 0;
+    for (i=0; i<3; i++)
+      for (j=i; j<3; j++)
+        m[k++] = lambda[0]*v[i][0]*v[j][0]
+               + lambda[1]*v[i][1]*v[j][1]
+               + lambda[2]*v[i][2]*v[j][2];
+    err = fabs(mat[0]-m[0]);
+    for (i=1; i<6; i++)
+      if ( fabs(m[i]-mat[i]) > err )  err = fabs(m[i]-mat[i]);
+
+    if ( err > 1.e03*maxm ) {
+      printf("\nProbleme eigenv3: err= %f\n",err*maxm);
+      printf("mat depart :\n");
+      printf("%13.6f  %13.6f  %13.6f\n",mat[0],mat[1],mat[2]);
+      printf("%13.6f  %13.6f  %13.6f\n",mat[1],mat[3],mat[4]);
+      printf("%13.6f  %13.6f  %13.6f\n",mat[2],mat[4],mat[5]);
+      printf("mat finale :\n");
+      printf("%13.6f  %13.6f  %13.6f\n",m[0],m[1],m[2]);
+      printf("%13.6f  %13.6f  %13.6f\n",m[1],m[3],m[4]);
+      printf("%13.6f  %13.6f  %13.6f\n",m[2],m[4],m[5]);
+      printf("lambda : %f %f %f\n",lambda[0],lambda[1],lambda[2]);
+      printf(" ordre %d\n",n);
+      printf("\nOrtho:\n");
+      printf("v1.v2 = %.14f\n",
+             v[0][0]*v[1][0]+v[0][1]*v[1][1]+ v[0][2]*v[1][2]);
+      printf("v1.v3 = %.14f\n",
+             v[0][0]*v[2][0]+v[0][1]*v[2][1]+ v[0][2]*v[2][2]);
+      printf("v2.v3 = %.14f\n",
+             v[1][0]*v[2][0]+v[1][1]*v[2][1]+ v[1][2]*v[2][2]);
+      
+      printf("Consistency\n");
+      for (i=0; i<3; i++) {
+        tmpx = v[0][i]*m[0] + v[1][i]*m[1]
+             + v[2][i]*m[2] - lambda[i]*v[0][i];
+        tmpy = v[0][i]*m[1] + v[1][i]*m[3]
+             + v[2][i]*m[4] - lambda[i]*v[1][i];
+        tmpz = v[0][i]*m[2] + v[1][i]*m[4]
+             + v[2][i]*m[5] - lambda[i]*v[2][i];
+        printf(" Av %d - lambda %d *v %d = %f %f %f\n",
+        i,i,i,tmpx,tmpy,tmpz);
+        
+        printf("w1 %f %f %f\n",w1[0],w1[1],w1[2]);
+        printf("w2 %f %f %f\n",w2[0],w2[1],w2[2]);
+        printf("w3 %f %f %f\n",w3[0],w3[1],w3[2]);
+      }
+      exit(1);
+    }
+  }
+  -------------------------------------------------------------------*/
+
+  return(n);
+}
+
+
+/* eigen value + vector extraction */
+int eigen2(double *mm,double *lambda,double vp[2][2]) {
+  double   m[3],dd,a1,xn,ddeltb,rr1,rr2,ux,uy;
+
+  /* init */
+  ux = 1.0;
+  uy = 0.0;
+
+  /* normalize */
+  memcpy(m,mm,3*sizeof(double));
+  xn = fabs(m[0]);
+  if ( fabs(m[1]) > xn )  xn = fabs(m[1]);
+  if ( fabs(m[2]) > xn )  xn = fabs(m[2]);
+  if ( xn < EPSD2 ) {
+    lambda[0] = lambda[1] = 0.0;
+    vp[0][0] = 1.0; 
+    vp[0][1] = 0.0;
+    vp[1][0] = 0.0;
+    vp[1][1] = 1.0;
+    return(1);
+  }
+  xn = 1.0 / xn;
+  m[0] *= xn;
+  m[1] *= xn;
+  m[2] *= xn;
+
+  if ( egal(m[1],0.0) ) {
+    rr1 = m[0];
+    rr2 = m[2];
+    goto vect;
+  }
+
+  /* eigenvalues of jacobian */
+  a1	 = -(m[0] + m[2]);
+  ddeltb = a1*a1 - 4.0 * (m[0]*m[2] - m[1]*m[1]);
+
+  if ( ddeltb < 0.0 ) {
+    fprintf(stderr,"  Delta: %f\n",ddeltb);
+    ddeltb = 0.0;
+  }
+  ddeltb = sqrt(ddeltb);
+
+  if ( fabs(a1) < EPS ) {
+    rr1 = 0.5 * sqrt(ddeltb);
+    rr2 = -rr1;
+  } 
+  else if ( a1 < 0.0 ) {
+    rr1 = 0.5 * (-a1 + ddeltb);
+    rr2 = (-m[1]*m[1] + m[0]*m[2]) / rr1;
+  }
+  else if ( a1 > 0.0 ) {
+    rr1 = 0.5 * (-a1 - ddeltb);
+    rr2 = (-m[1]*m[1] + m[0]*m[2]) / rr1;
+  }
+  else {
+    rr1 = 0.5 * ddeltb;
+    rr2 = -rr1;
+  }
+
+vect:
+  xn = 1.0 / xn;
+  lambda[0] = rr1 * xn;
+  lambda[1] = rr2 * xn;
+
+  /* eigenvectors */
+  a1 = m[0] - rr1;
+  if ( fabs(a1)+fabs(m[1]) < EPS ) {
+    if (fabs(lambda[1]) < fabs(lambda[0]) ) {
+      ux = 1.0;
+      uy = 0.0;    
+    }
+    else {
+      ux = 0.0;
+      uy = 1.0;
+    }
+  }
+  else if ( fabs(a1) < fabs(m[1]) ) {
+    ux = 1.0;
+    uy = -a1 / m[1];
+  }
+  else if ( fabs(a1) > fabs(m[1]) ) {
+    ux = -m[1] / a1;
+    uy = 1.0;
+  }
+  else if ( fabs(lambda[1]) > fabs(lambda[0]) ) {
+    ux = 0.0;
+    uy = 1.0;
+  }
+  else {
+    ux = 1.0;
+    uy = 0.0;
+  }
+
+  dd = sqrt(ux*ux + uy*uy);
+  dd = 1.0 / dd;
+  if ( fabs(lambda[0]) > fabs(lambda[1]) ) {
+    vp[0][0] =  ux * dd;
+    vp[0][1] =  uy * dd;
+  }
+  else {
+    vp[0][0] =  uy * dd;
+    vp[0][1] = -ux * dd;
+  }
+
+  /* orthogonal vector */
+  vp[1][0] = -vp[0][1];
+  vp[1][1] =  vp[0][0];
+
+  return(1);
+}
diff --git a/contrib/mmg3d/build/sources/eigenv.h b/contrib/mmg3d/build/sources/eigenv.h
new file mode 100644
index 0000000000000000000000000000000000000000..2f2d806a0d81bd2827dd6256b33b352ca59a9a1c
--- /dev/null
+++ b/contrib/mmg3d/build/sources/eigenv.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+int eigenv(int symmat,double *mat,double lambda[3],double v[3][3]);
+int eigen2(double *mm,double *lambda,double vp[2][2]);
diff --git a/contrib/mmg3d/build/sources/hash.c b/contrib/mmg3d/build/sources/hash.c
new file mode 100644
index 0000000000000000000000000000000000000000..1fa340f024378608ce37ea02053b374b10706f96
--- /dev/null
+++ b/contrib/mmg3d/build/sources/hash.c
@@ -0,0 +1,551 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+#define KA     31
+#define KB     57
+#define KC     79
+
+#define KTA     7
+#define KTB    11
+#define KTC    13
+
+
+
+/* local data structures */
+typedef struct {
+  int      min,max,sum,iel,nxt;
+} hface;
+
+typedef struct {
+  int      size,hnxt,nhmax;
+  hface   *item;
+} Hface;
+
+
+int MMG_hashTetra(pMesh mesh) {
+  pTetra    pt,pt1;
+  int       k,kk,pp,l,ll,mins,mins1,maxs,maxs1,sum,sum1,iadr;
+  int      *hcode,*link,hsize;  
+  long int  inival;
+  unsigned char  i,ii,i1,i2,i3;
+  unsigned int    key;
+
+  /* default */
+  if ( abs(mesh->info.imprim) > 5 ) {
+    fprintf(stdout,"  ** SETTING ADJACENCIES\n");
+    fflush(stdout);
+  }
+  /* memory alloc */
+  hcode = (int*)M_calloc(mesh->nemax+1,sizeof(int),"hash");
+  assert(hcode);
+  link  = mesh->adja;
+  hsize = mesh->ne;
+
+  /* init */
+  inival = 2147483647;
+  for (k=0; k<=mesh->ne; k++)
+    hcode[k] = -inival;
+  /* build hash table */
+  for (k=1; k<=mesh->ne; k++) {
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+    for (i=0; i<4; i++) {
+      i1 = MMG_idir[i][0];
+      i2 = MMG_idir[i][1];
+      i3 = MMG_idir[i][2];
+      mins = M_MIN(pt->v[i1],pt->v[i2]);
+      mins = M_MIN(mins,pt->v[i3]);
+      maxs = M_MAX(pt->v[i1],pt->v[i2]);
+      maxs = M_MAX(maxs,pt->v[i3]);
+
+      /* compute key */
+      sum = pt->v[i1] + pt->v[i2] + pt->v[i3];
+      key = KA*mins + KB*maxs + KC*sum;
+      key = key % hsize + 1;
+
+      /* insert */
+      iadr = 4*(k-1) + i+1;      
+      link[iadr] = hcode[key];
+      hcode[key] = -iadr;
+    }
+  }
+
+  /* set adjacency */
+  for (l=4*mesh->ne; l>0; l--) {  
+    if ( link[l] >= 0 )  continue;
+    k = ((l-1) >> 2) + 1;
+    i = (l-1) % 4;
+    i1 = MMG_idir[i][0];
+    i2 = MMG_idir[i][1];
+    i3 = MMG_idir[i][2];
+    pt = &mesh->tetra[k];
+
+    sum  = pt->v[i1] + pt->v[i2] + pt->v[i3];
+    mins = M_MIN(pt->v[i1],pt->v[i2]);
+    mins = M_MIN(mins,pt->v[i3]);
+    maxs = M_MAX(pt->v[i1],pt->v[i2]);
+    maxs = M_MAX(maxs,pt->v[i3]);
+
+    /* accross link */
+    ll = -link[l];
+    pp = 0;
+    link[l] = 0;
+    while ( ll != inival ) {
+      kk = ((ll-1) >> 2) + 1;
+      ii = (ll-1) % 4;
+      i1 = MMG_idir[ii][0];
+      i2 = MMG_idir[ii][1];
+      i3 = MMG_idir[ii][2];
+      pt1  = &mesh->tetra[kk];   
+      sum1 = pt1->v[i1] + pt1->v[i2] + pt1->v[i3];
+      if ( sum1 == sum ) {
+        mins1 = M_MIN(pt1->v[i1],pt1->v[i2]);
+        mins1 = M_MIN(mins1,pt1->v[i3]);
+        if ( mins1 == mins ) {
+          maxs1 = M_MAX(pt1->v[i1],pt1->v[i2]);
+          maxs1 = M_MAX(maxs1,pt1->v[i3]);
+          if ( maxs1 == maxs ) {
+            /* adjacent found */
+            if ( pp != 0 )  link[pp] = link[ll];
+            link[l] = 4*kk + ii;
+            link[ll]= 4*k + i;
+            break;
+          }
+        }
+      }
+      pp = ll;
+      ll = -link[ll];
+    }
+  }
+
+  M_free(hcode);
+  return(1);
+}
+
+
+
+/* hash mesh edge v[0],v[1] (face i of iel) */
+int MMG_hashEdge(pMesh mesh,pHedge hash,int iel,int i,int *v) {
+  int       *adja,iadr,jel,j,key,mins,maxs;
+  hedge     *ha;
+
+  /* compute key */
+  if ( v[0] < v[1] ) {
+    mins = v[0];
+    maxs = v[1];
+  }
+  else {
+    mins = v[1];
+    maxs = v[0];
+  }
+  key = KTA*mins + KTB*maxs;
+  key = key % hash->size;
+  ha  = &hash->item[key];
+
+  if ( ha->min ) {
+    /* identical face */
+    if ( ha->min == mins && ha->max == maxs ) {
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[i] = ha->iel;
+
+      jel  = ha->iel >> 2;
+      j    = ha->iel % 4;
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[j] = iel*4 + i;
+      return(1);
+    }
+    else
+      while ( ha->nxt && ha->nxt < hash->nhmax ) {
+        ha = &hash->item[ha->nxt];
+	    if ( ha->min == mins && ha->max == maxs ) {
+          iadr = (iel-1)*4 + 1;
+          adja = &mesh->adja[iadr];
+          adja[i] = ha->iel;
+
+          jel  = ha->iel >> 2;
+          j    = ha->iel % 4;
+          iadr = (jel-1)*4 + 1;
+          adja = &mesh->adja[iadr];
+          adja[j] = iel*4 + i;
+	      return(1);
+	    }
+      }
+    ha->nxt = hash->hnxt;
+    ha      = &hash->item[hash->hnxt];
+    ++hash->hnxt;
+    if ( hash->hnxt == hash->nhmax ) {
+      fprintf(stdout,"  ## Memory alloc problem (edge): %d\n",hash->nhmax);
+      return(0);
+    }
+  }
+
+  /* insert */
+  ha->min = mins;
+  ha->max = maxs;
+  ha->iel = iel*4 + i;
+  ha->nxt = 0;
+
+  return(1);
+}
+
+
+int MMG_inEdge(pHedge hash,int *v,int *iel,int *ia) {
+  int        key,mins,maxs;
+  hedge     *ha;
+
+  /* compute key */
+  if ( v[0] < v[1] ) {
+    mins = v[0];
+    maxs = v[1];
+  }
+  else {
+    mins = v[1];
+    maxs = v[0];
+  }
+  key = KA*mins + KB*maxs;
+  key = key % hash->size;
+
+  ha = &hash->item[key];
+
+  if ( !ha->min )  return(0);
+  else if ( ha->min == mins && ha->max == maxs ) {
+    *iel = ha->iel / 6;
+    *ia  = ha->iel % 6;
+    return(1);
+  }
+  else if ( ha->nxt ) {
+    do {
+      ha = &hash->item[ha->nxt];
+      if ( ha->min == mins && ha->max == maxs ) {
+        *iel = ha->iel / 6;
+        *ia  = ha->iel % 6;
+        return(1);
+      }
+    }
+    while ( ha->nxt && ha->nxt < hash->nhmax );
+  }
+
+  return(0);
+}
+
+
+/* hash triangles and return
+   iel: face stored, 0 problem */
+int MMG_hashFace(Hface *hash,int iel,int *v) {
+  int        key,mins,maxs,sum;
+  hface     *ht;
+
+  mins = M_MIN(v[0],v[1]);
+  mins = M_MIN(mins,v[2]);
+  maxs = M_MAX(v[0],v[1]);
+  maxs = M_MAX(maxs,v[2]);
+
+  /* compute key */
+  sum = v[0] + v[1] + v[2];
+  key = KTA*mins + KTB*maxs + KTC*sum;
+  key = key % hash->size;
+
+  ht = &hash->item[key];
+
+  if ( ht->min ) {
+    if ( ht->min == mins && ht->max == maxs && ht->sum == sum )
+      return(ht->iel);
+    else
+      while ( ht->nxt && ht->nxt < hash->nhmax ) {
+        ht = &hash->item[ht->nxt];
+	if ( ht->min == mins && ht->max == maxs && ht->sum == sum )
+	  return(ht->iel);
+      }
+    ht->nxt = hash->hnxt;
+    ht      = &hash->item[hash->hnxt];
+    ++hash->hnxt;
+    if ( hash->hnxt == hash->nhmax ) {
+      fprintf(stdout,"  ## memory alloc problem (hash)\n");
+      return(0);
+    }
+  }
+
+  ht->min = mins;
+  ht->max = maxs;
+  ht->sum = sum;
+  ht->iel = iel;
+  ht->nxt = 0;
+
+  return(iel);
+}
+
+
+/* hash triangles : put bdryref and assign a tet per triangle*/
+int MMG_seedTria(pMesh mesh) {
+  pTetra    pt,pt1;
+  pTria     ptt;
+  Hface     htri;
+  int      *adja,v[3],i,k,iel,adj,iadr;
+  int ncompt = 0;
+  
+  /* mem alloc */
+  htri.size  = mesh->nt;
+  htri.hnxt  = htri.size;
+  htri.nhmax = (int)(2*htri.size);
+  htri.item  = (hface*)M_calloc(htri.nhmax+1,sizeof(hface),"markTria"); 
+  assert(htri.item);
+
+  for (k=htri.size; k<htri.nhmax; k++)
+    htri.item[k].nxt = k+1;  
+
+  /* store triangles */
+  for (k=1; k<=mesh->nt; k++) {
+    ptt = &mesh->tria[k];
+    iel = MMG_hashFace(&htri,k,ptt->v);
+    if ( !iel )  return(0);
+  }
+
+  /* init seeds */
+  for (k=1; k<=mesh->ne; k++) {
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+    iadr = 4*(k-1) + 1;
+    adja = &mesh->adja[iadr];
+    for (i=0; i<4; i++) {
+      adj = adja[i] >> 2;
+      pt1 = &mesh->tetra[adj];
+      if ( !adj || ((pt->ref != pt1->ref) ) ) { /*&& (k < adj) IL FAUT TRAITER LES 2 TETS POUR LES SD*/ 
+        v[0] = pt->v[ MMG_idir[i][0] ];
+        v[1] = pt->v[ MMG_idir[i][1] ];
+        v[2] = pt->v[ MMG_idir[i][2] ];
+        iel  = MMG_hashFace(&htri,0,v);
+        if ( !iel )  { /*SD BDRY*/
+          if(mesh->info.imprim > 5) printf("on trouve un tr de SD %d : %d %d %d (between %d et %d)\n",++ncompt,v[0],v[1],v[2],
+                    k,adj);
+          pt->bdryref[i] = 10;
+          //return(0);
+        } else { 
+          /*ref bdry or sd bdry*/
+          ptt = &mesh->tria[iel];
+          pt->bdryref[i] = ptt->ref;
+          if ( !ptt->splx )  ptt->splx = k;
+        }
+      } /*else {
+        pt->bdryref[i] = pt->ref;
+      }*/
+    }
+  }
+  M_free(htri.item);
+  return(1);
+}
+
+
+/* mark boundary vertices */
+int MMG_markBdry(pMesh mesh) {
+  pTetra    pt,pt1;
+  pTria     ptt;
+  pPoint    ppt;
+  int      *adja,adj,iadr,k,i,ii,i1,nt;
+
+  //printf("on arrive avec %d\n",mesh->nt);
+  nt = 0;
+  for (k=1; k<=mesh->ne; k++) {
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+    iadr = 4*(k-1) + 1;
+    adja = &mesh->adja[iadr];
+    for (i=0; i<4; i++) {
+      adj = adja[i] >> 2;
+      pt1 = &mesh->tetra[adj];
+      if ( !adj || ((pt->ref != pt1->ref) && (k < adj)) ) { 
+        for (ii=0; ii<3; ii++) {
+          i1  = MMG_idir[i][ii];
+          ppt = &mesh->point[pt->v[i1]];
+          ppt->tag |= M_BDRY;
+        }
+        ++nt;
+        if ( !mesh->nt ) {
+          if ( (nt < mesh->ntmax-1) ) {  
+            ptt = &mesh->tria[nt];
+            ptt->v[0] = pt->v[ MMG_idir[i][0] ];
+            ptt->v[1] = pt->v[ MMG_idir[i][1] ];
+            ptt->v[2] = pt->v[ MMG_idir[i][2] ];   
+            if (pt->bdryref[i]!=-1) {  
+ 							//if(k==13) printf("pour %d (%d) on met %d : %d %d %d\n",k,i,pt->bdryref[i],pt->v[ MMG_idir[i][0] ]
+							//		,pt->v[ MMG_idir[i][1] ],pt->v[ MMG_idir[i][2] ]);
+             ptt->ref = pt->bdryref[i];
+            } else {
+	            if(mesh->info.imprim < -3 )    
+							printf("on a un tr qui n''a pas de ref : %d %d %d of %d %d \n",ptt->v[0],ptt->v[1],ptt->v[2],k,adj);
+							// if(k==10252) {
+							// 	printf("ses ref : %d %d %d %d\n",pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]);
+							// 	printf("face %d : %d %d %d %d\n",i,pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
+							//   exit(0);
+							// }
+							ptt->ref  = (adj)?M_MIN(pt->ref,pt1->ref):10; 
+							pt->bdryref[i] = (adj)?M_MIN(pt->ref,pt1->ref):10;
+            }
+            if ( !ptt->splx )  ptt->splx = k; 
+          } 
+          else {
+            mesh->nt = nt;
+          }
+        }
+      } else if ( (pt->ref != pt1->ref) ) {  
+        if (pt->bdryref[i]==-1) pt->bdryref[i] = (adj)?M_MIN(pt->ref,pt1->ref):10; 
+			}
+    }
+  }
+
+  if ( !mesh->nt ) {
+    mesh->nt    = nt;
+    mesh->ntnil = mesh->nt + 1;
+    for (k=mesh->ntnil; k<mesh->ntmax-1; k++)
+      mesh->tria[k].v[2] = k+1;
+  }
+  else {
+    //printf("passe-t-on la ?\n");
+    if ( mesh->nt != nt )
+    fprintf(stdout,"  ** WARNING: %d NON-BOUNDARY TRIANGLES : SEVERAL SD CONSIDERED\n",
+            /*abs*/(mesh->nt-nt),nt,mesh->nt);
+
+    MMG_seedTria(mesh); 
+    /*erase triangles*/ 
+    for (k=1; k<=mesh->nt; k++)
+      mesh->tria[k].v[0] = 0;
+     
+  }
+/*printf("on teste\n");
+pTria ptria;  
+for (k=1; k<=mesh->nt; k++) {
+   ptria = &mesh->tria[k];
+if(!(mesh->point[ptria->v[0]].tag & M_BDRY)) printf("pbs0 (%d) %d\n",k,ptria->v[0]); 
+mesh->point[ptria->v[0]].tag |= M_BDRY; 
+mesh->point[ptria->v[1]].tag |= M_BDRY; 
+mesh->point[ptria->v[2]].tag |= M_BDRY; 
+if(!(mesh->point[ptria->v[1]].tag & M_BDRY)) printf("pbs1 (%d) %d\n",k,ptria->v[1]);
+if(!(mesh->point[ptria->v[2]].tag & M_BDRY)) printf("pbs2 (%d) %d\n",k,ptria->v[2]);
+}   */
+  return(1);
+}
+
+/* return 0: no point, np: point stored */ 
+/* edge a-b*/
+int MMG_edgePoint(pHedge hash,int a,int b) {
+  int        key,mins,maxs;
+  hedge     *ha;
+
+  /* compute key */
+  mins = a;
+  maxs = b;
+  if ( a > b ) {
+    mins = b;
+    maxs = a;
+  }
+  key = KA*mins + KB*maxs;
+  key = key % hash->size;
+  ha  = &hash->item[key];
+  //printf("cherche %d %d\n",mins,maxs);
+  if ( !ha->min )  return(0);
+  else if ( ha->min == mins && ha->max == maxs ) {
+    return(ha->iel);
+  }
+  else if ( ha->nxt ) {
+    do {
+      ha = &hash->item[ha->nxt];
+      if ( ha->min == mins && ha->max == maxs ) {
+        return(ha->iel);
+      }
+    }
+    while ( ha->nxt && ha->nxt < hash->nhmax );
+  }
+  return(0);
+}
+
+/*put np on edge a-b*/
+int MMG_edgePut(pHedge hash,int a,int b,int np) {
+  int        key,mins,maxs;
+  hedge     *ha;
+
+  mins = a;
+  maxs = b;
+  if ( a > b ) {
+    mins = b;
+    maxs = a;
+  }                    
+  key = KA*mins + KB*maxs;
+  key = key % hash->size;    
+  ha  = &hash->item[key];
+
+  if ( ha->min ) {
+    /* identical edge */
+    if ( ha->min == mins && ha->max == maxs ) {
+      return(ha->iel);
+    }
+    else {
+      while ( ha->nxt && ha->nxt < hash->nhmax ) {
+        ha = &hash->item[ha->nxt];
+	      if ( ha->min == mins && ha->max == maxs ) {
+	        return(ha->iel);
+	      }
+      }             
+    }
+    ha->nxt = hash->hnxt;
+    ha      = &hash->item[hash->hnxt];
+    ++hash->hnxt;
+    if ( hash->hnxt >= hash->nhmax ) {
+      fprintf(stdout,"  ## Memory alloc problem (edge): %d\n",hash->nhmax);
+      return(0);
+    }
+  }
+  //printf("insert %d %d\n",mins,maxs);
+  /* insert */
+  ha->min = mins;
+  ha->max = maxs;
+  ha->iel = np;
+  ha->nxt = 0;
+
+  return(1);
+}
+
diff --git a/contrib/mmg3d/build/sources/heap.c b/contrib/mmg3d/build/sources/heap.c
new file mode 100644
index 0000000000000000000000000000000000000000..9570ce35024c4dfbc04f7d681eceb33d5e77529f
--- /dev/null
+++ b/contrib/mmg3d/build/sources/heap.c
@@ -0,0 +1,227 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+#define QUAL      1
+#define VECT      2
+
+
+/* compare functions */
+static int MMG_compVector(pMesh mesh,pHeap heap,int i,int j) {
+  pTetra   pt,pt1;
+  pPoint   pp1,pp2;
+  pDispl   pd;
+  int      dmin1,dmin2;
+  short    k;
+
+  pd    = mesh->disp;
+  pt    = &mesh->tetra[i];
+  pt1   = &mesh->tetra[j];
+  dmin1 = INT_MAX;
+  dmin2 = INT_MAX;
+
+  for(k=0; k<4; k++) {
+    pp1 = &mesh->point[pt->v[k]];
+    if ( pp1->tag & M_MOVE && pd->alpha[pt->v[k]] < dmin1 )
+      dmin1 = pd->alpha[pt->v[k]];
+    pp2 = &mesh->point[pt1->v[k]];
+    if ( pp2->tag & M_MOVE && pd->alpha[pt1->v[k]] < dmin2 )
+      dmin2 = pd->alpha[pt1->v[k]];
+  }
+
+  return( dmin1 > dmin2 );
+  /*return( mesh->tetra[i].move < mesh->tetra[j].move );*/
+}
+
+static int MMG_compQuality(pMesh mesh,pHeap heap,int i,int j) {
+  return( (mesh->tetra[i].qual > mesh->tetra[j].qual) );
+}
+
+static int (*MMG_compare)(pMesh ,pHeap ,int ,int );
+
+
+/* heap management */
+static void MMG_hipup(pMesh mesh,pHeap heap,int k) {
+  int     i,j;
+
+  i = k / 2;
+  j = heap->cell[k];
+
+  while ( (i > 0) && MMG_compare(mesh,heap,j,heap->cell[i]) ) {
+    heap->cell[k] = heap->cell[i];
+    heap->link[heap->cell[i]] = k;
+    k  = i;
+    i /= 2;
+  }
+  heap->cell[k] = j;
+  heap->link[j] = k;
+}
+
+
+static void MMG_hipdown(pMesh mesh,pHeap heap,int k) {
+  int      i,j,n;
+
+  i = heap->cell[k];
+  n = heap->curc / 2;
+
+  while ( k <= n ) {
+    j   = k+k;
+    if ( j < heap->curc ) {
+      if ( MMG_compare(mesh,heap,heap->cell[j+1],heap->cell[j]) )
+        j = j+1;
+    }
+    if ( MMG_compare(mesh,heap,i,heap->cell[j]) )
+      break;
+    heap->cell[k] = heap->cell[j];
+    heap->link[heap->cell[j]] = k;
+    k = j;
+  }
+
+  heap->cell[k] = i;
+  heap->link[i] = k;
+}
+
+
+int MMG_hippop(pMesh mesh,pHeap heap) {
+  int    j;
+
+  if ( heap->curc < 1 )  return(0);
+  j = heap->cell[1];
+  if ( heap->curc > 1 ) {
+    heap->cell[1] = heap->cell[heap->curc];
+    heap->link[ heap->cell[heap->curc--] ] = 1;
+    MMG_hipdown(mesh,heap,1);
+  }
+  else
+    heap->curc--;
+
+  return(j);
+}
+
+
+int MMG_hipput(pMesh mesh,pHeap heap,int k) {
+  if ( heap->curc >= heap->size )  return(0);
+
+  ++heap->curc;
+  heap->cell[heap->curc] = k;
+  heap->link[k]          = heap->curc;
+  MMG_hipup(mesh,heap,heap->curc);
+
+  return(1);
+}
+
+
+void MMG_hiprep(pMesh mesh,pHeap heap,int k) {
+  MMG_hipdown(mesh,heap,heap->link[k]);
+  MMG_hipup(mesh,heap,heap->link[k]);
+}
+
+
+void MMG_hipdel(pMesh mesh,pHeap heap,int k) {
+  if ( heap->link[k] )
+    MMG_hipdown(mesh,heap,heap->link[k]);
+}
+
+
+Heap *MMG_hipini(pMesh mesh,int nemax,short cmpfunc,double declic,int base) {
+  pTetra   pt;
+  pPoint   ppt;
+  pDispl   pd;
+  pHeap    heap;
+  int      i,k,nm,dmin;
+
+  /* mem alloc */
+  heap = (Heap*)M_malloc(sizeof(Heap),"hipini");
+  assert(heap);
+  heap->size = nemax+1;
+  heap->cell = (int*)M_calloc(heap->size,sizeof(int),"hipini");
+  assert(heap->cell);
+  heap->link = (int*)M_calloc(heap->size,sizeof(int),"hipini");
+  assert(heap->link);
+  heap->curc = 0;
+
+  pd  = mesh->disp;
+
+  /* assign function */
+  if ( cmpfunc == QUAL ) {
+    MMG_compare = MMG_compQuality;
+    for (k=1; k<=mesh->ne; k++) {
+      pt = &mesh->tetra[k];
+      if ( !pt->v[0] || pt->qual < declic )    continue;
+      else if ( base > 0 && pt->flag < base )  continue;
+      else if ( !MMG_hipput(mesh,heap,k) )         return(0);
+    }
+  }
+  else {
+    MMG_compare = MMG_compVector;
+    for (k=1; k<=mesh->ne; k++) {
+      pt = &mesh->tetra[k];
+      if ( !pt->v[0] )  continue;
+      dmin = INT_MAX;
+      nm   = 0;
+      for (i=0; i<4; i++) {
+        ppt = &mesh->point[ pt->v[i] ];
+        if ( ppt->tag & M_MOVE ) {
+          if ( pd->alpha[ 3*(pt->v[i]-1) + 1 ] < dmin )  dmin = pd->alpha[ 3*(pt->v[i]-1) + 1 ];
+          nm++;
+        }
+      }
+      if ( nm ) {
+        if ( !MMG_hipput(mesh,heap,k) )  return(0);
+      }
+    }
+  }
+
+  return(heap);
+}
+
+
+void MMG_hipfree(pHeap heap) {
+  M_free(heap->cell);
+  M_free(heap->link);
+  M_free(heap);
+  heap = 0;
+}
diff --git a/contrib/mmg3d/build/sources/inout.c b/contrib/mmg3d/build/sources/inout.c
new file mode 100644
index 0000000000000000000000000000000000000000..09e719fab4e0d43a4d31e8adfbe1f75a0366e922
--- /dev/null
+++ b/contrib/mmg3d/build/sources/inout.c
@@ -0,0 +1,1417 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+
+extern short	       MMG_imprim;
+#define sw 4
+#define sd 8
+
+int MMG_swapbin(int sbin)
+{
+	int inv; 
+  char *p_in = (char *) &sbin;
+  char *p = (char *)&inv;
+
+ 
+  p[0] = p_in[3];
+  p[1] = p_in[2];
+  p[2] = p_in[1];
+  p[3] = p_in[0]; 
+  
+  return(inv);
+  /*unsigned char c1, c2, c3, c4;
+
+  c1 = sbin & 255;
+  c2 = (sbin >> 8) & 255;
+  c3 = (sbin >> 16) & 255;
+  c4 = (sbin >> 24) & 255;
+  
+  return ((int)c1 << 24) + ((int)c2 << 16) + ((int)c3 << 8) + c4;   */
+
+}
+float MMG_swapf(float sbin)
+{ 
+  float out;
+  char *p_in = (char *) &sbin; 
+  char *p_out = (char *) &out; 
+  p_out[0] = p_in[3]; 
+  p_out[1] = p_in[2]; 
+  p_out[2] = p_in[1]; 
+  p_out[3] = p_in[0];
+  
+  return(out);
+}
+double MMG_swapd(double sbin)
+{
+  float out;
+  char *p_in = (char *) &sbin; 
+  char *p_out = (char *) &out; 
+  int i;
+  
+  for(i=0;i<8;i++)
+  {
+    p_out[i] = p_in[7-i];
+  }          
+  //printf("CONVERTION DOUBLE\n");
+  return(out);
+}
+
+/* read mesh data */
+int MMG_loadMesh(pMesh mesh,char *filename) {  
+  FILE*            inm;
+  Hedge    				 hed,hed2;
+  pPoint       	   ppt;
+  pTetra           pt;
+  pTria            pt1;
+  int              k,dim,ref,bin,bpos,i,tmp;   
+  long             posnp,posnt,posne,posnhex,posnpris,posncor,posned,posnq;
+  char            *ptr,data[128],chaine[128];
+  int              nhex,npris,netmp,ncor,ned,nq;
+  int              p0,p1,p2,p3,p4,p5,p6,p7;  
+  int              binch,bdim,iswp,nu1,nu2,nimp,ne;       
+  float            fc;
+  
+
+  posnp = posnt = posne = posnhex = posnpris = 0;
+  netmp = ncor = ned = 0;
+  bin = 0;
+  iswp = 0;
+  mesh->np = mesh->nt = mesh->ne = mesh->ncor = 0; 
+  npris = nhex = nq = 0;
+  
+  strcpy(data,filename);
+  ptr = strstr(data,".mesh");  
+  if ( !ptr ) {
+    strcat(data,".meshb");
+    if( !(inm = fopen(data,"rb")) ) {
+      ptr = strstr(data,".mesh");
+      *ptr = '\0';
+      strcat(data,".mesh");
+      if( !(inm = fopen(data,"r")) ) {
+        fprintf(stderr,"  ** %s  NOT FOUND.\n",data);
+        return(0);
+      }
+    } else {
+      bin = 1;
+    }
+  }
+  else {
+    ptr = strstr(data,".meshb");
+    if( !ptr ) {
+      if( !(inm = fopen(data,"r")) ) {
+        fprintf(stderr,"  ** %s  NOT FOUND.\n",data);
+        return(0);
+      }      
+    } else {
+      bin = 1;
+      if( !(inm = fopen(data,"rb")) ) {
+        fprintf(stderr,"  ** %s  NOT FOUND.\n",data);
+        return(0);
+      }
+      
+    }  
+  }
+
+  fprintf(stdout,"  %%%% %s OPENED\n",data);
+  if (!bin) {
+    strcpy(chaine,"D");     
+    while(fscanf(inm,"%s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) { 
+      if(!strncmp(chaine,"MeshVersionFormatted",strlen("MeshVersionFormatted"))) {
+          fscanf(inm,"%d",&mesh->ver);
+          continue;
+      } else if(!strncmp(chaine,"Dimension",strlen("Dimension"))) {
+          fscanf(inm,"%d",&dim);
+          if(dim!=3) {
+            fprintf(stdout,"BAD DIMENSION : %d\n",dim);
+            return(0);
+          }
+          continue;
+      } else if(!strncmp(chaine,"Vertices",strlen("Vertices"))) {
+        fscanf(inm,"%d",&mesh->np); 
+        posnp = ftell(inm);
+        continue;
+      } else if(!strncmp(chaine,"Triangles",strlen("Triangles"))) {
+        fscanf(inm,"%d",&mesh->nt); 
+        posnt = ftell(inm);
+        continue;
+      } else if(!strncmp(chaine,"Tetrahedra",strlen("Tetrahedra"))) {
+        fscanf(inm,"%d",&mesh->ne); 
+        netmp = mesh->ne;
+        posne = ftell(inm);
+        continue;
+      } else if(!strncmp(chaine,"Hexahedra",strlen("Hexahedra"))) { 
+        assert(abs(mesh->info.option)==10);  
+        fscanf(inm,"%d",&nhex); 
+				//nhex=0;
+        posnhex = ftell(inm);
+        continue;
+      } else if(!strncmp(chaine,"Pentahedra",strlen("Pentahedra"))) { 
+        assert(abs(mesh->info.option)==10); 
+        fscanf(inm,"%d",&npris);
+				//npris=0;
+        posnpris = ftell(inm);
+        continue;
+      } else if(!strncmp(chaine,"Corners",strlen("Corners"))) { 
+        fscanf(inm,"%d",&ncor); 
+        posncor = ftell(inm);
+        continue;
+      } else if(!strncmp(chaine,"Edges",strlen("Edges"))) { 
+	      fscanf(inm,"%d",&ned); 
+	      posned = ftell(inm);
+	      continue;
+	    } else if(abs(mesh->info.option)==10 && !strncmp(chaine,"Quadrilaterals",strlen("Quadrilaterals"))) {
+		    fscanf(inm,"%d",&nq); 
+		    posnq = ftell(inm);
+		    continue;
+		  }
+    }  
+  } else {
+    bdim = 0;
+    fread(&mesh->ver,sw,1,inm);
+    iswp=0;   
+    if(mesh->ver==16777216) 
+      iswp=1;    
+    else if(mesh->ver!=1) {
+      fprintf(stdout,"BAD FILE ENCODING\n");
+    } 
+    fread(&mesh->ver,sw,1,inm); 
+    if(iswp) mesh->ver = MMG_swapbin(mesh->ver); 
+    while(fread(&binch,sw,1,inm)!=0 && binch!=54 ) {  
+      if(iswp) binch=MMG_swapbin(binch);      
+      if(binch==54) break;  
+      if(!bdim && binch==3) {  //Dimension
+        fread(&bdim,sw,1,inm);  //NulPos=>20
+        if(iswp) bdim=MMG_swapbin(bdim);
+        fread(&bdim,sw,1,inm);  
+        if(iswp) bdim=MMG_swapbin(bdim);
+        if(bdim!=3) {
+          fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim);
+          exit(0);
+          return(1);
+        }
+        continue;
+      } else if(!mesh->np && binch==4) {  //Vertices
+        fread(&bpos,sw,1,inm); //NulPos 
+        if(iswp) bpos=MMG_swapbin(bpos);
+        fread(&mesh->np,sw,1,inm); 
+        if(iswp) mesh->np=MMG_swapbin(mesh->np);
+        posnp = ftell(inm);     
+        rewind(inm);
+        fseek(inm,bpos,SEEK_SET);        
+        continue;
+      }  else if(!mesh->nt && binch==6) {//Triangles
+        fread(&bpos,sw,1,inm); //NulPos 
+        if(iswp) bpos=MMG_swapbin(bpos);
+        fread(&mesh->nt,sw,1,inm); 
+        if(iswp) mesh->nt=MMG_swapbin(mesh->nt);
+        posnt = ftell(inm); 
+        rewind(inm);
+        fseek(inm,bpos,SEEK_SET);        
+        continue;
+       } else if(!mesh->ne && binch==8) {  
+         fread(&bpos,sw,1,inm); //NulPos 
+         if(iswp) bpos=MMG_swapbin(bpos);
+         fread(&mesh->ne,sw,1,inm); 
+         if(iswp) mesh->ne=MMG_swapbin(mesh->ne);
+         netmp = mesh->ne;
+         posne = ftell(inm);
+         rewind(inm);
+         fseek(inm,bpos,SEEK_SET);        
+         continue;
+       } else if(!nhex && binch==10) { 
+         assert(abs(mesh->info.option)==10);
+         fread(&bpos,sw,1,inm); //NulPos 
+         if(iswp) bpos=MMG_swapbin(bpos);
+         fread(&nhex,sw,1,inm); 
+         if(iswp) nhex=MMG_swapbin(nhex);
+         posnhex = ftell(inm);
+         rewind(inm);
+         fseek(inm,bpos,SEEK_SET);        
+         continue;
+       } else if(!npris && binch==9) { 
+         assert(abs(mesh->info.option)==10);
+         fread(&bpos,sw,1,inm); //NulPos 
+         if(iswp) bpos=MMG_swapbin(bpos);
+         fread(&npris,sw,1,inm); 
+         if(iswp) npris=MMG_swapbin(npris);
+         posnpris = ftell(inm);
+         rewind(inm);
+         fseek(inm,bpos,SEEK_SET);        
+         continue;
+       } else if(!ncor && binch==13) { 
+         fread(&bpos,sw,1,inm); //NulPos 
+         if(iswp) bpos=MMG_swapbin(bpos);
+         fread(&ncor,sw,1,inm);          
+         if(iswp) ncor=MMG_swapbin(ncor);
+         posncor = ftell(inm);
+         rewind(inm);
+         fseek(inm,bpos,SEEK_SET);        
+         continue;
+        } else if(!ned && binch==5) { //Edges
+	       fread(&bpos,sw,1,inm); //NulPos 
+	       if(iswp) bpos=MMG_swapbin(bpos);
+	       fread(&ned,sw,1,inm); 
+	       if(iswp) ned=MMG_swapbin(ned);
+	       posned = ftell(inm);
+	       rewind(inm);
+	       fseek(inm,bpos,SEEK_SET);        
+	       continue;
+	      } else {
+         //printf("on traite ? %d\n",binch);
+         fread(&bpos,sw,1,inm); //NulPos 
+         if(iswp) bpos=MMG_swapbin(bpos);
+         //printf("on avance... Nulpos %d\n",bpos);         
+         rewind(inm);
+         fseek(inm,bpos,SEEK_SET);        
+       }     
+    }            
+    
+  }
+
+  if ( abs(mesh->info.option)==10 ) {
+    fprintf(stdout,"  -- READING %8d HEXA %8d PRISMS\n",nhex,npris);  
+    if(!mesh->ne) netmp = 0;  
+    mesh->ne += 6*nhex + 3*npris; 
+  }
+
+  if ( abs(mesh->info.imprim) > 5 )
+    fprintf(stdout,"  -- READING DATA FILE %s\n",data);
+
+  if ( !mesh->np || !mesh->ne ) {
+    fprintf(stdout,"  ** MISSING DATA\n");
+    return(0);
+  }
+  if ( !MMG_zaldy(mesh) )  return(0);
+
+  /* read mesh vertices */
+  mesh->npfixe = mesh->np;
+  rewind(inm);
+  fseek(inm,posnp,SEEK_SET);
+  for (k=1; k<=mesh->np; k++) {
+    ppt = &mesh->point[k];
+    if (mesh->ver < 2) { /*float*/ 
+      if (!bin) {
+        for (i=0 ; i<3 ; i++) {
+          fscanf(inm,"%f",&fc);
+          ppt->c[i] = (double) fc;
+        } 
+        fscanf(inm,"%d",&ppt->ref);
+      } else {
+        for (i=0 ; i<3 ; i++) {
+          fread(&fc,sw,1,inm); 
+          if(iswp) fc=MMG_swapf(fc);    
+          ppt->c[i] = (double) fc;
+        }     
+        fread(&ppt->ref,sw,1,inm);         
+        if(iswp) ppt->ref=MMG_swapbin(ppt->ref);    
+      }
+    } else {
+      if (!bin) 
+        fscanf(inm,"%lf %lf %lf %d",&ppt->c[0],&ppt->c[1],&ppt->c[2],&ppt->ref); 
+      else {
+        for (i=0 ; i<3 ; i++) { 
+          fread(&ppt->c[i],sd,1,inm);
+          if(iswp) ppt->c[i]=MMG_swapd(ppt->c[i]); 
+        }   
+        fread(&ppt->ref,sw,1,inm);         
+        if(iswp) ppt->ref=MMG_swapbin(ppt->ref);    
+      }  
+    }             
+    ppt->tag  = M_UNUSED;    
+  }
+
+  /* read mesh triangles */
+  mesh->ntfixe = mesh->nt;
+  rewind(inm);
+  fseek(inm,posnt,SEEK_SET);
+  for (k=1; k<=mesh->nt; k++) {
+    pt1 = &mesh->tria[k]; 
+    if (!bin)
+      fscanf(inm,"%d %d %d %d",&pt1->v[0],&pt1->v[1],&pt1->v[2],&pt1->ref);
+    else {
+      for (i=0 ; i<3 ; i++) { 
+        fread(&pt1->v[i],sw,1,inm); 
+        if(iswp) pt1->v[i]=MMG_swapbin(pt1->v[i]);    
+      }
+      fread(&pt1->ref,sw,1,inm); 
+      if(iswp) pt1->ref=MMG_swapbin(pt1->ref);           
+    }  
+  }
+  /* read mesh quads (option 10)*/ 
+	if(abs(mesh->info.option)==10) { 
+		fprintf(stdout,"     QUADS READING %d\n",nq);
+    mesh->ntfixe += 4*nq;
+    rewind(inm);
+    fseek(inm,posnq,SEEK_SET);
+    for (k=1; k<=nq; k++) {
+      if (!bin)
+        fscanf(inm,"%d %d %d %d %d",&p0,&p1,&p2,&p3,&ref);
+      else {
+        fread(&p0,sw,1,inm); 
+        if(iswp) p0=MMG_swapbin(p0);    
+        fread(&p1,sw,1,inm); 
+        if(iswp) p1=MMG_swapbin(p1);    
+        fread(&p2,sw,1,inm); 
+        if(iswp) p2=MMG_swapbin(p2);    
+        fread(&p3,sw,1,inm); 
+        if(iswp) p3=MMG_swapbin(p3);    
+	      fread(&pt1->ref,sw,1,inm); 
+	      if(iswp) ref=MMG_swapbin(ref);           
+      } 
+      pt1 = &mesh->tria[++mesh->nt]; 
+			pt1->v[0] = p0;
+			pt1->v[1] = p1;
+			pt1->v[2] = p2;
+			pt1->ref  = ref;
+      pt1 = &mesh->tria[++mesh->nt]; 
+			pt1->v[0] = p0;
+			pt1->v[1] = p2;
+			pt1->v[2] = p3;
+			pt1->ref  = ref;
+      pt1 = &mesh->tria[++mesh->nt]; 
+			pt1->v[0] = p0;
+			pt1->v[1] = p1;
+			pt1->v[2] = p3;
+			pt1->ref  = ref;
+      pt1 = &mesh->tria[++mesh->nt]; 
+			pt1->v[0] = p1;
+			pt1->v[1] = p2;
+			pt1->v[2] = p3;
+			pt1->ref  = ref;
+ 
+    }
+  }
+
+	/*read and store edges*/
+  if (ned) {         
+	  if ( !MMG_zaldy4(&hed,ned) ) {
+      if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES IGNORED\n"); 
+			ned = 0;
+    }   
+		mesh->ned = ned;
+    rewind(inm);
+    fseek(inm,posned,SEEK_SET); 
+    for (k=1; k<=ned; k++) { 
+      if (!bin)
+        fscanf(inm,"%d %d %d",&nu1,&nu2,&ref);
+      else {
+        fread(&nu1,sw,1,inm); 
+        if(iswp) nu1=MMG_swapbin(nu1);    
+        fread(&nu2,sw,1,inm); 
+        if(iswp) nu2=MMG_swapbin(nu2);    
+        fread(&ref,sw,1,inm); 
+        if(iswp) ref=MMG_swapbin(ref);    
+      }  
+			if(MMG_edgePut(&hed,nu1,nu2,2)>1) {
+				fprintf(stdout,"  ## WARNING DOUBLE EDGE : %d %d\n",nu1,nu2);
+			}
+    }
+  }
+
+  /* read mesh tetrahedra */
+  mesh->nefixe = mesh->ne;
+  rewind(inm);
+  fseek(inm,posne,SEEK_SET);
+  for (k=1; k<=netmp; k++) { 
+    pt = &mesh->tetra[k];
+    if (!bin) 
+      fscanf(inm,"%d %d %d %d %d",&pt->v[0],&pt->v[1],&pt->v[2],&pt->v[3],&ref); 
+    else {                                                                        
+	
+      for (i=0 ; i<4 ; i++) { 
+        fread(&pt->v[i],sw,1,inm); 
+        if(iswp) pt->v[i]=MMG_swapbin(pt->v[i]);    
+      }
+      fread(&ref,sw,1,inm);         
+      if(iswp) ref=MMG_swapbin(ref);           
+    }  
+    pt->ref  = ref;//0;//ref ;  
+    for(i=0 ; i<4 ; i++)
+      pt->bdryref[i] = -1;  
+    
+		if (ned) {
+	    for(i=0 ; i<6 ; i++) {                         
+				nu1 = pt->v[MMG_iare[i][0]];
+				nu2 = pt->v[MMG_iare[i][1]];
+	      pt->bdryinfo[i] = MMG_edgePoint(&hed,nu1,nu2);
+			}  			
+			
+		} else {
+	    for(i=0 ; i<6 ; i++)
+	      pt->bdryinfo[i] = 0;  			
+		}
+  }
+  if (ned) M_free(hed.item); 
+
+  /*read corners*/ 
+  if (ncor) {
+    rewind(inm);
+    fseek(inm,posncor,SEEK_SET); 
+    mesh->ncor = ncor;
+    for (k=1; k<=ncor; k++) { 
+      if (!bin)
+        fscanf(inm,"%d",&ref);
+      else {
+        fread(&ref,sw,1,inm); 
+        if(iswp) ref=MMG_swapbin(ref);    
+      }  
+      ppt = &mesh->point[ref];
+      ppt->geom = M_CORNER; 
+    } 
+  }
+   
+	
+  if ( abs(mesh->info.option)==10 ) { 
+    if(bin) {
+      printf("NOT SUPPORTED\n");
+      exit(0);
+    } 
+	  if ( !MMG_zaldy4(&hed2,3*npris+6*nhex) ) {
+      if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : PRISM IGNORED\n"); 
+			npris = 0;
+			nhex  = 0;
+    }   
+
+    /*read hexa and transform to tetra*/
+    rewind(inm);
+    fseek(inm,posnhex,SEEK_SET);
+    for (k=1; k<=nhex; k++) {   
+      fscanf(inm,"%d %d %d %d %d %d %d %d %d",&p0,&p1,&p2,&p3,&p4,&p5,&p6,&p7,&ref); 
+      //fscanf(inm,"%d %d %d %d %d %d %d %d %d",&p0,&p4,&p2,&p1,&p3,&p5,&p6,&p7,&ref); 
+      //printf("hex %d : %d %d %d %d %d %d %d %d\n",k,p0,p1,p2,p3,p4,p5,p6,p7);   
+			MMG_cuthex(mesh,&hed2,netmp+(k-1)*6,p0,p1,p2,p3,p4,p5,p6,p7,ref);
+    }  
+    
+    /*read prism and transform to tetra
+		---> compatibility pbs ==> hash edge and switch case*/  
+    rewind(inm);
+    fseek(inm,posnpris,SEEK_SET); 
+		nimp = 0; 
+		ne = netmp+6*nhex;
+    for (k=1; k<=npris; k++) {
+      fscanf(inm,"%d %d %d %d %d %d %d",&p0,&p1,&p2,&p3,&p4,&p5,&ref); 
+			if(!MMG_cutprism(mesh,&hed2,ne,p0,p1,p2,p3,p4,p5,ref))
+			{
+				if(mesh->info.imprim < 0 ) fprintf(stdout,"DECOMPOSITION PRISM INVALID \n\n"); 
+				mesh->ne += 5;
+				ne += 8;
+				nimp++; 
+				continue;
+			}
+			ne += 3;
+    }
+		if(abs(mesh->info.imprim) > 3 )fprintf(stdout,"     %d INVALID DECOMPOSITION\n\n",nimp);
+  }
+  
+  if ( abs(mesh->info.imprim) > 3 ) {
+    fprintf(stdout,"     NUMBER OF GIVEN VERTICES   %8d\n",mesh->npfixe);
+    if ( mesh->ntfixe )
+      fprintf(stdout,"     NUMBER OF GIVEN TRIANGLES  %8d\n",mesh->ntfixe);
+    fprintf(stdout,"     NUMBER OF GIVEN TETRAHEDRA %8d\n",mesh->nefixe);
+    if ( ncor )
+      fprintf(stdout,"     NUMBER OF GIVEN CORNERS    %8d\n",ncor);
+    if ( ned )
+      fprintf(stdout,"     NUMBER OF GIVEN EDGES      %8d\n",ned);
+  }
+ fclose(inm);
+ return(1);
+}
+
+
+/* load solution (metric) */
+int MMG_loadSol(pSol sol,char *filename,int npmax) { 
+  FILE       *inm;   
+  float       fsol;
+  double      tmp;       
+  int         binch,bdim,iswp;
+  int         k,i,isol,type,bin,dim,btyp,bpos;
+  long        posnp;
+  char        *ptr,data[128],chaine[128];
+  
+  posnp = 0; 
+  bin   = 0;
+  iswp  = 0; 
+
+  strcpy(data,filename);
+  ptr = strstr(data,".mesh");
+  if ( ptr )  *ptr = '\0';
+  strcat(data,".solb");
+  if( !(inm = fopen(data,"rb")) ) {
+    ptr  = strstr(data,".solb");
+    *ptr = '\0';
+    strcat(data,".sol");
+    if( !(inm = fopen(data,"r")) ) {
+      fprintf(stderr,"  ** %s  NOT FOUND.\n",data);
+      return(1);
+    }
+  } else {
+    bin = 1;
+  }
+  fprintf(stdout,"  %%%% %s OPENED\n",data);
+
+   
+  if(!bin) {   
+    strcpy(chaine,"DDD");
+    while(fscanf(inm,"%s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) { 
+      if(!strncmp(chaine,"Dimension",strlen("Dimension"))) {
+          fscanf(inm,"%d",&dim);
+          if(dim!=3) {
+            fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim); 
+            return(1);
+          }
+          continue;
+      } else if(!strncmp(chaine,"SolAtVertices",strlen("SolAtVertices"))) {
+        fscanf(inm,"%d",&sol->np); 
+        fscanf(inm,"%d",&type); 
+        if(type!=1) {
+          fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
+          return(1);
+        }
+        fscanf(inm,"%d",&btyp);
+        posnp = ftell(inm);
+        break;
+      } 
+    }            
+  } else {     
+    fread(&binch,sw,1,inm); 
+    iswp=0;   
+    if(binch==16777216) iswp=1;    
+    else if(binch!=1) {
+      fprintf(stdout,"BAD FILE ENCODING\n");
+    } 
+    fread(&sol->ver,sw,1,inm); 
+    if(iswp) sol->ver = MMG_swapbin(sol->ver); 
+    while(fread(&binch,sw,1,inm)!=EOF && binch!=54 ) {
+      if(iswp) binch=MMG_swapbin(binch);      
+      if(binch==54) break;  
+      if(binch==3) {  //Dimension
+        fread(&bdim,sw,1,inm);  //NulPos=>20
+        if(iswp) bdim=MMG_swapbin(bdim);
+        fread(&bdim,sw,1,inm);
+        if(iswp) bdim=MMG_swapbin(bdim);
+        if(bdim!=3) {
+          fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim);
+          exit(0);
+          return(1);
+        }
+        continue;
+      } else if(binch==62) {  //SolAtVertices
+        fread(&binch,sw,1,inm); //NulPos
+        if(iswp) binch=MMG_swapbin(binch);
+        fread(&sol->np,sw,1,inm); 
+        if(iswp) sol->np=MMG_swapbin(sol->np);
+        fread(&binch,sw,1,inm); //nb sol
+        if(iswp) binch=MMG_swapbin(binch);
+        if(binch!=1) {
+          fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
+          return(1);
+        }
+        fread(&btyp,sw,1,inm); //typsol
+        if(iswp) btyp=MMG_swapbin(btyp);
+        posnp = ftell(inm);
+        break;
+      } else {
+        fread(&bpos,sw,1,inm); //Pos 
+        if(iswp) bpos=MMG_swapbin(bpos);
+        rewind(inm);
+        fseek(inm,bpos,SEEK_SET);        
+      } 
+    }            
+    
+  }       
+  if ( !sol->np ) {
+    fprintf(stdout,"  ** MISSING DATA\n");
+    return(1);
+  }
+
+  if ( btyp!= 1 && btyp!=3 ) {
+    fprintf(stdout,"  ** DATA IGNORED\n");
+    sol->np = 0;
+    return(1);
+  }
+  
+  sol->offset = (btyp==1) ? 1 : 6;
+
+  if ( abs(MMG_imprim) > 5 )
+    fprintf(stdout,"  -- READING DATA FILE %s\n",data);
+
+  if ( !sol->np ) {
+    fprintf(stdout,"  ** MISSING DATA\n");
+    return(0);
+  }
+  sol->npfixe = sol->np;
+  sol->npmax  = npmax;
+  if ( !MMG_zaldy3(sol) )  return(0);
+
+  /* read mesh solutions */
+  sol->npfixe = sol->np;
+  rewind(inm);
+  fseek(inm,posnp,SEEK_SET);  
+  for (k=1; k<=sol->np; k++) {
+    isol = (k-1) * sol->offset + 1;
+    if (sol->ver == 1) { 
+      for (i=0; i<sol->offset; i++) {
+        if(!bin){
+          fscanf(inm,"%f",&fsol);    
+          sol->met[isol + i] = (double) fsol;
+        } else {
+          fread(&fsol,sw,1,inm);             
+          if(iswp) fsol=MMG_swapf(fsol);
+          sol->met[isol + i] = (double) fsol;
+        }
+      } 
+    } else {
+      for (i=0; i<sol->offset; i++) {
+        if(!bin){
+          fscanf(inm,"%lf",&sol->met[isol + i]); 
+
+        } else {
+          fread(&sol->met[isol + i],sd,1,inm);       
+          if(iswp) sol->met[isol + i]=MMG_swapd(sol->met[isol + i]);
+        } 
+      } 
+    }             
+    /* MMG_swap data */
+    if ( sol->offset == 6 ) {
+      tmp                = sol->met[isol + 2];
+      sol->met[isol + 2] = sol->met[isol + 3];
+      sol->met[isol + 3] = tmp;
+    }
+  }
+
+  if ( abs(MMG_imprim) > 3 )
+    fprintf(stdout,"     NUMBER OF GIVEN DATA       %8d\n",sol->npfixe);
+
+  fclose(inm);   
+  return(1);  
+}
+
+
+int MMG_loadVect(pMesh mesh,char *filename,int npmax) {
+  FILE       *inm;   
+  pDispl       pd;
+  float       fsol;
+  int         binch,bdim,iswp;
+  int         k,i,type,bin,dim,btyp,bpos,iadr;
+  long        posnp;
+  char        *ptr,data[128],chaine[128];
+  
+  pd = mesh->disp;
+  
+  posnp = 0; 
+  bin   = 0; 
+  iswp  = 0;
+
+  strcpy(data,filename);
+  ptr = strstr(data,".mesh");
+  if ( ptr )  *ptr = '\0';
+  strcat(data,".solb");
+  if( !(inm = fopen(data,"rb")) ) {
+    ptr  = strstr(data,".solb");
+    *ptr = '\0';
+    strcat(data,".sol");
+    if( !(inm = fopen(data,"r")) ) {
+      fprintf(stderr,"  ** %s  NOT FOUND.\n",data);
+      return(1);
+    }
+  } else {
+    bin = 1;
+  }
+  fprintf(stdout,"  %%%% %s OPENED\n",data);
+
+   
+  if(!bin) {   
+    strcpy(chaine,"DDD");
+    while(fscanf(inm,"%s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) { 
+      if(!strncmp(chaine,"Dimension",strlen("Dimension"))) {
+          fscanf(inm,"%d",&dim);
+          if(dim!=3) {
+            fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim); 
+            return(1);
+          }
+          continue;
+      } else if(!strncmp(chaine,"SolAtVertices",strlen("SolAtVertices"))) {
+        fscanf(inm,"%d",&pd->np); 
+        fscanf(inm,"%d",&type); 
+        if(type!=1) {
+          fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
+          return(1);
+        }
+        fscanf(inm,"%d",&btyp);
+        posnp = ftell(inm);
+        break;
+      } 
+    }            
+  } else {     
+    fread(&pd->ver,sw,1,inm); 
+    iswp=0;   
+    if(pd->ver==16777216) iswp=1;    
+    else if(pd->ver!=1) {
+      fprintf(stdout,"BAD FILE ENCODING\n");
+    } 
+    fread(&pd->ver,sw,1,inm); 
+    if(iswp) pd->ver = MMG_swapbin(pd->ver); 
+    while(fread(&binch,sw,1,inm)!=EOF && binch!=54 ) {
+      if(iswp) binch=MMG_swapbin(binch);      
+      if(binch==54) break;  
+      if(binch==3) {  //Dimension
+        fread(&bdim,sw,1,inm);  //Pos=>20
+        if(iswp) bdim=MMG_swapbin(bdim);      
+        fread(&bdim,sw,1,inm);
+        if(iswp) bdim=MMG_swapbin(bdim);      
+        if(bdim!=3) {
+          fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim);
+          exit(0);
+          return(1);
+        }
+        continue;
+      } else if(binch==62) {  //SolAtVertices
+        fread(&binch,sw,1,inm); //Pos
+        if(iswp) binch=MMG_swapbin(binch);      
+        fread(&pd->np,sw,1,inm); 
+        if(iswp) pd->np=MMG_swapbin(pd->np);      
+        fread(&binch,sw,1,inm); //nb sol
+        if(iswp) binch=MMG_swapbin(binch);      
+        if(binch!=1) {
+          fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
+          return(1);
+        }
+        fread(&btyp,sw,1,inm); //typsol
+        if(iswp) btyp=MMG_swapbin(btyp);      
+        posnp = ftell(inm);
+        break;
+      } else {
+        fread(&bpos,sw,1,inm); //Pos 
+        if(iswp) bpos=MMG_swapbin(bpos);      
+        rewind(inm);
+        fseek(inm,bpos,SEEK_SET);        
+      } 
+    }            
+    
+  }       
+  if ( !pd->np ) {
+    fprintf(stdout,"  ** MISSING DATA\n");
+    return(0);
+  }
+  else if ( pd->np != mesh->np ) {
+    fprintf(stdout,"  ** WRONG DATA\n");
+    return(0);
+  }
+
+  if ( btyp != 2 ) {
+    fprintf(stdout,"  ** DATA IGNORED\n");
+    return(0);
+  }
+
+  if ( abs(mesh->info.imprim) > 5 )
+    fprintf(stdout,"  -- READING DATA FILE %s\n",data);
+
+  /* read mesh solutions */
+  rewind(inm);
+  fseek(inm,posnp,SEEK_SET);
+  for (k=1; k<=pd->np; k++) {
+    iadr = (k - 1) * 3 + 1;
+    if (pd->ver < 2) { 
+      for (i=0; i<3; i++) {
+        if(!bin){
+          fscanf(inm,"%f",&fsol); 
+          pd->mv[iadr + i] = (double) fsol;
+        } else {
+          fread(&fsol,sw,1,inm);             
+          if(iswp) fsol=MMG_swapf(fsol);      
+          pd->mv[iadr + i] = (double) fsol;
+        }
+      } 
+    } else {
+      for (i=0; i<3; i++) {
+        if(!bin){
+          fscanf(inm,"%lf",&pd->mv[iadr + i]); 
+        } else {
+          fread(&pd->mv[iadr + i],sd,1,inm);
+          if(iswp) pd->mv[iadr + i]=MMG_swapd(pd->mv[iadr + i]);      
+        } 
+      } 
+    }             
+  }
+
+  if ( abs(mesh->info.imprim) > 3 )
+    fprintf(stdout,"     NUMBER OF GIVEN DATA       %8d\n",pd->np);
+
+  fclose(inm); 
+  return(1);
+}
+
+
+/* save mesh to disk */
+int MMG_saveMesh(pMesh mesh,char *filename) {  
+  FILE*        inm; 
+	Hedge				 hed;
+  pPoint       ppt;
+  pTria        pt1;
+  pTetra       pt;
+  int          i,k,np,ne,nc,ned,*cor,*ed,ref,bin,bpos;
+  char        *ptr,data[128],chaine[128]; 
+  int          binch,nu1,nu2;
+  mesh->ver = 2; //double precision
+  bin = 0;
+  strcpy(data,filename);
+  ptr = strstr(data,".mesh");
+  if ( !ptr ) {
+    strcat(data,".meshb");
+    if( !(inm = fopen(data,"wb")) ) {
+      ptr  = strstr(data,".mesh");
+      *ptr = '\0';
+      strcat(data,".mesh");
+      if( !(inm = fopen(data,"w")) ) {
+        fprintf(stderr,"  ** UNABLE TO OPEN %s.\n",data);
+        return(0);
+      }
+    } else {
+      bin = 1;   
+    }
+  }
+  else { 
+    ptr = strstr(data,".meshb");
+    if( ptr ) bin = 1;
+    if( !(inm = fopen(data,"w")) ) {
+      fprintf(stderr,"  ** UNABLE TO OPEN %s.\n",data);
+      return(0);
+    } 
+  }
+  fprintf(stdout,"  %%%% %s OPENED\n",data);
+
+  /*entete fichier*/
+  if(!bin) {
+    strcpy(&chaine[0],"MeshVersionFormatted 2\n"); 
+    fprintf(inm,"%s",chaine);
+    strcpy(&chaine[0],"\n\nDimension 3\n"); 
+    fprintf(inm,"%s ",chaine);
+  } else {
+    binch = 1; //MeshVersionFormatted
+    fwrite(&binch,sw,1,inm);
+    binch = 2; //version
+    fwrite(&binch,sw,1,inm);
+    binch = 3; //Dimension
+    fwrite(&binch,sw,1,inm);
+    bpos = 20; //Pos
+    fwrite(&bpos,sw,1,inm);
+    binch = 3;
+    fwrite(&binch,sw,1,inm);
+    
+  }
+
+  /* compact vertices */
+  if(mesh->ncor) {   
+    cor = (int*) M_calloc(mesh->ncor,sizeof(int),"MMG_savemesh");
+    assert(cor);   
+  }
+  if(mesh->ned) {   
+	  if ( !MMG_zaldy4(&hed,mesh->ned) ) {
+      if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EXPORT EDGES IGNORED\n"); 
+			mesh->ned = 0;
+    }   
+    ed = (int*)M_calloc(2*mesh->ned,sizeof(int),"MMG_savemesh");
+    assert(ed);   
+  }
+  np = 0; 
+  nc = 0;
+  for (k=1; k<=mesh->np; k++) {
+    ppt = &mesh->point[k];
+    if ( ppt->tag & M_UNUSED )  continue;  
+		ppt->tmp = ++np;  
+    if ( ppt->geom & M_CORNER )  cor[nc++] = ppt->tmp;
+  } 
+	assert(mesh->ncor==nc);
+  if(!bin) {
+    strcpy(&chaine[0],"\n\nVertices\n"); 
+    fprintf(inm,"%s",chaine);
+    fprintf(inm,"%d\n",np);
+  } else {
+    binch = 4; //Vertices
+    fwrite(&binch,sw,1,inm);
+    bpos += 12+(1+3*mesh->ver)*4*np; //NullPos
+    fwrite(&bpos,sw,1,inm);
+    fwrite(&np,sw,1,inm);    
+  }
+  for(k=1; k<=mesh->np; k++) {
+    ppt = &mesh->point[k];
+    if ( ppt->tag & M_UNUSED )  continue;  
+		//if(ppt->tmp==52453) printf("point %d --> %d\n",ppt->tmp,k);
+    if(!bin) {
+      fprintf(inm,"%.15lg %.15lg %.15lg %d\n",ppt->c[0],ppt->c[1],ppt->c[2],ppt->ref);
+    } else {
+      fwrite((unsigned char*)&ppt->c[0],sd,1,inm);    
+      fwrite((unsigned char*)&ppt->c[1],sd,1,inm);    
+      fwrite((unsigned char*)&ppt->c[2],sd,1,inm);    
+      fwrite((unsigned char*)&ppt->ref,sw,1,inm);    
+    }
+  }
+
+  /* rebuild triangles tabular and write triangles */ 
+  mesh->nt = 0;
+  if(MMG_markBdry(mesh)) {
+    if(!bin) {
+      strcpy(&chaine[0],"\n\nTriangles\n"); 
+      fprintf(inm,"%s",chaine);
+      fprintf(inm,"%d \n",mesh->nt);
+    } else {
+      binch = 6; //Triangles
+      fwrite(&binch,sw,1,inm);
+      bpos += 12+16*mesh->nt; //Pos
+      fwrite(&bpos,sw,1,inm);
+      fwrite(&mesh->nt,sw,1,inm);    
+    }
+    for (k=1; k<=mesh->nt; k++) {
+      pt1  = &mesh->tria[k];
+  	    ref  = pt1->ref;    
+      if(!bin) {
+        fprintf(inm,"%d %d %d %d\n",mesh->point[pt1->v[0]].tmp,mesh->point[pt1->v[1]].tmp
+    							  ,mesh->point[pt1->v[2]].tmp,ref);
+      } else {
+        fwrite(&mesh->point[pt1->v[0]].tmp,sw,1,inm);    
+        fwrite(&mesh->point[pt1->v[1]].tmp,sw,1,inm);    
+        fwrite(&mesh->point[pt1->v[2]].tmp,sw,1,inm);    
+        fwrite(&ref,sw,1,inm);    
+      }
+    }
+  }   
+ 
+  /* write tetrahedra */
+  ne = 0; 
+	ned = 0;  
+	//printf("avt %d\n",mesh->ned);
+  for (k=1; k<=mesh->ne; k++) {
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+		if(mesh->ned) {
+		  for (i=0 ; i<6 ; i++) {
+		  	if (pt->bdryinfo[i]) {
+		  		nu1 = pt->v[MMG_iare[i][0]];
+		  		nu2 = pt->v[MMG_iare[i][1]];
+		  		if (MMG_edgePut(&hed,nu1,nu2,2)<=1) {
+		  			ed[2*ned] = (mesh->point[nu1]).tmp;
+		  			ed[2*ned + 1] = (mesh->point[nu2]).tmp;
+		  			ned++;
+		  		} 
+		  	}
+		  } 
+		}
+	  ne++;  
+  }
+	//printf("ned %d\n",ned);
+  if(!bin) {
+    strcpy(&chaine[0],"\n\nTetrahedra\n"); 
+    fprintf(inm,"%s",chaine);
+    fprintf(inm,"%d\n",ne);
+  } else {
+    binch = 8; //Tetra
+    fwrite(&binch,sw,1,inm);
+    bpos += 12 + 20*ne;//Pos
+    fwrite(&bpos,sw,1,inm);
+    fwrite((unsigned char*)&ne,sw,1,inm);    
+  } 
+	ne=0;
+  for (k=1; k<=mesh->ne; k++) {
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;  
+		ne++; 
+    ref = pt->ref;    
+    if(!bin) {
+      fprintf(inm,"%d %d %d %d %d\n",mesh->point[pt->v[0]].tmp,mesh->point[pt->v[1]].tmp
+  							   ,mesh->point[pt->v[2]].tmp,mesh->point[pt->v[3]].tmp,ref);
+    } else {
+      fwrite(&mesh->point[pt->v[0]].tmp,sw,1,inm);    
+      fwrite(&mesh->point[pt->v[1]].tmp,sw,1,inm);    
+      fwrite(&mesh->point[pt->v[2]].tmp,sw,1,inm);    
+      fwrite(&mesh->point[pt->v[3]].tmp,sw,1,inm);    
+      fwrite(&ref,sw,1,inm);    
+    }
+  }  
+     
+  if(mesh->ned) {
+    if(!bin) {
+      strcpy(&chaine[0],"\n\nEdges\n"); 
+      fprintf(inm,"%s",chaine);
+      fprintf(inm,"%d\n",ned);
+    } else {
+      binch = 5; //Edges
+      fwrite(&binch,sw,1,inm);
+      bpos += 12 + 3*4*ned;//Pos
+      fwrite(&bpos,sw,1,inm);
+      fwrite((unsigned char*)&ned,sw,1,inm);    
+    } 
+  	  for (k=0; k<ned; k++) {
+   	    ref = 0;    
+  	    if(!bin) {
+  	      fprintf(inm,"%d %d %d \n",ed[2*k],ed[2*k+1],ref);
+  	    } else {
+  	      fwrite(&ed[2*k],sw,1,inm);    
+  	      fwrite(&ed[2*k+1],sw,1,inm);    
+  	      fwrite(&ref,sw,1,inm);    
+  	    }
+  	  }
+  	  M_free(hed.item);
+  }
+  
+  /* write corners */
+  if(!bin) {
+    strcpy(&chaine[0],"\n\nCorners\n"); 
+    fprintf(inm,"%s",chaine);
+    fprintf(inm,"%d\n",mesh->ncor);
+  } else {
+    binch = 13; //Corners
+    fwrite(&binch,sw,1,inm);
+    bpos += 12 + 4*mesh->ncor;//Pos  
+    fwrite(&bpos,sw,1,inm);
+    fwrite((unsigned char*)&mesh->ncor,sw,1,inm);    
+  }
+  for (k=0; k<mesh->ncor; k++) {
+    if(!bin) {
+      fprintf(inm,"%d \n",cor[k]);
+    } else {
+      fwrite(&cor[k],sw,1,inm);    
+    }
+  }  
+  /*fin fichier*/
+  if(!bin) {
+    strcpy(&chaine[0],"\n\nEnd\n"); 
+    fprintf(inm,"%s",chaine);
+  } else {
+    binch = 54; //End
+    fwrite(&binch,sw,1,inm);
+  }
+  fclose(inm); 
+  if(mesh->ncor) M_free(cor);
+  if ( mesh->info.imprim ) {
+    fprintf(stdout,"     NUMBER OF GIVEN VERTICES   %8d\n",mesh->npfixe);
+    if ( mesh->ntfixe )
+      fprintf(stdout,"     NUMBER OF GIVEN TRIANGLES  %8d\n",mesh->ntfixe);
+    fprintf(stdout,"     NUMBER OF GIVEN ELEMENTS   %8d\n",mesh->nefixe);
+    fprintf(stdout,"     TOTAL NUMBER OF VERTICES   %8d\n",np);
+    fprintf(stdout,"     TOTAL NUMBER OF TRIANGLES  %8d\n",mesh->nt);
+    fprintf(stdout,"     TOTAL NUMBER OF ELEMENTS   %8d\n",ne);
+    if ( mesh->ncor )
+      fprintf(stdout,"     TOTAL NUMBER OF CORNERS    %8d\n",mesh->ncor);
+    if ( mesh->ned )
+      fprintf(stdout,"     TOTAL NUMBER OF EDGES      %8d\n",ned);
+  }
+	//if(ned!=mesh->ned) exit(0);
+  return(1);
+
+}
+
+
+int MMG_saveSol(pMesh mesh,pSol sol,char *filename) {
+  FILE*        inm;
+  pPoint       ppt;
+  float        fsol;
+  double       tmp;
+  int          i,k,nbl,isol,bin,bpos,typ;
+  char        *ptr,data[128],chaine[128]; 
+  int          binch;
+
+  if ( !sol->np )  return(1);
+  bin = 1;
+  strcpy(data,filename);
+  ptr = strstr(data,".meshb");
+  if ( ptr )  *ptr = '\0';
+  else {
+    ptr = strstr(data,".mesh");
+    if ( ptr ) {
+      *ptr = '\0';
+      bin  = 0;
+    } else {
+	    ptr = strstr(data,".solb");
+	    if ( ptr ) {
+	      *ptr = '\0';
+	      bin  = 1;	
+      } else {
+			  ptr = strstr(data,".sol");
+			  if ( ptr ) {
+			    *ptr = '\0';
+			    bin  = 0;	
+			  }
+			}
+    } 
+  }
+  if ( bin ) 
+    strcat(data,".solb");
+  else
+    strcat(data,".sol");
+  
+  sol->ver = 2;
+  if( bin && !(inm = fopen(data,"wb")) ) {
+    fprintf(stderr,"  ** UNABLE TO OPEN %s.\n",data);
+    return(0);
+  } else {
+    if( !(inm = fopen(data,"w")) ) {
+      fprintf(stderr,"  ** UNABLE TO OPEN %s.\n",data);
+      return(0);
+    }
+  }
+  fprintf(stdout,"  %%%% %s OPENED\n",data);
+
+  /*entete fichier*/
+  if(!bin) {
+    strcpy(&chaine[0],"MeshVersionFormatted 2\n"); 
+    fprintf(inm,"%s",chaine);
+    strcpy(&chaine[0],"\n\nDimension 3\n"); 
+    fprintf(inm,"%s ",chaine);
+  } else {
+    binch = 1; //MeshVersionFormatted
+    fwrite(&binch,sw,1,inm);
+    binch = 2; //version
+    fwrite(&binch,sw,1,inm);
+    binch = 3; //Dimension
+    fwrite(&binch,sw,1,inm);
+    bpos = 20; //Pos
+    fwrite(&bpos,sw,1,inm);
+    binch = 3;
+    fwrite(&binch,sw,1,inm);
+    
+  }
+
+
+  switch(sol->offset) {
+  case 1:
+	 typ = 1;
+   break;
+  case 6:
+	  typ = 3;
+    break;
+  default:
+    fprintf(stdout,"  ** DATA IGNORED\n");
+    return(0);
+  }
+
+  /* write data */
+  nbl = 0;
+  for (k=1; k<=mesh->np; k++) {
+    ppt = &mesh->point[k];
+    if ( ppt->tag & M_UNUSED )  continue;
+	nbl++;
+  }
+  
+  if(!bin) {
+    strcpy(&chaine[0],"\n\nSolAtVertices\n"); 
+    fprintf(inm,"%s",chaine);
+    fprintf(inm,"%d\n",nbl);
+    fprintf(inm,"%d %d\n",1,typ);
+  } else {
+    binch = 62; //Vertices
+    fwrite(&binch,sw,1,inm);
+    bpos += 20+(sol->offset*sol->ver)*4*nbl; //Pos
+    fwrite(&bpos,sw,1,inm);
+    fwrite(&nbl,sw,1,inm);    
+    binch = 1; //nb sol
+    fwrite(&binch,sw,1,inm);
+    binch = typ; //typ sol
+    fwrite(&binch,sw,1,inm);
+  }
+  for (k=1; k<=mesh->np; k++) {
+    ppt = &mesh->point[k];
+    if ( ppt->tag & M_UNUSED )  continue;
+    isol = (k-1) * sol->offset + 1;
+    /* swap data */
+    if ( sol->offset == 6 ) {
+      tmp                = sol->met[isol + 2];
+      sol->met[isol + 2] = sol->met[isol + 3];
+      sol->met[isol + 3] = tmp;
+    }
+    if (sol->ver < 2) {
+      if(!bin) { 
+        for (i=0; i<sol->offset; i++) {
+          fsol = (float) sol->met[isol + i];
+          fprintf(inm,"%f ",fsol);
+        } 
+        fprintf(inm,"\n");  
+      } else {
+        for (i=0; i<sol->offset; i++) { 
+          fsol = (float) sol->met[isol + i];
+          fwrite(&fsol,sw,1,inm);
+        }    
+      }
+    } else {
+      if(!bin) { 
+        for (i=0; i<sol->offset; i++)
+          fprintf(inm,"%.15lg ",sol->met[isol + i]); 
+        fprintf(inm,"\n");  
+      } else {
+        for (i=0; i<sol->offset; i++)
+          fwrite(&sol->met[isol + i],sd,1,inm);    
+      }
+      
+    }
+  }
+  
+  /*fin fichier*/
+  if(!bin) {
+    strcpy(&chaine[0],"\n\nEnd\n"); 
+    fprintf(inm,"%s",chaine);
+  } else {
+    binch = 54; //End
+    fwrite(&binch,sw,1,inm);
+  }
+  fclose(inm);
+  return(1);
+}
+
+/*save the node speed : coornew-coorold/dt*/
+int MMG_saveVect(pMesh mesh,char *filename) {
+  FILE*        inm;  
+  pDispl        pd;
+  pPoint       ppt;
+  double       dsol,dd;
+  int          i,k,nbl,bin,bpos,typ;
+  char        *ptr,data[128],chaine[128]; 
+  unsigned char binch;
+
+  pd      = mesh->disp;
+  pd->ver = 2;
+
+  bin = 0;
+  strcpy(data,filename);
+  ptr = strstr(data,".meshb");
+  if ( ptr )  *ptr = '\0';
+  else {
+    ptr = strstr(data,".mesh");
+    if ( ptr ) {
+      *ptr = '\0';
+      bin  = 0;
+    }
+  }
+  if ( bin ) 
+    strcat(data,".o.solb");
+  else
+    strcat(data,".o.sol");
+  if( bin && !(inm = fopen(data,"wb")) ) {
+    fprintf(stderr,"  ** UNABLE TO OPEN %s.\n",data);
+    return(0);
+  } else {
+    if( !(inm = fopen(data,"w")) ) {
+      fprintf(stderr,"  ** UNABLE TO OPEN %s.\n",data);
+      return(0);
+    }
+  }
+  fprintf(stdout,"  %%%% %s OPENED\n",data);
+
+  /*entete fichier*/
+  if(!bin) {
+    strcpy(&chaine[0],"MeshVersionFormatted 2\n"); 
+    fprintf(inm,"%s",chaine);
+    strcpy(&chaine[0],"\n\nDimension 3\n"); 
+    fprintf(inm,"%s ",chaine);
+  } else {
+    binch = 1; //MeshVersionFormatted
+    fwrite(&binch,sw,1,inm);
+    binch = pd->ver; //version
+    fwrite(&binch,sw,1,inm);
+    binch = 3; //Dimension
+    fwrite(&binch,sw,1,inm);
+    bpos = 20; //Pos
+    fwrite(&bpos,sw,1,inm);
+    binch = 3;
+    fwrite(&binch,sw,1,inm);
+    
+  }
+	typ = 2;
+
+  /* write data */
+  nbl = 0;
+  for (k=1; k<=mesh->np; k++) {
+    ppt = &mesh->point[k];
+    if ( ppt->tag & M_UNUSED )  continue;
+	nbl++;
+  }
+  
+  if(!bin) {
+    strcpy(&chaine[0],"\n\nSolAtVertices\n"); 
+    fprintf(inm,"%s",chaine);
+    fprintf(inm,"%d\n",nbl);
+    fprintf(inm,"%d %d\n",1,typ);
+  } else {
+    binch = 62; //SolAtVertices
+    fwrite(&binch,sw,1,inm);
+    bpos += 20+(3*pd->ver)*4*nbl; //Pos
+    fwrite(&bpos,sw,1,inm);
+    fwrite(&nbl,sw,1,inm);    
+    binch = 1; //nb sol
+    fwrite(&binch,sw,1,inm);
+    binch = typ; //typ sol
+    fwrite(&binch,sw,1,inm);
+  } 
+  
+  
+  dd = mesh->info.delta / (double)PRECI;  
+  fprintf(stdout,"        DT %e\n",mesh->info.dt);
+  for (k=1; k<=mesh->np; k++) {
+    ppt = &mesh->point[k];
+    if ( ppt->tag & M_UNUSED )  continue; 
+    for (i=0 ; i<3 ; i++) {
+      dsol = (ppt->c[i] - mesh->disp->cold[3*(k-1) + 1 + i]* dd - mesh->info.min[i])/mesh->info.dt; 
+      if(!bin) { 
+        fprintf(inm,"%.15lg ",dsol); 
+      } else {
+        fwrite(&dsol,sd,1,inm);    
+      }
+    }
+    if (!bin) fprintf(inm,"\n");  
+  }
+  
+  
+  /*fin fichier*/
+  if(!bin) {
+    strcpy(&chaine[0],"\n\nEnd\n"); 
+    fprintf(inm,"%s",chaine);
+  } else {
+    binch = 54; //End
+    fwrite(&binch,sw,1,inm);
+  }
+  fclose(inm);
+
+  return(1);
+}
diff --git a/contrib/mmg3d/build/sources/length.c b/contrib/mmg3d/build/sources/length.c
new file mode 100644
index 0000000000000000000000000000000000000000..89304ea9aed12a0e59dc02e9c6af0b2c9cf34396
--- /dev/null
+++ b/contrib/mmg3d/build/sources/length.c
@@ -0,0 +1,235 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+/* compute aniso edge MMG_length */
+double MMG_long_ani(double *ca,double *cb,double *sa,double *sb) {
+  double   ux,uy,uz,dd1,dd2,len;
+
+  ux = cb[0] - ca[0];
+  uy = cb[1] - ca[1];
+  uz = cb[2] - ca[2];
+
+  dd1 =      sa[0]*ux*ux + sa[3]*uy*uy + sa[5]*uz*uz \
+      + 2.0*(sa[1]*ux*uy + sa[2]*ux*uz + sa[4]*uy*uz);
+  if ( dd1 <= 0.0 )  dd1 = 0.0;
+
+  dd2 =      sb[0]*ux*ux + sb[3]*uy*uy + sb[5]*uz*uz \
+      + 2.0*(sb[1]*ux*uy + sb[2]*ux*uz + sb[4]*uy*uz);
+  if ( dd2 <= 0.0 )  dd2 = 0.0;
+  
+  /*longueur approchee*/   
+  /*precision a 3.5 10e-3 pres*/
+  if(fabs(dd1-dd2) < 0.05 ) {
+    //printf("bonne precision %e \n",sqrt(0.5*(dd1+dd2)) - (sqrt(dd1)+sqrt(dd2)+4.0*sqrt(0.5*(dd1+dd2))) / 6.0 );
+    len = sqrt(0.5*(dd1+dd2));
+    return(len);
+  }
+  len = (sqrt(dd1)+sqrt(dd2)+4.0*sqrt(0.5*(dd1+dd2))) / 6.0;
+
+  return(len);
+}
+
+double MMG_long_ani_init(double *ca,double *cb,double *sa,double *sb) {
+  double   ux,uy,uz,dd1,dd2,len;
+
+  ux = cb[0] - ca[0];
+  uy = cb[1] - ca[1];
+  uz = cb[2] - ca[2];
+
+  dd1 =      sa[0]*ux*ux + sa[3]*uy*uy + sa[5]*uz*uz \
+      + 2.0*(sa[1]*ux*uy + sa[2]*ux*uz + sa[4]*uy*uz);
+  if ( dd1 <= 0.0 )  dd1 = 0.0;
+
+  dd2 =      sb[0]*ux*ux + sb[3]*uy*uy + sb[5]*uz*uz \
+      + 2.0*(sb[1]*ux*uy + sb[2]*ux*uz + sb[4]*uy*uz);
+  if ( dd2 <= 0.0 )  dd2 = 0.0;
+  
+  len = (sqrt(dd1)+sqrt(dd2)+4.0*sqrt(0.5*(dd1+dd2))) / 6.0;
+
+  return(len);
+}
+
+/* compute iso edge MMG_length */
+double MMG_long_iso(double *ca,double *cb,double *ma,double *mb) {
+  double   ux,uy,uz,dd,rap,len;
+  double   sa,sb;
+
+  sa   = *ma;
+  sb   = *mb;
+  
+  ux = cb[0] - ca[0];
+  uy = cb[1] - ca[1];
+  uz = cb[2] - ca[2];
+  dd = sqrt(ux*ux + uy*uy + uz*uz);
+
+  rap = (sb - sa) / sa;
+  if ( fabs(rap) < EPS1 )
+    /*len = dd * (2.0-EPS1) / (2.0*sa);*/
+    len = dd / sa;
+  else
+    /*len = max(dd/sa,dd/sb);*/
+    len = dd * (1.0/sa + 1.0/sb + 8.0 / (sa+sb)) / 6.0;
+
+
+  return(len);
+}
+
+
+/* print histo of edge lengths */
+int MMG_prilen(pMesh mesh,pSol sol) {
+  pTetra      pt;
+  double      lavg,len,ecart,som,lmin,lmax,*ca,*cb,*ma,*mb;
+  int         k,l,lon,navg,ia,ipa,ipb,iamin,ibmin,iamax,ibmax,dep,hl[10];
+  int	      iadr;
+  List        list;
+  static double bd[9] = {0.0, 0.2, 0.5, 0.7071, 0.9, 1.111, 1.4142, 2.0, 5.0 };
+  navg  = 0;
+  lavg  = 0.0;
+  lmin  = 1.e20;
+  lmax  = 0.0;
+  som   = 0.0;
+  dep   = 1;
+  iamin = 0;
+  ibmin = 0;
+  iamax = 0;
+  ibmax = 0;
+
+  for (k=1; k<10; k++)  hl[k] = 0;
+
+  for (k=1; k<=mesh->ne; k++) {
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+
+    for (ia=0; ia<6; ia++) {
+      lon = MMG_coquil(mesh,k,ia,&list);
+      if ( lon < 2 )  continue;
+      for (l=2; l<=lon; l++)
+        if ( list.tetra[l] < 6*k )  break;
+
+ 	      if ( l <= lon )  continue;
+        
+        ipa = MMG_iare[ia][0];
+        ipb = MMG_iare[ia][1];
+        ca  = &mesh->point[pt->v[ipa]].c[0];
+        cb  = &mesh->point[pt->v[ipb]].c[0];
+
+        iadr = (pt->v[ipa]-1)*sol->offset + 1;
+        ma   = &sol->met[iadr];
+        iadr = (pt->v[ipb]-1)*sol->offset + 1;
+        mb   = &sol->met[iadr];  
+        if(sol->offset==6)
+          len = MMG_long_ani_init(ca,cb,ma,mb);  
+        else
+          len = MMG_length(ca,cb,ma,mb);  
+        navg++;
+        ecart = len; 
+        lavg += len;
+        /* update efficiency index */
+	      if ( ecart > 1.0 )  ecart = 1.0 / ecart; 
+
+        som  += (ecart - 1.0); 
+      
+        /* find largest, smallest edge */
+        if (len < lmin) {
+	        lmin  = len;
+		      iamin = pt->v[ipa];
+		      ibmin = pt->v[ipb];
+        }
+        else if (len > lmax) {
+		      lmax  = len;
+          iamax = pt->v[ipa];
+          ibmax = pt->v[ipb];
+        }
+
+        /* update histogram */
+        if (len < bd[3]) {
+		      if (len > bd[2])       hl[3]++;
+		      else if (len > bd[1])  hl[2]++;
+		      else                   hl[1]++;
+        }
+        else if (len < bd[5]) {
+		      if (len > bd[4])       hl[5]++;
+		      else if (len > bd[3])  hl[4]++;
+        }
+        else if (len < bd[6])    hl[6]++;
+        else if (len < bd[7])    hl[7]++;
+        else if (len < bd[8])    hl[8]++;
+        else                     hl[9]++;
+      }
+      /*    /if ( dep < 0 )  break;*/
+  }
+
+  fprintf(stdout,"\n  -- RESULTING EDGE LENGTHS  %d\n",navg);
+  fprintf(stdout,"     AVERAGE LENGTH         %12.4f\n",lavg / (double)navg);
+  fprintf(stdout,"     SMALLEST EDGE LENGTH   %12.4f   %6d %6d\n",
+  	  lmin,iamin,ibmin);
+  fprintf(stdout,"     LARGEST  EDGE LENGTH   %12.4f   %6d %6d \n",
+  	  lmax,iamax,ibmax);
+  fprintf(stdout,"     EFFICIENCY INDEX       %12.4f\n",exp(som/(double)navg));
+  if ( hl[4]+hl[5]+hl[6] )
+    fprintf(stdout,"   %6.2f < L <%5.2f  %8d   %5.2f %%  \n",
+      bd[3],bd[6],hl[4]+hl[5]+hl[6],100.*(hl[4]+hl[5]+hl[6])/(double)navg);
+
+  if ( abs(mesh->info.imprim) > 4 ) {
+    fprintf(stdout,"\n     HISTOGRAMM\n");
+    if ( hl[1] )
+      fprintf(stdout,"     0.00 < L < 0.20  %8d   %5.2f %%  \n",
+	      hl[1],100.*(hl[1]/(float)navg));
+    if ( lmax > 0.2 ) {
+      for (k=2; k<9; k++) {
+        if ( hl[k] > 0 )
+  	  fprintf(stdout,"   %6.2f < L <%5.2f  %8d   %5.2f %%  \n",
+		  bd[k-1],bd[k],hl[k],100.*(hl[k]/(float)navg));
+      }
+      if ( hl[9] )
+        fprintf(stdout,"     5.   < L         %8d   %5.2f %%  \n",
+	        hl[9],100.*(hl[9]/(float)navg));
+    }
+  }
+
+  return(1);
+}
diff --git a/contrib/mmg3d/build/sources/libmmg3d.h b/contrib/mmg3d/build/sources/libmmg3d.h
new file mode 100644
index 0000000000000000000000000000000000000000..22c002499ccaac300baea921c11557f883ce538e
--- /dev/null
+++ b/contrib/mmg3d/build/sources/libmmg3d.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+typedef struct {
+  double        c[3];
+  int           mark,tmp;
+  int           ref;
+  unsigned char flag,tag,tmp2;
+	unsigned char geom;
+} MMG_Point;
+typedef MMG_Point * MMG_pPoint;
+
+typedef struct {
+  int           v[4];
+  int           mark;
+  double        qual;
+  int           ref,bdryref[4];
+  unsigned char flag,edge,tabedg;  
+	unsigned char bdryinfo[6];
+} MMG_Tetra;
+typedef MMG_Tetra * MMG_pTetra;
+
+typedef struct {
+  int           v[3],splx;
+  int           ref;
+} MMG_Tria;
+typedef MMG_Tria * MMG_pTria;
+
+typedef struct {
+  int      np,ver;
+  double   *mv,*cold;
+  short    *alpha;  
+} MMG_Displ;
+typedef MMG_Displ * MMG_pDispl;
+
+typedef struct {
+  unsigned char  ddebug;
+  unsigned char  noswap,noinsert,nomove,bdry;
+  short          imprim,option,memory,rn,rn2;
+  int            bucksiz;
+  double   	     delta,dt;
+  double   	     min[3],max[3];  
+
+} MMG_Info;
+
+typedef struct {
+  int      np,ne,nt,ncor,ned,npmax,nemax,ntmax;
+  int      npfixe,nefixe,ntfixe,mark;
+  int      npnil,nenil,ntnil;
+  int     *adja,ver;
+  char    *name,*outf,*move;
+  unsigned char flag,booleen;
+
+  MMG_pPoint   point;
+  MMG_pTetra   tetra;
+  MMG_pTria    tria;
+  MMG_pDispl   disp;
+  MMG_Info     info;
+} MMG_Mesh;
+typedef MMG_Mesh * MMG_pMesh;
+
+typedef struct {
+  int      np,npfixe,npmax,ver;
+  double   *met,hmin,hmax;
+  char     *name;  
+  double   *metold;
+  unsigned char offset;
+} MMG_Sol;
+typedef MMG_Sol * MMG_pSol;
+
+/* inout */
+int  MMG_loadMesh(MMG_pMesh ,char *);
+int  MMG_loadSol(MMG_pSol ,char *,int );
+int  MMG_loadVect(MMG_pMesh ,char *,int );
+int  MMG_saveMesh(MMG_pMesh ,char *);
+int  MMG_saveSol(MMG_pMesh ,MMG_pSol ,char *);
+int  MMG_saveVect(MMG_pMesh ,char *);
+
+#ifdef  __cplusplus
+namespace mmg3d{
+extern "C" {
+#endif
+int MMG_mmg3dlib(int opt[9],MMG_pMesh mesh,MMG_pSol sol);
+#ifdef  __cplusplus
+}}
+#endif
diff --git a/contrib/mmg3d/build/sources/libmmg3d_internal.h b/contrib/mmg3d/build/sources/libmmg3d_internal.h
new file mode 100644
index 0000000000000000000000000000000000000000..67be6768cb1065d4847a69ec4ec1faa162329bbc
--- /dev/null
+++ b/contrib/mmg3d/build/sources/libmmg3d_internal.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+typedef MMG_Point Point;
+typedef MMG_Tetra Tetra;
+typedef MMG_Tria  Tria;
+typedef MMG_Displ Displ;
+typedef MMG_Mesh Mesh;
+typedef MMG_Sol Sol;
+
+typedef MMG_pPoint pPoint;
+typedef MMG_pTetra pTetra;
+typedef MMG_pDispl pDispl;
+typedef MMG_pTria pTria;
+typedef MMG_Info Info;
+typedef MMG_pMesh pMesh;
+typedef MMG_pSol pSol;
diff --git a/contrib/mmg3d/build/sources/librnbg.c b/contrib/mmg3d/build/sources/librnbg.c
new file mode 100644
index 0000000000000000000000000000000000000000..bacfb4940bbeeb918b344a2198be690a8fd1bf4a
--- /dev/null
+++ b/contrib/mmg3d/build/sources/librnbg.c
@@ -0,0 +1,461 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+/* librnbg
+ *
+ * Written by Cedric Lachat
+ */  
+#include "mesh.h"
+
+#ifdef USE_SCOTCH
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include "librnbg.h"
+
+#define CHECK_SCOTCH(t,m,e) if(0!=t){perror(m);exit(e);}
+
+
+
+
+/* Internal function : biPartBoxCompute
+ * it computes a new numbering of graph vertices, using a bipartitioning.
+ *
+ *  - graf : the input graph
+ *  - vertNbr : the number of vertices
+ *  - boxVertNbr : the number of vertices of each box
+ *  - permVrtTab : the new numbering
+ *  
+ *  returning 0 if OK, 1 else
+ */
+int biPartBoxCompute(SCOTCH_Graph graf, int vertNbr, int boxVertNbr, SCOTCH_Num *permVrtTab) {
+  int boxNbr, vertIdx, boxIdx;
+  SCOTCH_Num tmp, tmp2, *partTab, *partNumTab, *partPrmTab;
+  SCOTCH_Strat strat ;
+
+  /* Computing the number of boxes */
+  boxNbr = vertNbr / boxVertNbr;
+  if (boxNbr * boxVertNbr != vertNbr) {
+    boxNbr = boxNbr + 1;
+  }
+
+
+  /* Initializing SCOTCH functions */
+  CHECK_SCOTCH(SCOTCH_stratInit(&strat), "scotch_stratInit", 0) ; 
+  CHECK_SCOTCH(SCOTCH_stratGraphMap(&strat, "r{job=t,map=t,poli=S,sep=m{type=h,vert=80,low=h{pass=10}f{bal=0.005,move=0},asc=b{bnd=f{bal=0.05,move=0},org=f{bal=0.05,move=0}}}|m{type=h,vert=80,low=h{pass=10}f{bal=0.005,move=0},asc=b{bnd=f{bal=0.05,move=0},org=f{bal=0.05,move=0}}}}"), "scotch_stratGraphMap", 0) ; 
+
+  partTab = (SCOTCH_Num *)M_calloc(vertNbr, sizeof(SCOTCH_Num), "boxCompute");
+
+
+  /* Partionning the graph */
+  CHECK_SCOTCH(SCOTCH_graphPart(&graf, boxNbr, &strat, partTab), "scotch_graphPart", 0);
+
+  partNumTab = (SCOTCH_Num *)M_calloc(boxNbr, sizeof(SCOTCH_Num), "boxCompute");
+
+  if (!memset(partNumTab, 0, boxNbr*sizeof(SCOTCH_Num))) {
+    perror("memset");
+    return 0;
+  }
+
+  /* Computing the number of elements of each box */
+  for( vertIdx = 0 ; vertIdx< vertNbr ;vertIdx++)
+    partNumTab[partTab[vertIdx]] += 1;
+
+
+  /* partition permutation tabular */
+  partPrmTab = (SCOTCH_Num *)M_calloc(vertNbr + 1, sizeof(SCOTCH_Num), "boxCompute");
+
+
+  /* Copying the previous tabular in order to have the index of the first
+   * element of each box
+   * */
+  tmp = partNumTab[0];
+  partNumTab[0] = 0;
+  for(boxIdx = 1; boxIdx < boxNbr ; boxIdx++) {
+    tmp2 = partNumTab[boxIdx];
+    partNumTab[boxIdx] = partNumTab[boxIdx-1] + tmp;
+    tmp = tmp2;
+  }
+
+  /* partPrmTab is built such as each vertex belongs to his box */
+  for( vertIdx = 0;vertIdx< vertNbr;vertIdx++)
+    partPrmTab[partNumTab[partTab[vertIdx]]++] = vertIdx;
+
+
+  /* Infering the new numbering */
+  for (vertIdx = 0; vertIdx < vertNbr ; vertIdx++)
+    permVrtTab[partPrmTab[vertIdx] + 1] = vertIdx + 1;
+
+  M_free(partTab);
+  M_free(partNumTab);
+  M_free(partPrmTab);
+
+  SCOTCH_stratExit(&strat) ;
+  return 0;
+}
+
+
+
+
+/* Internal function : kPartBoxCompute
+ * it computes a new numbering of graph vertices, using a k-partitioning.
+ * Assuming that baseval of the graph is 1
+ *
+ *  - graf : the input graph
+ *  - vertNbr : the number of vertices
+ *  - boxVertNbr : the number of vertices of each box
+ *  - permVrtTab : the new numbering
+ *  
+ *  returning 0 if OK, 1 else
+ */
+int kPartBoxCompute(SCOTCH_Graph graf, int vertNbr, int boxVertNbr, SCOTCH_Num *permVrtTab) {
+  int boxNbr, vertIdx;
+  SCOTCH_Num logMaxVal, SupMaxVal, InfMaxVal, maxVal;
+  char s[200];
+  SCOTCH_Num *sortPartTb;
+  SCOTCH_Strat strat ;
+  SCOTCH_Arch arch;
+
+  /* Computing the number of boxes */
+  boxNbr = vertNbr / boxVertNbr;
+  if (boxNbr * boxVertNbr != vertNbr) {
+    boxNbr = boxNbr + 1;
+  }
+
+
+  /* Initializing SCOTCH functions */
+  CHECK_SCOTCH(SCOTCH_stratInit(&strat), "scotch_stratInit", 0) ; 
+  CHECK_SCOTCH(SCOTCH_archVcmplt(&arch), "scotch_archVcmplt", 0) ; 
+
+  sprintf(s, "m{vert=%d,low=r{job=t,map=t,poli=S,sep=m{type=h,vert=80,low=h{pass=10}f{bal=0.0005,move=80},asc=f{bal=0.005,move=80}}}}", vertNbr / boxVertNbr);
+  CHECK_SCOTCH(SCOTCH_stratGraphMap(&strat, s), "scotch_stratGraphMap", 0) ; 
+
+
+  sortPartTb= (SCOTCH_Num *)M_calloc(2*vertNbr, sizeof(SCOTCH_Num), "boxCompute");
+
+
+  /* Partionning the graph */
+  CHECK_SCOTCH(SCOTCH_graphMap(&graf, &arch, &strat, sortPartTb), "scotch_graphMap", 0);
+
+
+  // Looking for the max value in sortPartTb and computing sortPartTb as
+  // followed : 
+  //  - sortPartTb[2i] is the box value
+  //  - sortPartTb[2i+1] is the vertex number
+  maxVal = sortPartTb[0];
+  for (vertIdx = vertNbr - 1 ; vertIdx >= 0 ; vertIdx--) {
+    sortPartTb[2*vertIdx] = sortPartTb[vertIdx];
+    sortPartTb[2*vertIdx+1] = vertIdx + 1;
+    if (sortPartTb[vertIdx] > maxVal)
+      maxVal = sortPartTb[vertIdx];
+  }
+
+  // Determining the log of MaxVal
+  logMaxVal = 0;
+  while ( maxVal > 0) {
+    logMaxVal++;
+    maxVal >>= 1;
+  }
+
+  // Infering the interval in which box values will be
+  InfMaxVal = logMaxVal << logMaxVal;
+  SupMaxVal = (logMaxVal << (logMaxVal + 1)) - 1;
+
+  // Increasing box values until they are in the previous interval
+  for (vertIdx = 0 ; vertIdx < vertNbr ; vertIdx++) {
+    while (!(sortPartTb[2*vertIdx] >= InfMaxVal && sortPartTb[2*vertIdx] <= SupMaxVal)) {
+      sortPartTb[2*vertIdx] <<= 1;
+    }
+  }
+
+
+
+  // Sorting the tabular, which contains box values and vertex numbers
+  _SCOTCHintSort2asc1(sortPartTb, vertNbr);
+
+
+  /* Infering the new numbering */
+  for (vertIdx = 0; vertIdx < vertNbr ; vertIdx++) {
+    permVrtTab[sortPartTb[2*vertIdx + 1]] = vertIdx + 1;
+  }
+
+  SCOTCH_stratExit(&strat) ;
+  SCOTCH_archExit(&arch) ;
+
+  M_free(sortPartTb);
+
+  return 0;
+}
+
+
+
+/* Function : renumbering
+ *  it modifies the numbering of each node to prevent from cache missing.
+ *
+ *  - boxVertNbr : number of vertices by box
+ *  - mesh : the input mesh which is modified
+ *  
+ *  returning 0 if OK, 1 else
+ */
+int renumbering(int boxVertNbr, MMG_pMesh mesh, MMG_pSol sol) {
+  MMG_pPoint ppt;
+  MMG_pPoint points;
+  MMG_pTria ptri, trias;
+  MMG_pTetra ptet, tetras;
+  SCOTCH_Num edgeNbr;
+  SCOTCH_Num *vertTab, *vendTab, *edgeTab, *permVrtTab;
+  SCOTCH_Graph graf ;
+  int vertNbr, nodeGlbIdx, triaIdx, tetraIdx, ballTetIdx;
+  int i, j, k, addrNew, addrOld;
+  int edgeSiz;
+  int *vertOldTab, *permNodTab, ntreal, nereal, npreal;
+  int      *adja,iadr;
+  double *metNew;
+
+
+  /* Computing the number of vertices and a contiguous tabular of vertices */
+  vertNbr = 0;
+  vertOldTab = (int *)M_calloc(mesh->ne + 1, sizeof(int), "renumbering");
+
+  if (!memset(vertOldTab, 0, sizeof(int)*(mesh->ne+1))) {
+    perror("memset");
+    return 1;
+  }
+
+  for(tetraIdx = 1 ; tetraIdx < mesh->ne + 1 ; tetraIdx++) {
+
+    /* Testing if the tetra exists */
+    if (!mesh->tetra[tetraIdx].v[0]) continue;
+    vertOldTab[tetraIdx] = vertNbr+1;
+    vertNbr++;
+  }
+
+
+  /* Allocating memory to compute adjacency lists */
+  vertTab = (SCOTCH_Num *)M_calloc(vertNbr + 1, sizeof(SCOTCH_Num), "renumbering");
+
+  if (!memset(vertTab, ~0, sizeof(SCOTCH_Num)*(vertNbr + 1))) {
+    perror("memset");
+    return 1;
+  }
+
+  vendTab = (SCOTCH_Num *)M_calloc(vertNbr + 1, sizeof(SCOTCH_Num), "renumbering");
+
+  edgeNbr = 1;
+  edgeSiz = vertNbr*2;
+  edgeTab = (SCOTCH_Num *)M_calloc(edgeSiz, sizeof(SCOTCH_Num), "renumbering");
+
+
+
+  /* Computing the adjacency list for each vertex */
+  for(tetraIdx = 1 ; tetraIdx < mesh->ne + 1 ; tetraIdx++) {
+
+    /* Testing if the tetra exists */
+    if (!mesh->tetra[tetraIdx].v[0]) continue;
+
+
+
+
+
+    iadr = 4*(tetraIdx-1) + 1;
+    adja = &mesh->adja[iadr];
+    for (i=0; i<4; i++) {
+      ballTetIdx = adja[i] >> 2;
+
+      if (!ballTetIdx) continue;
+
+
+
+
+
+
+      /* Testing if one neighbour of tetraIdx has already been added */
+      if (vertTab[vertOldTab[tetraIdx]] < 0)
+        vertTab[vertOldTab[tetraIdx]] = edgeNbr;
+      vendTab[vertOldTab[tetraIdx]] = edgeNbr+1;
+
+      /* Testing if edgeTab memory is enough */
+      if (edgeNbr >= edgeSiz) {
+        edgeSiz += EDGEGAP;
+        edgeTab = (SCOTCH_Num *)M_realloc(edgeTab, edgeSiz * sizeof(SCOTCH_Num), "renumbering");
+      }
+
+      edgeTab[edgeNbr++] = vertOldTab[ballTetIdx];
+    }
+  }
+
+  edgeNbr--;
+
+
+  /* Building the graph by calling Scotch functions */
+
+  SCOTCH_graphInit(&graf) ;
+  CHECK_SCOTCH(SCOTCH_graphBuild(&graf, (SCOTCH_Num) 1, vertNbr, vertTab+1, vendTab+1, NULL, NULL, edgeNbr, edgeTab+1, NULL), "scotch_graphbuild", 0) ;
+  CHECK_SCOTCH(SCOTCH_graphCheck(&graf), "scotch_graphcheck", 0) ;
+
+  permVrtTab = (SCOTCH_Num *)M_calloc(vertNbr + 1, sizeof(SCOTCH_Num), "renumbering");
+
+  CHECK_SCOTCH(kPartBoxCompute(graf, vertNbr, boxVertNbr, permVrtTab), "boxCompute", 0);
+
+  SCOTCH_graphExit(&graf) ;
+
+  M_free(vertTab);
+  M_free(vendTab);
+  M_free(edgeTab);
+
+
+  permNodTab = (int *)M_calloc(mesh->np + 1, sizeof(int), "renumbering");
+
+  /* Computing the new point list and modifying the sol structures*/
+  tetras = (MMG_pTetra)M_calloc(mesh->nemax+1,sizeof(MMG_Tetra),"renumbering");
+
+  points = (MMG_pPoint)M_calloc(mesh->npmax+1,sizeof(MMG_Point),"renumbering");
+
+  metNew = (double*)M_calloc(sol->npmax+1,sol->offset*sizeof(double),"renumbering");
+
+  nereal = 0;
+  npreal = 1;
+  for(tetraIdx = 1 ; tetraIdx < mesh->ne + 1 ; tetraIdx++) {
+    ptet = &mesh->tetra[tetraIdx];
+
+    /* Testing if the tetra exists */
+    if (!ptet->v[0]) continue;
+
+    /* Building the new point list */
+    tetras[permVrtTab[vertOldTab[tetraIdx]]] = *ptet;  
+    nereal++;
+
+    for(j = 0 ; j <= 3 ; j++) {
+
+      nodeGlbIdx = mesh->tetra[tetraIdx].v[j];
+
+      if (permNodTab[nodeGlbIdx]) continue;
+
+      ppt = &mesh->point[nodeGlbIdx];
+
+      if (!(ppt->tag & M_UNUSED)) {
+        /* Building the new point list */
+        permNodTab[nodeGlbIdx] = npreal++;
+
+        points[permNodTab[nodeGlbIdx]] = *ppt;  
+
+        /* Building the new sol met */
+        addrOld = (nodeGlbIdx-1)*sol->offset + 1;
+        addrNew = (permNodTab[nodeGlbIdx]-1)*sol->offset + 1;
+        memcpy(&metNew[addrNew], &sol->met[addrOld], sol->offset*sizeof(double));
+      }
+    }
+  }
+
+
+  M_free(mesh->tetra);
+  mesh->tetra = tetras;
+  mesh->ne = nereal;
+
+  M_free(mesh->point);
+  mesh->point = points;
+  mesh->np    = npreal - 1;
+
+  M_free(sol->met);
+  sol->met = metNew;
+
+  trias = (MMG_pTria)M_calloc(mesh->ntmax+1,sizeof(MMG_Tria),"renumbering");
+
+  ntreal = 1;
+  for(triaIdx = 1 ; triaIdx < mesh->nt + 1 ; triaIdx++) {
+    ptri = &mesh->tria[triaIdx];
+
+    /* Testing if the tetra exists */
+    if (!ptri->v[0]) continue;
+
+    /* Building the new point list */
+    trias[ntreal] = *ptri;  
+    ntreal++;
+  }
+
+  M_free(mesh->tria);
+  mesh->tria = trias;
+  mesh->nt = ntreal - 1;
+
+  mesh->npnil = mesh->np + 1;
+  mesh->nenil = mesh->ne + 1;
+
+  for (k=mesh->npnil; k<mesh->npmax-1; k++)
+    mesh->point[k].tmp  = k+1;
+
+  for (k=mesh->nenil; k<mesh->nemax-1; k++)
+    mesh->tetra[k].v[3] = k+1;
+
+  if ( mesh->nt ) {
+    mesh->ntnil = mesh->nt + 1;
+    for (k=mesh->ntnil; k<mesh->ntmax-1; k++)
+      mesh->tria[k].v[2] = k+1;
+  }
+
+
+
+  /* Modifying the numbering of the nodes of each tetra */
+  for(tetraIdx = 1 ; tetraIdx < mesh->ne + 1 ; tetraIdx++) {
+    if (!mesh->tetra[tetraIdx].v[0]) continue;
+    for(j = 0 ; j <= 3 ; j++) {
+      mesh->tetra[tetraIdx].v[j] = permNodTab[mesh->tetra[tetraIdx].v[j]];
+    }
+  }
+
+  /* Modifying the numbering of the nodes of each triangle */
+  for(triaIdx = 1 ; triaIdx < mesh->nt + 1 ; triaIdx++) {  
+    if (!mesh->tria[triaIdx].v[0]) continue;  
+    for(j = 0 ; j <= 2 ; j++) {
+      mesh->tria[triaIdx].v[j] = permNodTab[mesh->tria[triaIdx].v[j]];
+    } 
+  }
+
+  M_free(permVrtTab);
+
+  return 1;
+}
+#endif
\ No newline at end of file
diff --git a/contrib/mmg3d/build/sources/librnbg.h b/contrib/mmg3d/build/sources/librnbg.h
new file mode 100644
index 0000000000000000000000000000000000000000..97639a447cd5c7914b079c976f758b17d7cdf6a2
--- /dev/null
+++ b/contrib/mmg3d/build/sources/librnbg.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+/* librnbg
+*
+* Written by Cedric Lachat
+*/  
+#ifdef USE_SCOTCH
+
+#ifndef __RENUM__
+#define __RENUM__
+
+#include <scotch.h>
+
+#define HASHPRIME 37
+#define EDGEGAP 100
+
+typedef struct MeshGraphHash_ {
+ int vertNum;
+ int vertEnd;
+} MeshGraphHash;
+
+int renumbering(int vertBoxNbr, MMG_pMesh mesh, MMG_pSol sol) ;
+
+#endif /* __RENUM__ */
+#endif
\ No newline at end of file
diff --git a/contrib/mmg3d/build/sources/locate.c b/contrib/mmg3d/build/sources/locate.c
new file mode 100644
index 0000000000000000000000000000000000000000..c01826d9dc19737d19d862054338453defbf01ec
--- /dev/null
+++ b/contrib/mmg3d/build/sources/locate.c
@@ -0,0 +1,141 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+#define EPST    -1.e-14
+#define EPSR     1.e+14
+
+
+/* find tetra containg p, starting nsdep */
+int MMG_loctet(pMesh mesh,int nsdep,int base,double *p,double *cb) {
+  pTetra   pt;
+  pPoint   p0,p1,p2,p3;
+  double   bx,by,bz,cx,cy,cz,dx,dy,dz,vx,vy,vz,apx,apy,apz;
+  double   epsra,vol1,vol2,vol3,vol4,dd; 
+  int     *adj,iadr,it,nsfin;
+
+  it    = 0;
+  nsfin = nsdep;
+  /*printf("locateTetra: searching for %f %f %f , init %d\n",p[0],p[1],p[2],nsdep);*/
+  do {
+    if ( !nsfin )  return(0);
+    pt = &mesh->tetra[nsfin];
+    if ( !pt->v[0] )  return(0);
+    if ( pt->mark == base )  return(0);
+    pt->mark = base;
+    iadr = 4*(nsfin-1)+1;
+    adj  = &mesh->adja[iadr];
+    p0   = &mesh->point[pt->v[0]];
+    p1   = &mesh->point[pt->v[1]];
+    p2   = &mesh->point[pt->v[2]];
+    p3   = &mesh->point[pt->v[3]];
+
+    /* barycentric */
+    bx  = p1->c[0] - p0->c[0];
+    by  = p1->c[1] - p0->c[1];
+    bz  = p1->c[2] - p0->c[2];
+    cx  = p2->c[0] - p0->c[0];
+    cy  = p2->c[1] - p0->c[1];
+    cz  = p2->c[2] - p0->c[2];
+    dx  = p3->c[0] - p0->c[0];
+    dy  = p3->c[1] - p0->c[1];
+    dz  = p3->c[2] - p0->c[2];
+
+    /* test volume */
+    vx  = cy*dz - cz*dy;
+    vy  = cz*dx - cx*dz;
+    vz  = cx*dy - cy*dx;
+
+    epsra = EPST*(bx*vx + by*vy + bz*vz);
+    apx = p[0] - p0->c[0];
+    apy = p[1] - p0->c[1];
+    apz = p[2] - p0->c[2];
+
+    /* p in 2 */
+    vol2  = apx*vx + apy*vy + apz*vz;
+    if ( epsra > vol2 ) {
+      nsfin = adj[1]/4;
+      continue;
+    }
+
+    /* p in 3 */
+    vx  = by*apz - bz*apy;
+    vy  = bz*apx - bx*apz;
+    vz  = bx*apy - by*apx;
+    vol3 = dx*vx + dy*vy + dz*vz;
+    if ( epsra > vol3 ) {
+      nsfin = adj[2]/4;
+      continue;
+    }
+    
+    /* p in 4 */
+    vol4 = -cx*vx - cy*vy - cz*vz;
+    if ( epsra > vol4 ) {
+      nsfin = adj[3]/4;
+      continue;
+    }
+    
+    /* p in 1 */
+    vol1 = -epsra * EPSR - vol2 - vol3 - vol4;
+    if ( epsra > vol1 ) {
+      nsfin = adj[0]/4;
+      continue;
+    }
+
+    dd = vol1+vol2+vol3+vol4;
+    if ( dd != 0.0 )  dd = 1.0 / dd;
+    cb[0] = vol1 * dd;
+    cb[1] = vol2 * dd;
+    cb[2] = vol3 * dd;
+    cb[3] = vol4 * dd; 
+    
+    return(nsfin);
+  }
+  while ( ++it <= mesh->ne );
+
+  return(0);
+}
+
diff --git a/contrib/mmg3d/build/sources/matrix.c b/contrib/mmg3d/build/sources/matrix.c
new file mode 100644
index 0000000000000000000000000000000000000000..d09a8212ee377a8f0fe49d28427f5e4b6a82543f
--- /dev/null
+++ b/contrib/mmg3d/build/sources/matrix.c
@@ -0,0 +1,96 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#define EPS3    1.e-42
+#define EPS     1e-6
+
+/* invert 3x3 symmetric matrix */
+int MMG_invmat(double *m,double *mi) {
+  double  aa,bb,cc,det,vmin,vmax,maxx;
+  int     k;
+
+  /* check diagonal matrices */
+  vmax = fabs(m[1]);
+  maxx = fabs(m[2]);
+  if( maxx > vmax ) vmax = maxx;
+  maxx = fabs(m[4]);
+  if( maxx > vmax ) vmax = maxx;
+  if ( vmax < EPS ) {
+    mi[0]  = 1./m[0];
+    mi[3]  = 1./m[3];
+    mi[5]  = 1./m[5];
+    mi[1] = mi[2] = mi[4] = 0.0;
+    return(1);
+  }
+
+  /* check ill-conditionned matrix */
+  vmin = vmax = fabs(m[0]);
+  for (k=1; k<6; k++) {
+    maxx = fabs(m[k]);
+    if ( maxx < vmin )  vmin = maxx;
+    else if ( maxx > vmax )  vmax = maxx;
+  }
+  if ( vmax == 0.0 )  return(0);
+  /* compute sub-dets */
+  aa  = m[3]*m[5] - m[4]*m[4];
+  bb  = m[4]*m[2] - m[1]*m[5];
+  cc  = m[1]*m[4] - m[2]*m[3];
+  det = m[0]*aa + m[1]*bb + m[2]*cc;
+  if ( fabs(det) < EPS3 )  return(0);
+  det = 1.0 / det;
+
+  mi[0] = aa*det;
+  mi[1] = bb*det;
+  mi[2] = cc*det;
+  mi[3] = (m[0]*m[5] - m[2]*m[2])*det;
+  mi[4] = (m[1]*m[2] - m[0]*m[4])*det;
+  mi[5] = (m[0]*m[3] - m[1]*m[1])*det;
+
+  return(1);
+}
diff --git a/contrib/mmg3d/build/sources/memory.c b/contrib/mmg3d/build/sources/memory.c
new file mode 100644
index 0000000000000000000000000000000000000000..9219eb3d56542c51bfae0408bcac8cc32ba5f494
--- /dev/null
+++ b/contrib/mmg3d/build/sources/memory.c
@@ -0,0 +1,284 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+/* file    : memory.c
+ *   C code for memory debugging, to be used in lieu
+ *   of standard memory functions
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "memory.h"
+
+
+typedef struct memstack {
+  size_t   size;
+  void    *ptr;
+  int      nxt;
+  char     call[30];
+} Memstack;
+
+typedef Memstack   * pMemstack;
+
+const int  MAXMEM = 300;
+pMemstack  mstack;
+int        stack,cur;
+
+
+int M_memLeak() {
+  int   i,c=0;
+
+  for (i=1; i<=MAXMEM; i++)
+    if (mstack[i].ptr)  c++;
+  return(c);
+}
+
+/* print out allocated pointers */
+void M_memDump() {
+  size_t  size;
+  int     i,c;
+  static long mega = 1024 * 1024;
+  static long kilo = 1024;
+
+  fprintf(stdout,"\n  -- MEMORY USAGE\n");
+  fprintf(stdout,"  Allocated pointers\n");
+  size = 0;
+  c    = 0;
+  for (i=1; i<=MAXMEM; i++)
+    if ( mstack[i].ptr ) {
+      fprintf(stdout,"   %3d  %3d Pointer %10p  size ",++c,i,mstack[i].ptr);
+      if (mstack[i].size > mega)
+        fprintf(stdout,"   %10d Mbytes  ",(int)(mstack[i].size/mega));
+      else if (mstack[i].size > kilo)
+        fprintf(stdout,"   %10d Kbytes  ",(int)(mstack[i].size/kilo));
+      else 
+        fprintf(stdout,"   %10d  bytes  ",(int)(mstack[i].size));
+      fprintf(stdout,"(%s)\n",mstack[i].call);
+      size += mstack[i].size;
+    }
+  fprintf(stdout,"  Memory leaks    ");
+  if ( size > mega )
+    fprintf(stdout,"  %10d Mbytes  %d pointers\n",(int)(size/mega),c);
+  else if ( size > kilo )
+    fprintf(stdout,"  %10d Kbytes  %d pointers\n",(int)(size/kilo),c);
+  else if ( size )
+    fprintf(stdout,"  %10d bytes   %d pointers\n",(int)size,c);
+}
+
+/* Returns allocated memory space in bytes */
+size_t M_memSize() {
+  size_t size;
+  int    i;
+
+  size = 0;
+  for (i=1; i<=MAXMEM; i++)
+    if ( mstack[i].ptr )
+      size += mstack[i].size;
+  return size;
+}
+
+/* Allocates space for a block of at least size bytes,
+   but does not initialize the space. */
+void *M_malloc(size_t size,char *call) {
+  int   i;
+
+  /* check if first call */
+  if ( !mstack ) {
+    mstack = (Memstack *)calloc((1+MAXMEM),sizeof(Memstack));
+    assert(mstack);
+    for (i=1; i<MAXMEM; i++)
+      mstack[i].nxt    = i+1;
+    cur   = 1;
+    stack = 0;
+  }
+
+  /* store pointer, size */
+  if ( stack < MAXMEM ) {
+    mstack[cur].ptr  = malloc(size);
+    assert(mstack[cur].ptr);
+    mstack[cur].size = size;
+    /* i.e. mstack[cur].call = strdup(call) */
+    /* mstack[cur].call = (char*)malloc((strlen(call)+1) * sizeof(char));
+    assert(mstack[cur].call); */
+    strncpy(mstack[cur].call,call,19);
+    i = cur;
+    cur = mstack[cur].nxt;
+    ++stack;
+#ifdef MEMDEBUG
+    fprintf(stdout,"M_malloc: allocate %p of size %10d         (%g,%d)\n",
+	    mstack[cur].ptr,size,stack,cur);
+#endif
+    return(mstack[i].ptr);
+  }
+  else {
+    fprintf(stderr,"M_malloc: unable to store %10Zd bytes pointer. table full\n",
+	    size);
+    return(0);
+  }
+}
+
+
+/* Allocates space for an array of nelem elements, each of size 
+   elsize bytes, and initializes the space to zeros.  
+   Actual amount of space allocated is >=  nelem * elsize bytes. */
+void *M_calloc(size_t nelem, size_t elsize,char *call) {
+  int    i;
+
+  /* check if first call */
+  if ( !mstack ) {
+    mstack = (Memstack *)calloc((1+MAXMEM),sizeof(Memstack));
+    assert(mstack);
+    for (i=1; i<MAXMEM; i++)
+      mstack[i].nxt    = i+1;
+    cur   = 1;
+    stack = 0;
+  }
+
+  /* store pointer, size */
+  if ( stack < MAXMEM ) {
+    mstack[cur].ptr  = calloc(nelem,elsize);
+    if ( !mstack[cur].ptr )  return(0);
+
+    /*assert(mstack[cur].ptr);*/
+    mstack[cur].size = nelem * elsize;
+    /* mstack[cur].call = (char*)malloc((strlen(call)+1) * sizeof(char));
+    assert(mstack[cur].call); */
+    strncpy(mstack[cur].call,call,19);
+    i   = cur;
+    cur = mstack[cur].nxt;
+    ++stack;
+#ifdef MEMDEBUG
+    fprintf(stdout,"M_calloc: allocate %p of size %d         (%d,%d)\n",
+	    mstack[cur].ptr,nelem*elsize,stack,cur);
+#endif
+    return(mstack[i].ptr);
+  }
+  else {
+    fprintf(stderr,"M_calloc: unable to allocate %10Zd bytes. table full\n",
+	    nelem*elsize);
+    return(0);
+  }
+}
+
+/* Changes the size of the block pointed to by ptr to size bytes 
+   and returns a pointer to the (possibly moved) block. Existing 
+   contents are unchanged up to the lesser of the new and old sizes. */
+void *M_realloc(void *ptr, size_t size,char *call) {
+  int    i;
+
+  if ( !ptr )
+    return 0;
+
+  for (i=1; i<=MAXMEM; i++) {
+    if (ptr == mstack[i].ptr) {
+      /* free(mstack[i].call);
+      mstack[cur].call = (char*)malloc((strlen(call)+1) * sizeof(char));
+      assert(mstack[cur].call); */
+      strncpy(mstack[i].call,call,19);
+      mstack[i].ptr = realloc(mstack[i].ptr,size);
+      if (size)
+	assert(mstack[i].ptr);
+      mstack[i].size = size;
+#ifdef MEMDEBUG
+      fprintf(stdout,"M_realloc: reallocate %p of size %d       (%d)\n",
+	      mstack[i].ptr,mstack[i].size,size);
+#endif
+      return(mstack[i].ptr);
+    }
+  }
+#ifdef MEMDEBUG
+  fprintf(stderr,"M_realloc: pointer %p not found\n",ptr);
+#endif
+  return(0);
+}
+
+/* Deallocates the space pointed to by ptr (a pointer to a block 
+   previously allocated by malloc() and makes the space available
+   for further allocation.  If ptr is NULL, no action occurs. */
+void M_free(void *ptr) {
+  int   i;
+  
+  assert(ptr);
+  for (i=1; i<=MAXMEM; i++) {
+    if (mstack[i].ptr && ptr == mstack[i].ptr) {
+      --stack;
+      free(mstack[i].ptr);
+      mstack[i].ptr  = 0;
+      mstack[i].size = 0;
+      mstack[i].nxt  = cur;
+      mstack[i].call[0]  = '\0';
+      cur = i;
+#ifdef MEMDEBUG
+      fprintf(stdout,"M_free: deallocate %p of size %d       (%d,%d)\n",
+	      ptr,mstack[i].size,stack,cur);
+#endif
+      return;
+    }
+  }
+#ifdef MEMDEBUG
+  fprintf(stderr,"M_free: pointer %p not found\n",ptr);
+#endif
+}
+
+
+/* dump memory requirements */
+void primem(int np) {
+  int memsize;
+
+  memsize = M_memSize();
+  if ( memsize ) {
+    fprintf(stdout,"\n  -- MEMORY REQUIREMENTS\n");
+    if (memsize > 1024*1024)
+      fprintf(stdout,"  Total size :  %10Zd Mbytes",
+	      (long int)(memsize/(1024.*1024.)));
+    else if (memsize > 1024)
+      fprintf(stdout,"  Total size :  %10Zd Kbytes",(long int)(memsize/1024.));
+    else
+      fprintf(stdout,"  Total size :  %10Zd bytes ",(long int)memsize);
+    fprintf(stdout,"    (i.e. %d bytes/point)\n",memsize / np);
+  }
+}
diff --git a/contrib/mmg3d/build/sources/memory.h b/contrib/mmg3d/build/sources/memory.h
new file mode 100644
index 0000000000000000000000000000000000000000..dc85346434464576c403bbae7eb75e90d2757a54
--- /dev/null
+++ b/contrib/mmg3d/build/sources/memory.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <assert.h>
+
+/* prototype (re)definitions */
+void  *M_malloc(size_t size,char *call);
+void  *M_calloc(size_t nelem,size_t elsize,char *call);
+void  *M_realloc(void *ptr, size_t size,char *call);
+void   M_free(void *ptr);
+
+/* ptototypes : tools */
+int    M_memLeak();
+void   M_memDump();
+size_t M_memSize();
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/contrib/mmg3d/build/sources/mesh.h b/contrib/mmg3d/build/sources/mesh.h
new file mode 100644
index 0000000000000000000000000000000000000000..efa8ae9ccff11a20258510b1cef4d492e3fb7f7f
--- /dev/null
+++ b/contrib/mmg3d/build/sources/mesh.h
@@ -0,0 +1,411 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#ifndef _MMG3D_H
+#define _MMG3D_H
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#include <float.h>
+
+
+#include "chrono.h"
+#include "memory.h"
+
+#include "libmmg3d.h"
+#include "libmmg3d_internal.h"
+#include "mmg3dConfig.h"
+#include "eigenv.h"
+
+#define M_VER "4.0 c"
+#define M_REL "July 20, 2010"
+#define M_STR "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"
+
+#define EPS      1.e-06
+#define EPS1     1.e-9
+#define EPS2     1.e-12
+#define EPSOK    1.e-18
+#define EPS30    1.e-30
+
+#define ALPHAC   0.20412415      /* sqrt(6)/12 */  
+#define ALPHAD   0.04811252      /* 1.0/(12*sqrt(3)) */
+#define BETAC    0.03928371      /* sqrt(2)/36 */   
+#define CALLIM   1.E+35    	    /*valeur de la qual pire*/
+
+
+#define LLONG    1.41
+#define LSHORT   0.68
+#define LFILT    0.7
+#define QDEGRAD  2.45
+
+#define LONMAX     4096//512
+#define NPMAX    500000
+#define NTMAX   1000000
+#define NEMAX   3000000
+
+#define PRECI       1
+#define BUCKSIZ    64
+
+#define M_MIN(a,b) ( (a) < (b) ? (a) : (b) )
+#define M_MAX(a,b) ( (a) < (b) ? (b) : (a) )
+
+#define M_NOTAG     (0)
+#define M_UNUSED    (1 << 0)
+#define M_BDRY      (1 << 1)
+#define M_MOVE      (1 << 2)
+#define M_CAVITY    (1 << 3)
+#define M_CORNER    (1 << 4)
+#define M_REQUIRED  (1 << 5)
+#define M_RIDGE_GEO (1 << 6)
+#define M_RIDGE_REF (1 << 7)
+#define ALL_BDRY   63
+
+/*#ifdef INT_MAX
+#undef INT_MAX
+#undef SHORT_MAX
+#endif
+*/#define INT_MAX      0x7fffffff
+#define SHORT_MAX    0x7fff
+
+
+extern unsigned char MMG_idir[4][3];
+extern unsigned char MMG_inxt[7];
+extern unsigned char MMG_iarf[4][3];
+extern unsigned char MMG_iare[6][2];
+extern unsigned char MMG_ifar[6][2];
+extern unsigned char MMG_isar[6][2];
+extern unsigned char MMG_arpt[4][3];
+                             
+
+typedef struct {
+  int      min,max,iel,nxt;
+} hedge;
+typedef struct {
+  int      size,nhmax,hnxt;
+  hedge   *item;  
+} Hedge;
+typedef Hedge * pHedge;
+
+typedef struct {
+  int     *blay,*blref,nblay;
+} Blayer;
+
+
+typedef struct slist {
+  Hedge    hedg;
+  double    qual[LONMAX+1];
+  int      tetra[LONMAX+1];
+} List;
+typedef List * pList;
+
+typedef struct squeue {
+  int    *stack,cur;
+} Queue;
+typedef Queue * pQueue;
+
+typedef struct {
+  int     size,curc;
+  int    *cell;
+  int    *link;
+} Heap;
+typedef Heap * pHeap;
+
+typedef struct {
+  int     size;
+  int    *head;
+  int    *link;
+} Bucket;
+typedef Bucket * pBucket;
+
+/*basic*/
+int MMG_setfunc(int );
+
+int MMG_cutprism(pMesh mesh,pHedge hed,int k,int p0,int p1,int p2,int p3,int p4,int p5,int ref);
+int MMG_cuthex(pMesh mesh,pHedge hed,int k,int p0,int p1,int p2,int p3,int p4,int p5,int p6,int p7, int ref);
+
+int MMG_analar(pMesh ,pSol ,pBucket ,int *,int *,int *,int *);
+int MMG_analarcutting(pMesh ,pSol ,pHedge ,int *,double* ,double );
+int MMG_boulep(pMesh ,int ,int ,pList );
+int MMG_bouleg(pMesh ,int ,int ,pList );
+int MMG_coquil(pMesh ,int ,int ,pList );
+int MMG_cendel(pMesh ,pSol ,double ,int );
+int MMG_spledg(pMesh ,pSol ,pQueue ,pList ,int ,double ,double );
+
+int MMG_interp_ani(double *,double *,double *,double );
+int MMG_interplog(double *,double *,double *,double *,double );
+int MMG_interp_iso(double *,double *,double *,double );
+
+/* delaunay */
+int MMG_correction(pMesh ,int ,pList ,int ,int ,char );
+int MMG_delone(pMesh ,pSol ,int ,pList ,int );
+int MMG_delons(pMesh ,pSol ,pQueue ,int ,pList ,int ,double );
+int MMG_cenrad_ani(pMesh ,double * ,double *,double *,double *); 
+int MMG_cenrad_iso(pMesh ,double * ,double *,double *); 
+
+/*pattern*/
+int MMG_pattern1(pMesh ,pSol ,pHedge ,int );
+int MMG_pattern2(pMesh ,pSol ,pHedge ,int );
+int MMG_pattern3(pMesh ,pSol ,pHedge ,int );
+int MMG_pattern4(pMesh ,pSol ,pHedge ,int );
+int MMG_pattern5(pMesh ,pSol ,pHedge ,int );
+int MMG_pattern6(pMesh ,pSol ,int ,int* );
+int MMG_pattern22(pMesh ,pSol ,pHedge ,int );
+int MMG_pattern31(pMesh ,pSol ,pHedge ,int );
+int MMG_pattern32(pMesh ,pSol ,pHedge ,int );
+int MMG_pattern33(pMesh ,pSol ,pHedge ,int );
+int MMG_pattern41(pMesh ,pSol ,pHedge ,int );
+
+int MMG_colpoi(pMesh ,pSol ,int ,int ,int ,double );
+
+/* hash */
+int  MMG_hashTetra(pMesh );
+int  MMG_hashEdge(pMesh ,pHedge ,int ,int ,int *);
+int  MMG_inEdge(pHedge ,int *,int *,int *);
+int  MMG_markBdry(pMesh );
+int  MMG_edgePoint(pHedge ,int ,int );
+int  MMG_edgePut(pHedge ,int ,int ,int );
+
+
+int  MMG_loctet(pMesh ,int ,int ,double *,double *);
+int  MMG_computeMetric(pMesh ,pSol ,int ,double * );
+
+/* scale */
+int  MMG_doSol(pMesh ,pSol );
+int  MMG_scaleMesh(pMesh ,pSol );
+int  MMG_unscaleMesh(pMesh ,pSol );
+
+int  MMG_mmg3d1(pMesh ,pSol ,int *);
+int  MMG_mmg3d9(pMesh ,pSol ,int *);
+int  MMG_mmg3d4(pMesh ,pSol ,int *);
+
+/* zaldy */
+int  MMG_newPt(pMesh ,double *c);
+int  MMG_newElt(pMesh );
+int  MMG_getnElt(pMesh ,int );
+int  MMG_newTria(pMesh );
+void MMG_delPt(pMesh ,int );
+void MMG_delElt(pMesh ,int );
+void MMG_delTria(pMesh ,int );
+int  MMG_zaldy(pMesh );
+int  MMG_zaldy3(pSol );
+int  MMG_zaldy4(pHedge ,int );
+
+int  MMG_optra4(pMesh ,pSol );
+int  MMG_optcoq(pMesh ,pSol);
+int  MMG_opttet(pMesh ,pSol);
+int  MMG_opttyp(pMesh ,pSol ,double ,int *);
+int  MMG_optbdry(pMesh ,pSol ,int );
+int  MMG_opt2peau(pMesh ,pSol ,pQueue ,int ,double );
+int  MMG_optlap(pMesh ,pSol );
+
+/* swapar */
+int  MMG_swapar(pMesh ,pSol ,pQueue ,List *,int ,double ,double );
+
+int  MMG_simu23(pMesh ,pSol ,int ,int ,double );
+int  MMG_simu32(pMesh ,pSol ,pList ,double );
+int  MMG_swap32(pMesh ,pSol ,pList );
+int  MMG_swap23(pMesh ,pSol ,pQueue ,int ,int ,double );
+
+int  MMG_simu44(pMesh ,pSol ,pList ,double );
+int  MMG_swap44_1(pMesh ,pSol ,pList );
+int  MMG_swap44_2(pMesh ,pSol ,pList );
+
+int  MMG_simu56(pMesh ,pSol ,pList ,double );
+int  MMG_swap56_1(pMesh ,pSol ,pList );
+int  MMG_swap56_2(pMesh ,pSol ,pList );
+int  MMG_swap56_3(pMesh ,pSol ,pList );
+int  MMG_swap56_4(pMesh ,pSol ,pList );
+int  MMG_swap56_5(pMesh ,pSol ,pList );
+
+int MMG_simu68(pMesh ,pSol ,pList ,double );
+int MMG_swap68_1(pMesh ,pSol ,pList );
+int MMG_swap68_2(pMesh ,pSol ,pList );
+int MMG_swap68_3(pMesh ,pSol ,pList );
+int MMG_swap68_4(pMesh ,pSol ,pList );
+int MMG_swap68_5(pMesh ,pSol ,pList );
+int MMG_swap68_6(pMesh ,pSol ,pList );
+int MMG_swap68_7(pMesh ,pSol ,pList );
+int MMG_swap68_8(pMesh ,pSol ,pList );
+int MMG_swap68_9(pMesh ,pSol ,pList );
+int MMG_swap68_10(pMesh ,pSol ,pList );
+int MMG_swap68_11(pMesh ,pSol ,pList );
+int MMG_swap68_12(pMesh ,pSol ,pList );
+int MMG_swap68_13(pMesh ,pSol ,pList );
+int MMG_swap68_14(pMesh ,pSol ,pList );
+
+int MMG_simu710(pMesh ,pSol ,pList ,double );
+int MMG_swap710_1(pMesh ,pSol ,pList );
+int MMG_swap710_2(pMesh ,pSol ,pList );
+int MMG_swap710_3(pMesh ,pSol ,pList );
+int MMG_swap710_4(pMesh ,pSol ,pList );
+int MMG_swap710_5(pMesh ,pSol ,pList );
+int MMG_swap710_6(pMesh ,pSol ,pList );
+int MMG_swap710_7(pMesh ,pSol ,pList );
+int MMG_swap710_8(pMesh ,pSol ,pList );
+int MMG_swap710_9(pMesh ,pSol ,pList );
+int MMG_swap710_10(pMesh ,pSol ,pList );
+int MMG_swap710_11(pMesh ,pSol ,pList );
+int MMG_swap710_12(pMesh ,pSol ,pList );
+int MMG_swap710_13(pMesh ,pSol ,pList );
+int MMG_swap710_14(pMesh ,pSol ,pList );
+int MMG_swap710_15(pMesh ,pSol ,pList );
+int MMG_swap710_16(pMesh ,pSol ,pList );
+int MMG_swap710_17(pMesh ,pSol ,pList );
+int MMG_swap710_18(pMesh ,pSol ,pList );
+int MMG_swap710_19(pMesh ,pSol ,pList );
+int MMG_swap710_20(pMesh ,pSol ,pList );
+int MMG_swap710_21(pMesh ,pSol ,pList );
+int MMG_swap710_22(pMesh ,pSol ,pList );
+int MMG_swap710_23(pMesh ,pSol ,pList );
+int MMG_swap710_24(pMesh ,pSol ,pList );
+int MMG_swap710_25(pMesh ,pSol ,pList );
+int MMG_swap710_26(pMesh ,pSol ,pList );
+int MMG_swap710_27(pMesh ,pSol ,pList );
+int MMG_swap710_28(pMesh ,pSol ,pList );
+int MMG_swap710_29(pMesh ,pSol ,pList );
+int MMG_swap710_30(pMesh ,pSol ,pList );
+int MMG_swap710_31(pMesh ,pSol ,pList );
+int MMG_swap710_32(pMesh ,pSol ,pList );
+int MMG_swap710_33(pMesh ,pSol ,pList );
+int MMG_swap710_34(pMesh ,pSol ,pList );
+int MMG_swap710_35(pMesh ,pSol ,pList );
+int MMG_swap710_36(pMesh ,pSol ,pList );
+int MMG_swap710_37(pMesh ,pSol ,pList );
+int MMG_swap710_38(pMesh ,pSol ,pList );
+int MMG_swap710_39(pMesh ,pSol ,pList );
+int MMG_swap710_40(pMesh ,pSol ,pList );
+int MMG_swap710_41(pMesh ,pSol ,pList );
+int MMG_swap710_42(pMesh ,pSol ,pList );
+
+int  MMG_typelt(pMesh ,int ,int *);
+
+/* quality */
+double MMG_voltet(pMesh ,int );
+double MMG_quickvol(double *,double *,double *,double *);
+int    MMG_prilen(pMesh ,pSol );
+int    MMG_outqua(pMesh ,pSol );
+int    MMG_outquacubic(pMesh ,pSol );
+double MMG_priworst(pMesh , pSol );
+int MMG_ratio(pMesh mesh, pSol sol,char* filename);
+
+int  MMG_chkmsh(pMesh ,int ,int );
+
+/* bucket */
+pBucket MMG_newBucket(pMesh ,int );
+int     MMG_addBucket(pMesh ,pBucket ,int );
+int     MMG_delBucket(pMesh ,pBucket ,int );
+void    MMG_freeBucket(pBucket );
+
+/* heap */
+Heap *MMG_hipini(pMesh ,int ,short ,double ,int );
+void  MMG_hipfree(Heap *);
+int   MMG_hipput(pMesh ,Heap *,int );
+int   MMG_hippop(pMesh ,Heap *);
+void  MMG_hiprep(pMesh ,Heap *,int );
+void  MMG_hipdel(pMesh ,Heap *,int );
+
+/* queue */
+pQueue MMG_kiuini(pMesh ,int ,double ,int );
+int    MMG_kiupop(pQueue );
+int    MMG_kiudel(pQueue ,int );
+int    MMG_kiuput(pQueue ,int );
+void   MMG_kiufree(pQueue );
+
+/* matrices */
+int MMG_invmat(double *,double *);
+
+double MMG_calte3_ani(pMesh mesh,pSol sol,int iel);
+
+/* function pointers */
+double MMG_long_ani(double *,double *,double *,double *);
+double MMG_long_iso(double *,double *,double *,double *);
+double MMG_caltetcubic(pMesh mesh,pSol sol,int iel);
+double MMG_caltetrao(pMesh mesh,pSol sol,int iel);
+double MMG_caltet_ani(pMesh mesh,pSol sol,int iel);
+double MMG_caltet_iso(pMesh mesh,pSol sol,int iel);
+double MMG_calte1_iso(pMesh mesh,pSol sol,int iel);
+double MMG_calte1_ani(pMesh mesh,pSol sol,int iel);
+double MMG_callong(pMesh mesh,pSol sol,int iel);
+int    MMG_caltet2_iso(pMesh mesh,pSol sol,int iel,int ie,double ,double * caltab);
+int    MMG_caltet2_ani(pMesh mesh,pSol sol,int iel,int ie,double ,double * caltab);
+int    MMG_caltet2long_ani(pMesh mesh,pSol sol,int iel,int ie,double crit, double * caltab);
+int    MMG_caltet2long_iso(pMesh mesh,pSol sol,int iel,int ie,double crit, double * caltab);
+int    MMG_buckin_ani(pMesh mesh,pSol sol,pBucket bucket,int ip);
+int    MMG_buckin_iso(pMesh mesh,pSol sol,pBucket bucket,int ip);
+int    MMG_cavity_ani(pMesh mesh,pSol sol,int iel,int ip,pList list,int lon);
+int    MMG_cavity_iso(pMesh mesh,pSol sol,int iel,int ip,pList list,int lon);
+int    MMG_optlen_ani(pMesh mesh,pSol sol,double declic,int base);
+int    MMG_optlen_iso(pMesh mesh,pSol sol,double declic,int base);
+int    MMG_optlen_iso_new(pMesh mesh,pSol sol,double declic,int base);
+int    MMG_optlen_iso2(pMesh mesh,pSol sol,double declic);
+int    MMG_interp_ani(double *,double *,double * ,double );
+int    MMG_interp_iso(double *,double *,double * ,double );
+int    MMG_optlentet_ani(pMesh ,pSol ,pQueue ,double ,int ,int );
+int    MMG_optlentet_iso(pMesh ,pSol ,pQueue ,double ,int ,int );
+int    MMG_movevertex_ani(pMesh ,pSol ,int ,int );
+int    MMG_movevertex_iso(pMesh ,pSol ,int ,int );
+
+
+/* function pointers */
+typedef int (*MMG_Swap)(pMesh ,pSol ,pList );
+MMG_Swap MMG_swpptr;
+double (*MMG_length)(double *,double *,double *,double *);
+double (*MMG_caltet)(pMesh ,pSol ,int );
+double (*MMG_calte1)(pMesh ,pSol ,int );
+int    (*MMG_caltet2)(pMesh ,pSol ,int ,int ,double ,double *);
+int    (*MMG_cavity)(pMesh ,pSol ,int ,int ,pList ,int );
+int    (*MMG_buckin)(pMesh ,pSol ,pBucket ,int );
+int    (*MMG_optlen)(pMesh ,pSol ,double ,int );
+int    (*MMG_interp)(double *,double *,double *,double );
+int    (*MMG_optlentet)(pMesh ,pSol ,pQueue ,double ,int ,int );
+int    (*MMG_movevertex)(pMesh ,pSol ,int ,int );
+
+
+#endif
diff --git a/contrib/mmg3d/build/sources/mmg3d.c b/contrib/mmg3d/build/sources/mmg3d.c
new file mode 100644
index 0000000000000000000000000000000000000000..b394a38a75df6dcadcc5d3c0da8e27d0cb6f3c9a
--- /dev/null
+++ b/contrib/mmg3d/build/sources/mmg3d.c
@@ -0,0 +1,701 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "compil.date"
+#include "mesh.h"
+#include "eigenv.h"
+
+TIM_mytime         MMG_ctim[TIMEMAX];
+short	             MMG_imprim;
+
+unsigned char MMG_idir[4][3] = { {1,2,3}, {0,3,2}, {0,1,3}, {0,2,1} };
+unsigned char MMG_inxt[7]    = { 1,2,3,0,1,2,3 };
+unsigned char MMG_iarf[4][3] = { {5,4,3}, {5,1,2}, {4,2,0}, {3,0,1} };
+unsigned char MMG_iare[6][2] = { {0,1}, {0,2}, {0,3}, {1,2}, {1,3}, {2,3} };
+unsigned char MMG_ifar[6][2] = { {2,3}, {1,3}, {1,2}, {0,3}, {0,2}, {0,1} };
+unsigned char MMG_isar[6][2] = { {2,3}, {3,1}, {1,2}, {0,3}, {2,0}, {0,1} };
+unsigned char MMG_arpt[4][3] = { {0,1,2}, {0,4,3}, {1,3,5}, {2,5,4} };
+
+static void excfun(int sigid) {
+  switch (sigid) {
+  case SIGFPE:
+    fprintf(stderr,"  ## FP EXCEPTION. STOP\n");
+    break;
+  case SIGILL:
+    fprintf(stderr,"  ## ILLEGAL INSTRUCTION. STOP\n");
+    break;
+  case SIGSEGV:
+    fprintf(stderr,"  ## SEGMENTATION FAULT. STOP\n");
+    break;
+  case SIGABRT:
+  case SIGTERM:
+  case SIGINT:
+    fprintf(stderr,"  ## ABNORMAL END. STOP\n");
+    break;
+  }
+  exit(1);
+}
+
+
+static void usage(char *prog) {
+  fprintf(stdout,"usage: %s [-v[n]] [-h] [-m n] [opts..] filein[.mesh] [-out fileout]\n",prog);
+  
+  fprintf(stdout,"\n** Generic options :\n");
+  fprintf(stdout,"-d      Turn on debug mode\n");
+  fprintf(stdout,"-h      Print this message\n");
+  fprintf(stdout,"-v [n]  Tune level of verbosity\n");
+  fprintf(stdout,"-m [n]  Set memory size to n Mbytes\n");
+
+  fprintf(stdout,"\n");
+  fprintf(stdout,"-O [n]  Optimization level\n");
+  fprintf(stdout,"  1      adaptation\n");
+  fprintf(stdout,"  4      use global splitting (warning modify boundary mesh)\n");
+  fprintf(stdout,"  9      moving mesh\n");
+  fprintf(stdout,"  10     transform an hexahedral/prism mesh in a tetrahedral mesh \n");
+  fprintf(stdout," -n      turn off optimisation\n");
+
+  fprintf(stdout,"\n** Misc. options\n");
+  fprintf(stdout,"-bucket [n]    Specify the size of bucket per dimension\n");
+  fprintf(stdout,"-noswap        no edge or face flipping\n");
+  fprintf(stdout,"-nomove        no point relocation\n");
+  fprintf(stdout,"-noinsert      no new point\n");
+  //fprintf(stdout,"-bdry          add points on boundary mesh\n");
+  fprintf(stdout,"-out fileout   Specify output file name\n");  
+#ifdef USE_SCOTCH
+  fprintf(stdout,"-rn n num         Specify the number of vertices by box to renumber nodes and the renumberings\n");
+#endif
+  fprintf(stdout,"-dt dt         to compute the node speed\n");
+
+  exit(1);
+}
+
+
+static int parsar(int argc,char *argv[],pMesh mesh,pSol sol) {
+  int      	i;
+  Info     	*info;
+  char    	*ptr;
+
+  info = &mesh->info;
+
+  i = 1;
+  while ( i < argc ) {
+    if ( *argv[i] == '-' ) {
+      switch(argv[i][1]) {
+      case 'h':  /* on-line help */
+      case '?':
+	      usage(argv[0]);
+	      break;
+
+      case 'b':
+	      if ( !strcmp(argv[i],"-bucket") && i < argc-1 ) {
+	        ++i;
+	        if ( isdigit(argv[i][0]) )
+	          info->bucksiz = atoi(argv[i]);
+	        else
+	          i--;
+	      }
+	      else if ( !strcmp(argv[i],"-bdry") ){  
+          printf("-bdry option discarded\n");
+  	      //info->bdry = 1;
+	      }
+	      else {
+  	      fprintf(stderr,"Missing argument option %s\n",argv[i]);
+	        usage(argv[0]);
+	      }
+        break;
+      
+      case 'd':  /* debug */
+        if ( !strcmp(argv[i],"-dt") ) {
+          ++i;
+          info->dt = atof(argv[i]);
+        } else {
+          info->ddebug = 1;
+        }
+        break;
+
+      case 'i':
+        if ( !strcmp(argv[i],"-in") ) {
+          ++i;
+          mesh->name = argv[i];
+          info->imprim     = 5;
+        }
+        break;
+
+      case 'm':  /* memory */
+	if ( !strcmp(argv[i],"-mov") ) {
+          ++i;
+          mesh->move = argv[i];
+        }
+        else if ( ++i < argc ) {
+	  if ( isdigit(argv[i][0]) )
+	    info->memory = atoi(argv[i]);
+	  else
+	    i--;
+	}
+	else {
+	  fprintf(stderr,"Missing argument option %c\n",argv[i-1][1]);
+	  usage(argv[0]);
+	}
+        break;
+
+      case 'n':
+        if ( !strcmp(argv[i],"-noswap") )
+	  info->noswap = 1;
+	else if( !strcmp(argv[i],"-noinsert") )
+	  info->noinsert = 1;
+	else if( !strcmp(argv[i],"-nomove") )
+	  info->nomove = 1;
+        break;
+
+      case 'o':
+        if ( !strcmp(argv[i],"-out") ) {
+          ++i;
+          mesh->outf = argv[i];
+        }
+        break;
+
+      case 'O':  /* option */
+        if ( ++i < argc ) {
+	  if ( (argv[i][0] == '-' && isdigit(argv[i][1])) ||
+	        argv[i][0] == '0' )
+	    info->option = atoi(argv[i]);
+	  else if ( isdigit(argv[i][0]) )
+	    info->option = atoi(argv[i]);
+	  else
+	    i--;
+	}
+        break;
+
+      case 's':
+        if ( !strcmp(argv[i],"-sol") ) {
+          ++i;
+          sol->name = argv[i];
+        }
+        break; 
+#ifdef USE_SCOTCH
+ /* renumbering begin */
+      case 'r':
+        if ( !strcmp(argv[i],"-rn") ) {
+          if ( ++i < argc ) {
+            if ( isdigit(argv[i][0]) )
+              info->rn = atoi(argv[i]);
+            else {
+              fprintf(stderr,"Missing argument option %s\n",argv[i-1]);
+              usage(argv[0]);
+            }
+            if ( ++i < argc ) {
+              if ( isdigit(argv[i][0]) ) {
+                info->rn2 = atoi(argv[i]);
+                if (! ((info->rn2>=0) && (info->rn2<=3))){
+                  fprintf(stderr,"Wrong argument option %s\n",argv[i-1]);
+                  usage(argv[0]);
+                }
+              }
+              else {
+                fprintf(stderr,"Missing argument option %s\n",argv[i-1]);
+                usage(argv[0]);
+              }
+            }
+            else {
+              fprintf(stderr,"Missing argument option %s\n",argv[i-1]);
+              usage(argv[0]);
+            }
+          }
+          else {
+            fprintf(stderr,"Missing argument option %s\n",argv[i-1]);
+            usage(argv[0]);
+          }
+        }
+        break;
+/* renumbering end */ 
+#endif
+      case 'v':
+        if ( ++i < argc ) {
+	  if ( argv[i][0] == '-' || isdigit(argv[i][0]) )
+	    info->imprim = atoi(argv[i]);
+	  else 
+	    i--;
+	}
+	else {
+	  fprintf(stderr,"Missing argument option %c\n",argv[i-1][1]);
+	  usage(argv[0]);
+	}
+	break;
+
+      default:
+	fprintf(stderr,"  Unrecognized option %s\n",argv[i]);
+	usage(argv[0]);
+      }
+    }
+
+    else {
+      if ( mesh->name == NULL ) {
+        mesh->name = argv[i];
+        info->imprim = 5;
+      }
+      else if ( mesh->outf == NULL )
+        mesh->outf = argv[i];
+      else if ( mesh->move == NULL )
+        mesh->move = argv[i];
+      else {
+        fprintf(stdout,"  Argument %s ignored\n",argv[i]);
+	      usage(argv[0]);
+      }
+    }
+    i++;
+  }
+
+  /* check file names */
+  if ( mesh->name == NULL || info->imprim == -99 ) {
+    fprintf(stdout,"\n  -- PRINT (0 10(advised) -10) ?\n");
+    fflush(stdin);
+    fscanf(stdin,"%d",&i);
+    info->imprim = i;
+  }
+
+  if ( mesh->name == NULL ) {
+    mesh->name = (char *)calloc(128,sizeof(char));
+    assert(mesh->name);
+    fprintf(stdout,"  -- FILE BASENAME ?\n");
+    fflush(stdin); 
+    fscanf(stdin,"%s",mesh->name);
+  }
+  if ( sol->name == NULL ) {
+    sol->name = (char *)calloc(128,sizeof(char));
+    assert(sol->name);
+    strcpy(sol->name,mesh->name);
+  }
+  if ( mesh->outf == NULL ) {
+    mesh->outf = (char *)calloc(128,sizeof(char));
+    assert(mesh->outf);
+    strcpy(mesh->outf,mesh->name);
+    ptr = strstr(mesh->outf,".mesh");
+    if ( ptr ) *ptr = '\0';
+    strcat(mesh->outf,".o.meshb");
+  }
+  if ( abs(info->option) == 9 && mesh->move == NULL ) {
+    mesh->move = (char *)calloc(128,sizeof(char));
+    assert(mesh->move);
+    fprintf(stdout,"  -- DISPLACEMENT FILE ?\n");
+    fflush(stdin); 
+    fscanf(stdin,"%s",mesh->move);
+  }
+
+  return(1);
+}
+ 
+
+int parsop(pMesh mesh) {
+  int      i,ret;
+  char    *ptr,data[256];
+  FILE    *in;
+
+  strcpy(data,mesh->name);
+  ptr = strstr(data,".mesh");
+  if ( ptr )  *ptr = '\0';
+  strcat(data,".mmg");
+  in = fopen(data,"r");
+  if ( !in ) {
+    sprintf(data,"%s","DEFAULT.mmg");
+    in = fopen(data,"r");
+    if ( !in )  return(1);
+  }
+  fprintf(stdout,"  %%%% %s OPENED\n",data);
+
+  while ( !feof(in) ) {
+    ret = fscanf(in,"%s",data);
+    if ( !ret || feof(in) )  break;
+    for (i=0; i<strlen(data); i++) data[i] = tolower(data[i]);
+/*
+    if ( !strcmp(data,"blayer") ) {
+      fscanf(in,"%d",&dummi);
+      if ( dummi ) {
+        mesh->blayer.nblay = dummi;
+        mesh->blayer.blay  = (int*)calloc(dummi+1,sizeof(int));
+        assert(mesh->blayer.blay);
+        mesh->blayer.blref = (int*)calloc(dummi+1,sizeof(int));
+        assert(mesh->blayer.blref);
+        for (j=0; j<=dummi; j++)
+          fscanf(in,"%d %d",&mesh->blayer.blay[j],&mesh->blayer.blref[j]);
+      }
+    }
+*/
+    fprintf(stderr,"  ** UNKNOWN KEYWORD %s\n",data);
+  }
+  fclose(in);
+
+  return(1);
+}
+
+
+void endcod() {
+  double   ttot,ttim[TIMEMAX];
+  int      k,call[TIMEMAX];
+
+  TIM_chrono(OFF,&MMG_ctim[0]);
+  
+  for (k=0; k<TIMEMAX; k++) {
+    call[k] = MMG_ctim[k].call;
+    ttim[k] = MMG_ctim[k].call ? TIM_gttime(MMG_ctim[k]) : 0.0;
+  }
+  ttot    = ttim[1]+ttim[2]+ttim[3]+ttim[4];
+  ttim[0] = M_MAX(ttim[0],ttot);
+
+  if ( abs(MMG_imprim) > 5 ) {
+    fprintf(stdout,"\n  -- CPU REQUIREMENTS\n");
+    fprintf(stdout,"  in/out    %8.2f %%    %3d. calls,   %7.2f sec/call\n",
+	    100.*ttim[1]/ttim[0],call[1],ttim[1]/(float)call[1]);
+    fprintf(stdout,"  analysis  %8.2f %%    %3d. calls,   %7.2f sec/call\n",
+	    100.*ttim[2]/ttim[0],call[2],ttim[2]/(float)call[2]);
+    fprintf(stdout,"  optim     %8.2f %%    %3d. calls,   %7.2f sec/call\n",
+	    100.*ttim[3]/ttim[0],call[3],ttim[3]/(float)call[3]);
+    fprintf(stdout,"  total     %8.2f %%    %3d. calls,   %7.2f sec/call\n",
+	    100.*ttot/ttim[0],call[0],ttot/(float)call[0]);
+  }
+  fprintf(stdout,"\n   ELAPSED TIME  %.2f SEC.  (%.2f)\n",ttim[0],ttot);
+}
+
+
+/* set function pointers */
+int MMG_setfunc(int type) {
+  if ( type == 6 ) {
+    MMG_length     = MMG_long_ani;
+    MMG_cavity     = MMG_cavity_ani;
+    MMG_caltet     = MMG_caltet_ani;  //MMG_callong;//MMG_caltet_ani;
+    MMG_calte1     = MMG_calte1_ani;
+    MMG_caltet2    = MMG_caltet2_ani;//MMG_caltet2long_ani;
+    MMG_buckin     = MMG_buckin_ani;
+    MMG_optlen     = MMG_optlen_ani;
+    MMG_interp     = MMG_interp_ani;
+    MMG_optlentet  = MMG_optlentet_ani;
+    MMG_movevertex = MMG_movevertex_ani;
+  }
+  else if ( type == 1 ) {
+    MMG_length     = MMG_long_iso;
+    MMG_cavity     = MMG_cavity_iso;
+    MMG_caltet     = MMG_caltet_iso; //MMG_callong;
+    MMG_calte1     = MMG_calte1_iso;
+    MMG_caltet2    = MMG_caltet2_iso; //MMG_caltet2long_iso;//MMG_caltet2_iso;
+    MMG_buckin     = MMG_buckin_iso;
+    MMG_optlen     = MMG_optlen_iso;
+    MMG_interp     = MMG_interp_iso;
+    MMG_optlentet  = MMG_optlentet_iso;
+    MMG_movevertex = MMG_movevertex_iso;
+  }
+  else if ( type != 3 ) {
+    fprintf(stdout,"  ** WRONG DATA TYPE\n");
+    return(0);
+  }
+  return(1);
+}
+
+/* /\* /\\* *\/ */
+/* /\* int main(int argc,char *argv[]) { *\/ */
+/* /\*   pMesh      	mesh; *\/ */
+/* /\*   pSol       	sol; *\/ */
+/* /\*   Info     	*info; *\/ */
+/* /\*   int        	alert; *\/ */
+/* /\* int k,iadr,i,jj,kk,ii; *\/ */
+/* /\* double	lambda[3],v[3][3],*mold,*m; *\/ */
+
+/* /\*   fprintf(stdout,"  -- MMG3d, Release %s (%s) \n",M_VER,M_REL); *\/ */
+/* /\*   fprintf(stdout,"     Copyright (c) LJLL/IMB, 2010\n"); *\/ */
+/* /\*   fprintf(stdout,"    %s\n",COMPIL); *\/ */
+
+/* /\*   signal(SIGABRT,excfun); *\/ */
+/* /\*   signal(SIGFPE,excfun); *\/ */
+/* /\*   signal(SIGILL,excfun); *\/ */
+/* /\*   signal(SIGSEGV,excfun); *\/ */
+/* /\*   signal(SIGTERM,excfun); *\/ */
+/* /\*   signal(SIGINT,excfun); *\/ */
+/* /\*   atexit(endcod); *\/ */
+
+/* /\*   TIM_tminit(MMG_ctim,TIMEMAX); *\/ */
+/* /\*   TIM_chrono(ON,&MMG_ctim[0]); *\/ */
+
+/* /\*   mesh = (pMesh)M_calloc(1,sizeof(Mesh),"main"); *\/ */
+/* /\*   assert(mesh); *\/ */
+/* /\*   sol  = (pSol)M_calloc(1,sizeof(Sol),"main"); *\/ */
+/* /\*   assert(sol); *\/ */
+/* /\*   sol->offset = 1; *\/ */
+
+
+/* /\*   info = &mesh->info; *\/ */
+
+/* /\*   info->imprim   = -99; *\/ */
+/* /\*   info->memory   = -1; *\/ */
+/* /\*   info->ddebug   = 0; *\/ */
+/* /\*   info->rn2      = 3; *\/ */
+/* /\*   info->rn       = 500; *\/ */
+/* /\*   info->option   = 1; *\/ */
+/* /\*   alert          = 0; *\/ */
+/* /\*   info->bucksiz  = 0; *\/ */
+/* /\*   info->noswap   = 0; *\/ */
+/* /\*   info->nomove   = 0; *\/ */
+/* /\*   info->noinsert = 0;  *\/ */
+/* /\*   info->dt       = 1.; *\/ */
+/* /\*   info->bdry     = 0; *\/ */
+
+/* /\*   if ( !parsar(argc,argv,mesh,sol) )  return(1); *\/ */
+/* /\*   MMG_imprim = info->imprim; *\/ */
+  
+
+/* /\*   if ( MMG_imprim )   fprintf(stdout,"\n  -- INPUT DATA\n"); *\/ */
+/* /\*   TIM_chrono(ON,&MMG_ctim[1]); *\/ */
+/* /\*   if ( !MMG_loadMesh(mesh,mesh->name) )  return(1);  *\/ */
+/* /\*   if ( !MMG_loadSol(sol,sol->name,mesh->npmax) )  return(1); *\/ */
+/* /\*   if ( sol->np && sol->np != mesh->np ) { *\/ */
+/* /\*     fprintf(stdout,"  ## WARNING: WRONG SOLUTION NUMBER. IGNORED\n"); *\/ */
+/* /\*     sol->np = 0; *\/ */
+/* /\*   } *\/ */
+
+/* /\*   if ( !parsop(mesh) )  return(1); *\/ */
+
+/* /\*   if ( abs(info->option) == 9 && !MMG_loadVect(mesh,mesh->move,mesh->np) )  return(0); *\/ */
+
+/* /\*   if ( !MMG_setfunc(sol->offset) ) return(1); *\/ */
+/* /\*   if ( !MMG_scaleMesh(mesh,sol) )  return(1); *\/ */
+/* /\*   TIM_chrono(OFF,&MMG_ctim[1]); *\/ */
+/* /\*   if ( MMG_imprim ) *\/ */
+/* /\*     fprintf(stdout,"  -- DATA READING COMPLETED.     %.2f sec.\n", *\/ */
+/* /\*             TIM_gttime(MMG_ctim[1])); *\/ */
+  
+/* /\*   if ( abs(MMG_imprim) > 3 )  { *\/ */
+/* /\*     alert = MMG_outqua(mesh,sol); *\/ */
+/* /\*     if(alert) { *\/ */
+/* /\*       fprintf(stdout,"\n \n    ## INVALID MESH. STOP\n"); *\/ */
+/* /\*       exit(1);   *\/ */
+/* /\*     } *\/ */
+/* /\*     if(MMG_imprim < 0) MMG_outquacubic(mesh,sol); *\/ */
+/* /\*   } *\/ */
+
+/* /\*   fprintf(stdout,"\n  %s\n   MODULE MMG3D-LJLL/IMB : %s (%s)  %s\n  %s\n", *\/ */
+/* /\*           M_STR,M_VER,M_REL,sol->offset == 1 ? "ISO" : "ANISO",M_STR); *\/ */
+/* /\*   fprintf(stdout,"  MAXIMUM NUMBER OF POINTS    (NPMAX) : %8d\n",mesh->npmax); *\/ */
+/* /\*   fprintf(stdout,"  MAXIMUM NUMBER OF TRIANGLES (NTMAX) : %8d\n",mesh->ntmax); *\/ */
+/* /\*   fprintf(stdout,"  MAXIMUM NUMBER OF ELEMENTS  (NEMAX) : %8d\n",mesh->nemax); *\/ */
+
+
+/* /\*   TIM_chrono(ON,&MMG_ctim[2]); *\/ */
+/* /\*   if ( MMG_imprim )   fprintf(stdout,"\n  -- PHASE 1 : ANALYSIS\n"); *\/ */
+/* /\*   if ( !MMG_hashTetra(mesh) )    return(1); *\/ */
+/* /\*   if ( !MMG_markBdry(mesh) )     return(1); *\/ */
+/* /\*   if (abs(mesh->info.option)==10) { *\/ */
+/* /\*     MMG_saveMesh(mesh,"tetra.mesh"); *\/ */
+/* /\*     return(0); *\/ */
+/* /\*   }            *\/ */
+
+
+/* /\*   if ( !sol->np  &&  !MMG_doSol(mesh,sol) )  return(1); *\/ */
+/* /\*   TIM_chrono(OFF,&MMG_ctim[2]); *\/ */
+/* /\*   if ( MMG_imprim ) *\/ */
+/* /\*     fprintf(stdout,"  -- PHASE 1 COMPLETED.     %.2f sec.\n", *\/ */
+/* /\*             TIM_gttime(MMG_ctim[2])); *\/ */
+
+/* /\*   if ( info->ddebug )  MMG_chkmsh(mesh,1,1); *\/ */
+  
+/* /\*   if ( abs(MMG_imprim) > 4 )  { *\/ */
+/* /\* 	  MMG_prilen(mesh,sol); *\/ */
+/* /\*     MMG_ratio(mesh,sol,NULL);         *\/ */
+/* /\*   }                        *\/ */
+   
+/* /\* #ifdef USE_SCOTCH *\/ */
+/* /\*   /\\* renumbering begin *\\/ *\/ */
+/* /\* 	  /\\*check enough vertex to renum*\\/  *\/ */
+/* /\*    if ( (info->rn2 & 1) && (mesh->np/2. > info->rn)) {  *\/ */
+/* /\*      TIM_chrono(ON,&MMG_ctim[5]);  *\/ */
+/* /\*      if ( MMG_imprim < -6) *\/ */
+/* /\*        fprintf(stdout,"renumbering"); *\/ */
+/* /\*      renumbering(info->rn, mesh, sol);   *\/ */
+    
+/* /\*      if ( !MMG_hashTetra(mesh) )    return(1);     *\/ */
+/* /\*      TIM_chrono(OFF,&MMG_ctim[5]);  *\/ */
+/* /\*      if ( MMG_imprim < -6) *\/ */
+/* /\*        fprintf(stdout,"  -- PHASE RENUMBERING COMPLETED.     %.2f sec.\n", *\/ */
+/* /\*                TIM_gttime(MMG_ctim[5])); *\/ */
+/* /\*      if ( info->ddebug ) MMG_chkmsh(mesh,1,0); *\/ */
+/* /\*    } *\/ */
+/* /\*    /\\* renumbering end *\\/ *\/ */
+/* /\* #endif  *\/ */
+/* /\*   /\\* mesh optimization *\\/ *\/ */
+/* /\*   if ( info->option ) { *\/ */
+/* /\*     TIM_chrono(ON,&MMG_ctim[3]); *\/ */
+/* /\*     if ( MMG_imprim )   fprintf(stdout,"\n  -- PHASE 2 : UNIT MESH\n"); *\/ */
+/* /\*     if ( abs(info->option) == 9 ) { *\/ */
+/* /\*       if(!MMG_mmg3d9(mesh,sol,&alert)) { *\/ */
+/* /\*         if ( !MMG_unscaleMesh(mesh,sol) )  return(1); *\/ */
+/* /\*         MMG_saveMesh(mesh,mesh->outf); *\/ */
+/* /\* 	    MMG_saveSol(mesh,sol,mesh->outf); *\/ */
+/* /\* 	    return(1); *\/ */
+/* /\*       } *\/ */
+/* /\*       /\\*puts("appel 1"); *\/ */
+/* /\*       MMG_mmg3d1(mesh,sol,&alert);*\\/  *\/ */
+/* /\*       for (k=1; k<=mesh->np; k++) { *\/ */
+/* /\*         iadr = (k-1)*sol->offset + 1; *\/ */
+/* /\*         m    = &sol->met[iadr];       *\/ */
+/* /\*         /\\*calcul du log de M*\\/ *\/ */
+/* /\*         if ( !eigenv(1,m,lambda,v) ) { *\/ */
+/* /\*              puts("pbs eigen");  *\/ */
+/* /\*          return(0); *\/ */
+/* /\*         } *\/ */
+/* /\*         for (i=0; i<3; i++) lambda[i] = log(lambda[i]); *\/ */
+/* /\*         mold    = &sol->metold[iadr];  *\/ */
+/* /\*         kk = 0; *\/ */
+/* /\*       for (ii=0; ii<3; ii++) { *\/ */
+/* /\*            for (jj=ii; jj<3; jj++) { *\/ */
+/* /\*               mold[kk] = lambda[0]*v[0][ii]*v[0][jj] +  *\/ */
+/* /\*                          lambda[1]*v[1][ii]*v[1][jj] + *\/ */
+/* /\*                          lambda[2]*v[2][ii]*v[2][jj];  *\/ */
+/* /\*               kk = kk+1; *\/ */
+/* /\*            }                      *\/ */
+/* /\*          } *\/ */
+/* /\*       } *\/ */
+/* /\*     }  *\/ */
+    
+/* /\*     if(!info->noinsert) { *\/ */
+/* /\*       if(abs(info->option) == 4){ *\/ */
+/* /\*         MMG_mmg3d4(mesh,sol,&alert); *\/ */
+/* /\*       } else { *\/ */
+/* /\*         MMG_mmg3d1(mesh,sol,&alert); *\/ */
+/* /\*       } *\/ */
+/* /\*     } *\/ */
+      
+/* /\*     TIM_chrono(OFF,&MMG_ctim[3]); *\/ */
+/* /\*     if ( MMG_imprim ) *\/ */
+/* /\*       fprintf(stdout,"  -- PHASE 2 COMPLETED.     %.2f sec.\n", *\/ */
+/* /\*               TIM_gttime(MMG_ctim[3])); *\/ */
+/* /\*   } *\/ */
+/* /\* /////////////////////////////////////   *\/ */
+/* /\* /\\*MMG_caltet     = MMG_caltetrao; *\/ */
+/* /\* for(k=1 ; k<=mesh->ne ; k++) { *\/ */
+/* /\* 	if(!mesh->tetra[k].v[0]) continue; *\/ */
+/* /\* 	mesh->tetra[k].qual = MMG_caltet(mesh,sol,k);   *\/ */
+/* /\* } *\\/ *\/ */
+/* /\* /////////////////////////////////////   *\/ */
+/* /\*   /\\* mesh regularisation *\\/ *\/ */
+/* /\*   if ( info->option > -1 ) { *\/ */
+/* /\* #ifdef USE_SCOTCH *\/ */
+/* /\*     /\\* renumbering begin *\\/ *\/ */
+/* /\*     /\\*MMG_chkmsh(mesh,0,-1);  *\/ */
+/* /\*     puts("3er chk ok"); *\/ */
+/* /\*     *\\/ *\/ */
+/* /\*     if ( (info->rn2 & 2) && (mesh->np/2. > info->rn))  {  *\/ */
+/* /\*       TIM_chrono(ON,&MMG_ctim[6]);  *\/ */
+/* /\*       if ( MMG_imprim < -6) *\/ */
+/* /\*         fprintf(stdout,"renumbering");  *\/ */
+/* /\* 			renumbering(info->rn, mesh, sol); *\/ */
+/* /\*       if ( !MMG_hashTetra(mesh) )    return(1);     *\/ */
+/* /\*       TIM_chrono(OFF,&MMG_ctim[6]);  *\/ */
+/* /\*       if ( MMG_imprim < -6) *\/ */
+/* /\*         fprintf(stdout,"  -- PHASE RENUMBERING COMPLETED.     %.2f sec.\n", *\/ */
+/* /\*               TIM_gttime(MMG_ctim[6])); *\/ */
+/* /\*       if ( info->ddebug ) MMG_chkmsh(mesh,1,0); *\/ */
+/* /\*     }  *\/ */
+/* /\*     /\\* renumbering end *\\/    *\/ */
+/* /\* #endif *\/ */
+/* /\*     TIM_chrono(ON,&MMG_ctim[4]); *\/ */
+/* /\*     if ( MMG_imprim )  fprintf(stdout,"\n  -- PHASE 3 : OPTIMIZATION\n"); *\/ */
+/* /\*     if ( !alert )  { *\/ */
+/* /\*       if ( info->option == 9 ) {  *\/ */
+/* /\*          MMG_optra4(mesh,sol);  *\/ */
+/* /\*       } else { *\/ */
+/* /\*          MMG_optra4(mesh,sol);  *\/ */
+/* /\*       } *\/ */
+/* /\*     } *\/ */
+    
+/* /\*     if ( info->ddebug )  MMG_chkmsh(mesh,1,1); *\/ */
+/* /\*     TIM_chrono(OFF,&MMG_ctim[4]); *\/ */
+/* /\*     if ( MMG_imprim ) *\/ */
+/* /\*       fprintf(stdout,"  -- PHASE 3 COMPLETED.     %.2f sec.\n", *\/ */
+/* /\*               TIM_gttime(MMG_ctim[4])); *\/ */
+/* /\*   } *\/ */
+/* /\* /////////////////////////////////////   *\/ */
+/* /\* /\\*MMG_caltet     = MMG_caltet_iso; *\/ */
+/* /\* for(k=1 ; k<=mesh->ne ; k++) { *\/ */
+/* /\* 	mesh->tetra[k].qual = MMG_caltet(mesh,sol,k);   *\/ */
+/* /\* } *\\/ *\/ */
+/* /\* /////////////////////////////////////   *\/ */
+
+/* /\*   if ( info->option > -1 || abs(MMG_imprim) > 3 ) { *\/ */
+/* /\*     MMG_outqua(mesh,sol); *\/ */
+/* /\*     if(MMG_imprim < 0) MMG_outquacubic(mesh,sol); *\/ */
+/* /\*     MMG_prilen(mesh,sol); *\/ */
+/* /\*     MMG_ratio(mesh,sol,NULL); *\/ */
+/* /\*   } *\/ */
+/* /\*   fprintf(stdout,"\n  %s\n   END OF MODULE MMG3D \n  %s\n",M_STR,M_STR); *\/ */
+/* /\*   if ( alert ) *\/ */
+/* /\*     fprintf(stdout,"\n  ## WARNING: INCOMPLETE MESH  %d , %d\n", *\/ */
+/* /\*             mesh->np,mesh->ne); *\/ */
+
+/* /\*   if ( MMG_imprim )  fprintf(stdout,"\n  -- WRITING DATA FILE %s\n",mesh->outf); *\/ */
+/* /\*   TIM_chrono(ON,&MMG_ctim[1]); *\/ */
+/* /\*   if ( !MMG_unscaleMesh(mesh,sol) )  return(1); *\/ */
+/* /\*   MMG_saveMesh(mesh,mesh->outf); *\/ */
+/* /\*   if ( info->option == 9 ) { *\/ */
+/* /\*     MMG_saveSol(mesh,sol,mesh->outf); *\/ */
+/* /\*     MMG_saveVect(mesh,mesh->move);     *\/ */
+/* /\*   } *\/ */
+/* /\*   else *\/ */
+/* /\*     MMG_saveSol(mesh,sol,mesh->outf); *\/ */
+/* /\*   TIM_chrono(OFF,&MMG_ctim[1]); *\/ */
+/* /\*   if ( MMG_imprim )  fprintf(stdout,"  -- WRITING COMPLETED\n"); *\/ */
+
+/* /\*   /\\* free mem *\\/ *\/ */
+/* /\*   M_free(mesh->point); *\/ */
+/* /\*   M_free(mesh->tria); *\/ */
+/* /\*   M_free(mesh->tetra); *\/ */
+/* /\*   /\\*la desallocation de ce pointeur plante dans certains cas...*\\/ *\/ */
+/* /\*   M_free(mesh->adja); *\/ */
+/* /\*   M_free(mesh->disp->alpha); *\/ */
+/* /\*   M_free(mesh->disp->mv); *\/ */
+/* /\*   M_free(mesh->disp); *\/ */
+
+/* /\*   if ( sol->npfixe )  M_free(sol->met); *\/ */
+/* /\*   M_free(sol); *\/ */
+
+/* /\*   if ( MMG_imprim < -4 || info->ddebug )  M_memDump(); *\/ */
+/* /\*   M_free(mesh); *\/ */
+/* /\*   return(0); *\/ */
+/* /\* } *\/ */
diff --git a/contrib/mmg3d/build/sources/mmg3d1.c b/contrib/mmg3d/build/sources/mmg3d1.c
new file mode 100644
index 0000000000000000000000000000000000000000..a71424f863a933c2d0d90286a82d6418b31e0b35
--- /dev/null
+++ b/contrib/mmg3d/build/sources/mmg3d1.c
@@ -0,0 +1,192 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+extern TIM_mytime         MMG_ctim[TIMEMAX];
+
+int MMG_npdtot,MMG_npuisstot,MMG_nvoltot,MMG_nprestot;
+int MMG_npuiss,MMG_nvol,MMG_npres,MMG_npd;
+
+int MMG_cendellong(pMesh mesh,pSol sol,double declic,int base);
+
+int MMG_mmg3d1(pMesh mesh,pSol sol,int *alert) {
+  pBucket	bucket;
+  int		base,na,nd,nf,nna,nnd,dd,it,maxtou;
+  int   naold,ndold;
+//double q,declicw;
+//pTetra pt;      
+//int  nw;
+
+  if ( abs(mesh->info.imprim) > 3 )
+    fprintf(stdout,"  ** SIZE OPTIMIZATION\n");
+  if ( mesh->info.imprim < 0 ) {
+    MMG_outqua(mesh,sol);
+    MMG_prilen(mesh,sol);
+  }
+
+  base   = mesh->flag;
+  *alert = 0;
+
+  nna = 0;
+  nnd = 0;
+  nf  = 0;
+  it  = 0;
+  maxtou = 100;
+MMG_npdtot=0;
+MMG_npuisstot=0;
+MMG_nprestot=0;
+MMG_nvoltot=0;
+
+  /* 2. field points */
+  if ( mesh->info.imprim < -4 ) {
+    MMG_prilen(mesh,sol);
+    fprintf(stdout,"  -- FIELD POINTS\n");
+  }
+  /* create filter */
+  bucket = MMG_newBucket(mesh,M_MAX(mesh->info.bucksiz,BUCKSIZ));
+  if ( !bucket )  return(0);
+  
+  naold = ndold = 0;
+  do {
+    base = mesh->flag;
+    nf   = 0;
+        
+    MMG_analar(mesh,sol,bucket,&na,&nd,&nf,alert);    
+    nna += na;
+    nnd += nd;
+
+    if ( *alert ) {
+      if ( nd < 1000 )  break;
+      else  *alert = 0;
+    }
+    
+    /*test avec comme critere de qualite les longueurs*/
+    /*if( it < 7 && !(it%3) ) {
+      ns = 0; 
+      declic = 120.; //attention c'est 60*len  
+      if ( !*alert && !mesh->info.noswap ) {
+          declicw = 180.;  
+          nw += MMG_opttyp(mesh,sol,declicw,&alert);
+          ns = MMG_cendellong(mesh,sol,declic,-1);
+        if ( ns < 0 ) {
+          *alert = 1;
+      	  ns    = -ns;
+        }
+      }
+      if ( mesh->info.imprim && ns )
+        fprintf(stdout,"     %8d SWAPPED\n",ns);    
+      //puts("on arrete la");exit(0); 
+    }
+    
+    if( it > 5 ) {
+      
+      
+      //printf("on traite moins 1%% : %d %d %e\n",na,nd,(na+nd)/(double)mesh->np); 
+      //printf("delold/ins %e %e\n",ndold / (double) (na+1),naold / (double) (nd+1));
+      
+      if( it > 10 ) {
+        q = ndold / (double) (na+1);
+        if( q < 1.7 && q > 0.57) {
+          break;
+        }
+        q = naold / (double) (nd+1);
+        if( q < 1.7 && q > 0.57) {
+          break;
+        }        
+      }
+      q = ndold / (double) (na+1);
+      if( q < 1.1 && q > 0.9) {
+        break;
+      }
+      q = naold / (double) (nd+1);
+      if( q < 1.1 && q > 0.9) {
+        break;
+      }
+    }
+    naold = na;
+    ndold = nd;
+    */
+    
+    if ( it > 5 ) {
+      dd = abs(nd-na);
+      if ( dd < 5 || dd < 0.05*nd )   break;
+      else if ( it > 12 && nd >= na )  break;
+    }
+    if ( na + nd > 0 && abs(mesh->info.imprim) > 2 )
+      fprintf(stdout,"     %8d INSERTED   %8d REMOVED   %8d FILTERED\n",
+              na,nd,nf);
+    }
+    while ( na+nd > 0 && ++it < maxtou );
+
+
+  if ( nna+nnd && abs(mesh->info.imprim) < 3 ) {
+    fprintf(stdout,"     %7d INSERTED  %7d REMOVED  %7d FILTERED\n",nna,nnd,nf);
+  }
+
+if(MMG_npdtot>0) { 
+fprintf(stdout,"    REJECTED : %5d\n",MMG_npdtot);
+fprintf(stdout,"          VOL      : %6.2f %%    %5d \n",
+	100*(MMG_nvoltot/(float)
+MMG_npdtot),MMG_nvoltot); 
+fprintf(stdout,"          PUISS    : %6.2f %%    %5d \n",
+	100*(MMG_npuisstot/(float) MMG_npdtot),MMG_npuisstot);
+fprintf(stdout,"         PROCHE    : %6.2f %%    %5d \n",
+	100*(MMG_nprestot/(float) MMG_npuisstot),MMG_nprestot);	
+MMG_npdtot=0;
+MMG_npuisstot=0;
+MMG_nvoltot=0;  
+} 
+  if ( mesh->info.imprim < 0 ) {
+    MMG_outqua(mesh,sol);
+    MMG_prilen(mesh,sol);
+  }
+
+  M_free(bucket->head);
+  M_free(bucket->link);
+  M_free(bucket);
+
+  return(1);
+}
diff --git a/contrib/mmg3d/build/sources/mmg3d4.c b/contrib/mmg3d/build/sources/mmg3d4.c
new file mode 100644
index 0000000000000000000000000000000000000000..67791e2f88826b25f4c6590779fa3af444e766dc
--- /dev/null
+++ b/contrib/mmg3d/build/sources/mmg3d4.c
@@ -0,0 +1,237 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+int MMG_npuiss,MMG_nvol,MMG_npres;
+int MMG_nlen,MMG_ncal,MMG_ntopo,MMG_nex;
+int MMG_npuisstot,MMG_nvoltot,MMG_nprestot;
+int MMG_npdtot;
+int MMG_nplen,MMG_npref,MMG_bouffe;
+
+int ddebug;
+
+int MMG_mmg3d4(pMesh mesh,pSol sol,int *alert) {
+  Hedge    hash;
+  pBucket	 bucket; 
+  double   declic;
+  int		   base,na,nd,ns,nna,nnd,nns,dd,it,nf,maxtou; 
+  double   lmoy,LLLONG;
+  if ( abs(mesh->info.imprim) > 3 )
+    fprintf(stdout,"  ** SIZE OPTIMIZATION\n");
+  if ( mesh->info.imprim < 0 ) {
+    MMG_outqua(mesh,sol);
+    MMG_prilen(mesh,sol);
+  }
+
+  base   = mesh->flag;
+  *alert = 0;
+  maxtou = 10;
+  nna = nns = nnd = 0;
+  it  = 0;
+  declic = 3. / ALPHAD;  
+  lmoy = 10.;
+  LLLONG = 1.5;
+  
+  nna = 10;
+  do { 
+    na  = nd  = ns  = 0; 
+    if(0) ddebug = 1;
+    else ddebug = 0;
+    
+    if(!(it%2) ) {
+      bucket = MMG_newBucket(mesh,M_MAX(mesh->info.bucksiz,BUCKSIZ));
+      if ( !bucket )  return(0);
+      
+      MMG_analar(mesh,sol,bucket,&na,&nd,&nf,alert);      
+      if ( abs(mesh->info.imprim) > 5 ) 
+        fprintf(stdout,"     %7d INSERTED  %7d REMOVED   %7d FILTERED\n",na,nd,nf);  
+
+	    M_free(bucket->head);
+	    M_free(bucket->link);
+	    M_free(bucket);
+        
+    } else {
+        ++mesh->flag;
+    }
+    //printf("IT %d $$$$$$$$$$$ LLLONG  %9.3f\n",it,LLLONG); 
+    nna = nns = nnd = 0; 
+      
+    /*splitting*/
+    if ( !mesh->info.noinsert && (!*alert)  ) {
+      /* store points on edges */
+      if ( !MMG_zaldy4(&hash,mesh->np) ) {
+        if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM.\n"); 
+        *alert = 2;
+        break;
+      }
+          
+      nna = MMG_analarcutting(mesh,sol,&hash,alert,&lmoy,LLLONG); 
+      if ( abs(mesh->info.imprim) > 5 ) { printf("lmoy %9.5f\n",lmoy); }
+      /*puts("--------------------------------------");
+      puts("--------------------------------------");
+      puts("--------------------------------------");
+      */
+      if ( *alert ) {
+        fprintf(stdout," \n\n ** UNABLE TO CUT (analarcutting)\n");
+        fprintf(stdout," ** RETRY WITH -m > %6d \n\n",mesh->info.memory);
+        MMG_saveMesh(mesh,"crash.meshb");
+        MMG_saveSol(mesh,sol,"crash.solb"); 
+        exit(0);
+      }
+      M_free(hash.item);        
+    }
+    else if ( *alert )  nna = 0;  
+    /* adjacencies */ 
+    if ( nna /*|| it == (maxtou-1)*/ ) {
+      mesh->nt = 0;
+      if ( !MMG_hashTetra(mesh) )  return(0);
+      if ( !MMG_markBdry(mesh) )   return(0);
+    }
+    // printf("chkmsh\n");
+    // MMG_saveMesh(mesh,"chk.mesh");
+    //MMG_chkmsh(mesh,1,-1);
+		//if(it==1)exit(0);		
+     /* delaunization */
+    if ( !mesh->info.noswap && (nna || na) ) {  
+      nns   =  MMG_cendel(mesh,sol,declic,base);
+    }
+
+    /* deletion */
+    /*if ( 0 && nna ) {
+      nnd   = MMG_colvert(mesh,sol,base);
+    } */
+    if ( nna+nnd+nns && abs(mesh->info.imprim) > 3 )
+      fprintf(stdout,"     %7d INSERTED  %7d REMOVED   %7d FLIPPED\n",nna+na,nnd+nd,nns);
+    
+  }
+  while ( na+nd+nns+nna+nnd > 0 && ++it < maxtou && lmoy > 1.3);
+
+  if ( nna+nnd+nns && abs(mesh->info.imprim) < 4 ) {
+    fprintf(stdout,"     %7d INSERTED  %7d REMOVED %7d FLIPPED\n",nna,nnd,nns);
+  }
+
+  if ( mesh->info.imprim < 0 ) {
+    MMG_outqua(mesh,sol);
+    MMG_prilen(mesh,sol);
+  }
+
+	//return(1);
+	//MMG_saveMesh(mesh,"aprescut.mesh");
+	fprintf(stdout,"    ---\n");
+  
+  /*analyze standard*/
+    base   = mesh->flag;
+    *alert = 0;
+
+    nna = 0;
+    nnd = 0;
+    nf  = 0;
+    it  = 0;
+    maxtou = 100;
+    MMG_npdtot=0;
+    MMG_npuisstot=0;
+    MMG_nprestot=0;
+    MMG_nvoltot=0;
+
+    /* 2. field points */
+    if ( mesh->info.imprim < -4 ) {
+      MMG_prilen(mesh,sol);
+      fprintf(stdout,"  -- FIELD POINTS\n");
+    }
+
+    /* create filter */
+    bucket = MMG_newBucket(mesh,M_MAX(mesh->info.bucksiz,BUCKSIZ));
+    if ( !bucket )  return(0);
+
+    do {
+      MMG_analar(mesh,sol,bucket,&na,&nd,&nf,alert);    
+      nna += na;
+      nnd += nd;
+      if ( *alert ) {
+        if ( nd < 1000 )  break;
+        else  *alert = 0;
+      }
+      if ( it > 5 ) {
+        dd = abs(nd-na);
+        if ( dd < 5 || dd < 0.05*nd )   break;
+        else if ( it > 12 && nd >= na )  break;
+      }
+      if ( na+nd && abs(mesh->info.imprim) > 3 )
+        fprintf(stdout,"     %7d INSERTED  %7d REMOVED   %7d FILTERED\n",na,nd,nf);    
+			// MMG_saveMesh(mesh,"chk.mesh");
+			// //if(it==1) exit(0);
+    }
+    while ( na+nd > 0 && ++it < maxtou );
+
+    if ( nna+nnd && abs(mesh->info.imprim) < 3 ) {
+      fprintf(stdout,"     %7d INSERTED  %7d REMOVED  %7d FILTERED\n",na,nd,nf);
+    }
+
+  if(MMG_npdtot>0) { 
+  fprintf(stdout,"    REJECTED : %5d\n",MMG_npdtot);
+  fprintf(stdout,"          VOL      : %6.2f %%    %5d \n",
+  	100*(MMG_nvoltot/(float)
+  MMG_npdtot),MMG_nvoltot); 
+  fprintf(stdout,"          PUISS    : %6.2f %%    %5d \n",
+  	100*(MMG_npuisstot/(float) MMG_npdtot),MMG_npuisstot);
+  fprintf(stdout,"         PROCHE    : %6.2f %%    %5d \n",
+  	100*(MMG_nprestot/(float) MMG_npuisstot),MMG_nprestot);	
+  MMG_npdtot=0;
+  MMG_npuisstot=0;
+  MMG_nvoltot=0;  
+  } 
+    if ( mesh->info.imprim < 0 ) {
+      MMG_outqua(mesh,sol);
+      MMG_prilen(mesh,sol);
+    }
+
+    M_free(bucket->head);
+    M_free(bucket->link);
+    M_free(bucket);
+  
+
+  return(1);
+}
diff --git a/contrib/mmg3d/build/sources/mmg3d9.c b/contrib/mmg3d/build/sources/mmg3d9.c
new file mode 100644
index 0000000000000000000000000000000000000000..e691727bf57f9e53e7920437e7fdfd79d12fe6f2
--- /dev/null
+++ b/contrib/mmg3d/build/sources/mmg3d9.c
@@ -0,0 +1,528 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+extern int MMG_nlen,MMG_ncal,MMG_ntopo,MMG_nex;
+
+/*essaie d'enlever les tets ayant plus d'une face de peau pour faciliter le bouger*/
+int MMG_optfacespeau(pMesh mesh,pSol sol) {
+  double  	declic;
+  pTetra	pt;
+  pQueue    queue;
+  int      	it,maxtou,i,iadr,*adja,npeau,nwtot,nw,k;
+  
+  declic = 1.7 / ALPHAD;
+  maxtou = 10;
+  it     = 0;
+
+  do {
+    queue = MMG_kiuini(mesh,mesh->nemax,declic,-1);
+    assert(queue);
+    nw    = 0;
+    nwtot = 0;
+    do {
+      k = MMG_kiupop(queue);
+      pt = &mesh->tetra[k];
+      if ( !k )  break;
+      if ( !pt->v[0] )  continue;
+      iadr = 4*(k-1) + 1;
+      adja = &mesh->adja[iadr];
+      /*optim bdry tetra*/
+      npeau = 0;
+      for(i=0 ; i<4 ; i++) {
+        if(!adja[i])npeau++;	 
+      }
+      if(npeau>1 ) {
+        nwtot++;
+        //if(mesh->info.imprim<0) printf("%d faces de peau!!!! %d %e\n",npeau,k,mesh->tetra[k].qual * ALPHAD);
+	    nw += MMG_opt2peau(mesh,sol,queue,k,declic);
+        continue;
+      }    
+    } 
+    while (k);
+    fprintf(stdout,"      %7d / %7d BDRY TETS\n",nw,nwtot);
+    MMG_kiufree(queue);
+  }
+  while ( nw && ++it < maxtou );
+ 
+ return(1);
+}
+
+/*collapse*/
+int MMG_colps(pMesh mesh,pSol sol,int *nd) {
+  pTetra    pt,pt1;
+  pPoint    pa,pb;
+  double    len,*ca,*cb,*ma,*mb;
+  float     coef;
+  int       i,k,l,jel,num,lon,ndd,npp,ia,ib,ipa,ipb,nedep,base;
+  int      *adja,adj,iadr;
+  List      list;
+  char      tabar;
+
+MMG_nlen = 0;
+MMG_ncal = 0;
+MMG_ntopo = 0;
+MMG_nex = 0;
+
+  npp = 0;
+  ndd = 0;
+  coef  = QDEGRAD;
+  nedep = mesh->ne;
+  base  = ++mesh->flag;
+  /*Try collapse*/
+  for (k=1; k<=nedep; k++) {
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+    else if ( pt->flag != base-1 )  continue;
+
+    /* mark internal edges */
+    tabar = 0;
+    iadr  = 4*(k-1) + 1;
+    adja  = &mesh->adja[iadr];
+    for (i=0; i<4; i++) {
+      adj = adja[i] >> 2;
+      if ( !adj || pt->ref != mesh->tetra[adj].ref ) {
+  	tabar |= 1 << MMG_iarf[i][0];
+  	tabar |= 1 << MMG_iarf[i][1];
+  	tabar |= 1 << MMG_iarf[i][2];
+     }
+    }
+    if ( tabar == ALL_BDRY )  continue;
+
+    /* internal edge */
+    for (i=0; i<6; i++) {
+      if ( tabar & 1<<i )  continue;
+      else if ( pt->edge & 1 << i )  continue;
+
+      /* edge length */
+      ia  = MMG_iare[i][0];
+      ib  = MMG_iare[i][1];
+      ipa = pt->v[ia];
+      ipb = pt->v[ib];
+      pa  = &mesh->point[ipa];
+      pb  = &mesh->point[ipb];
+      ca  = &pa->c[0];
+      cb  = &pb->c[0];
+      iadr = (ipa-1)*sol->offset + 1;
+      ma  = &sol->met[iadr];
+
+      iadr = (ipb-1)*sol->offset + 1;
+      mb  = &sol->met[iadr];
+      
+      /* coquille */
+      lon = MMG_coquil(mesh,k,i,&list);
+      for (l=1; l<=lon; l++) {
+  	    jel = list.tetra[l] / 6;
+  	    num = list.tetra[l] % 6;
+  	    pt1 = &mesh->tetra[jel];
+  	    pt1->edge |= 1 << num;
+      }
+      if ( lon < 3 )  continue;
+      len = MMG_length(ca,cb,ma,mb);
+  
+      if ( len < LSHORT ) {
+  	    npp++;
+  	    pa = &mesh->point[ipa];
+  	    pb = &mesh->point[ipb];
+  	    if ( MMG_colpoi(mesh,sol,k,ia,ib,coef) ) {
+  	      MMG_delPt(mesh,ipb);
+  	      ndd++;
+  	      break;
+  	    }
+  	    else if ( MMG_colpoi(mesh,sol,k,ib,ia,coef) ) {
+  	      MMG_delPt(mesh,ipa);
+  	      ndd++;
+  	      break;
+  	    }
+      }
+    }
+  }
+
+        *nd = ndd;
+printf("analyzed %d \n",npp);
+printf("rejected colpoi : cal %d  , len %d , topo %d , ex %d\n",MMG_ncal,MMG_nlen,MMG_ntopo,MMG_nex);
+
+  if ( *nd > 0 && abs(mesh->info.imprim) > 2 )
+    fprintf(stdout,"	%8d REMOVED  \n",*nd);
+
+  return(1);
+
+}
+
+
+/* dichotomy: check if nodes can move */
+int MMG_dikomv(pMesh mesh,pSol sol,short t) {
+  pTetra    pt;
+  pPoint    ppt;
+  pDispl    pd;
+  double    vol,c[4][3];
+  double    alpha,coor[3];
+  int       k,i,nm;
+/*double hmax,*mp,h1,lambda[3],dd;  
+int iadr;  
+Info     *info;
+*/
+  pd = mesh->disp;
+
+  alpha = (double)t / SHORT_MAX;
+  for (k=1; k<=mesh->ne; k++) {
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+    for (i=0; i<4; i++) {
+      ppt      = &mesh->point[ pt->v[i] ];
+      ppt->tmp = k;
+      if ( ppt->tag & M_MOVE ) {
+        c[i][0] = ppt->c[0] + alpha * pd->mv[3*(pt->v[i]-1) + 1 + 0];
+        c[i][1] = ppt->c[1] + alpha * pd->mv[3*(pt->v[i]-1) + 1 + 1];
+        c[i][2] = ppt->c[2] + alpha * pd->mv[3*(pt->v[i]-1) + 1 + 2];
+      }
+      else
+        memcpy(c[i],ppt->c,3*sizeof(double));
+    }
+
+    vol = MMG_quickvol(c[0],c[1],c[2],c[3]);
+    if ( vol < 1e-24/*EPS2*/ )  {
+      if(mesh->info.imprim < 0) printf("vol reject %d %e %e\n",k,vol,pt->qual * ALPHAD);
+      return(0);
+    }
+  }
+  /* update metrics */
+  for (k=1; k<=mesh->np; k++) {
+    ppt = &mesh->point[k];
+    if(ppt->tag & M_UNUSED) continue;
+//#warning a mettre ou pas?    
+    if(ppt->tag & M_BDRY) continue;
+    if ( ppt->tag & M_MOVE ) {
+      coor[0] = ppt->c[0] + alpha * pd->mv[3*(k-1) + 1 + 0];
+      coor[1] = ppt->c[1] + alpha * pd->mv[3*(k-1) + 1 + 1];
+      coor[2] = ppt->c[2] + alpha * pd->mv[3*(k-1) + 1 + 2];
+if(MMG_computeMetric(mesh,sol,k,coor) == -1) ;//printf("point %d not found\n",k);
+// /*pour mettre une metrique analytique*/
+//       iadr = (k-1)*sol->offset + 1;
+//       mp   = &sol->met[iadr];
+//             
+//       info = &mesh->info;
+// 
+//     /* normalize metrics */
+//     dd = (double)PRECI / info->delta;
+// 
+//       hmax = 0.5;
+//       h1 = hmax * fabs(1-exp(-fabs((coor[2] * 1./dd + info->min[2])+4))) + 0.008;
+//       lambda[2]=1./(h1*h1);
+//       lambda[1]=1./(hmax*hmax);
+//       lambda[0]=1./(hmax*hmax);
+//      dd = 1.0 / (dd*dd);
+// 
+//       mp[0]=dd*lambda[0];
+//       mp[1]=0;
+//       mp[3]=dd*lambda[1];
+//       mp[2]=0;
+//       mp[4]=0;
+//       mp[5]=dd*lambda[2];
+// /*fin metrique analytique*/      
+   }
+  }
+
+  /* update point coords */
+  nm = 0;
+  for (k=1; k<=mesh->np; k++) {
+    ppt = &mesh->point[k];
+    if ( ppt->tag & M_MOVE ) {
+      ppt->c[0] += alpha * pd->mv[3*(k-1) + 1 + 0];
+      ppt->c[1] += alpha * pd->mv[3*(k-1) + 1 + 1];
+      ppt->c[2] += alpha * pd->mv[3*(k-1) + 1 + 2];
+      pd->alpha[k]  = t;
+      if ( t == SHORT_MAX )  ppt->tag &= ~M_MOVE;
+      nm++;
+    }
+  }
+
+  if ( mesh->info.imprim < 0 )  fprintf(stdout,"     %7d NODES UPDATED\n",nm);
+  return(nm);
+}
+
+
+/* check if displacement ok */
+int MMG_chkmov(pMesh mesh,char level) {
+  pTetra     pt;
+  pPoint     ppt;
+  pDispl     pd;
+  double     vol;
+  int        k,nc;
+
+  pd  = mesh->disp;
+
+  nc = 0;
+  for (k=1; k<=mesh->np; k++) {
+    ppt = &mesh->point[k];
+    if ( ppt->tag & M_MOVE ) {
+      if ( pd->alpha[k] < SHORT_MAX )  return(0);
+      ppt->tag &= ~M_MOVE;
+      nc++;
+    }
+  }
+
+  /* check element validity */
+  if ( level > 0 ) {
+    for (k=1 ; k<=mesh->ne; k++) {
+      pt = &mesh->tetra[k];
+      if ( !pt->v[0] )  continue;
+      vol = MMG_voltet(mesh,k);
+      if ( vol < 0.0 )  return(0);
+    }
+  }
+
+  return(1);
+}
+
+int MMG_optra9(pMesh mesh,pSol sol) {
+  double	declicw;
+  double	declic;
+  int		base,nm,ns,it,maxtou,alert,nw,k;
+  
+  /* optim coquil */
+  alert  = 0;
+  maxtou = 10;
+  it     = 0;
+    
+  for (k=1; k<=mesh->ne; k++) mesh->tetra[k].flag = mesh->flag;
+  for (k=1; k<=mesh->np; k++) mesh->point[k].flag = mesh->flag;
+ 
+  declicw = 5./ALPHAD;
+  declic  = 1.1 / ALPHAD;//1.1 pour mmg3d
+
+  do {
+    for (k=1; k<=mesh->ne; k++) mesh->tetra[k].flag = mesh->flag;
+    for (k=1; k<=mesh->np; k++) mesh->point[k].flag = mesh->flag;
+    base = ++mesh->flag;
+    
+    ns = 0;
+    if ( !alert && !mesh->info.noswap ) {
+      ns = MMG_cendel(mesh,sol,declic,base);
+      if ( ns < 0 ) {
+        alert = 1;
+    	ns    = -ns;
+      }
+    }
+    nw = 0;
+    /*if (!mesh->info.noinsert)  nw = MMG_pretreat(mesh,sol,declicw,&alert);
+    */
+    /*sur des surfaces courbes, il existe des tetras ayant  4 points de peau avec Q=3*/  
+    if (1/*!mesh->info.noswap*/ /*&& (it < 10)*/ )  {
+	  nw += MMG_opttyp(mesh,sol,declicw,&alert);   
+    }
+
+    nm = MMG_optlen(mesh,sol,declic,base);  
+//    if(abs(mesh->info.option)!=9 || !mesh->disp) if(it<2) MMG_optlap(mesh,sol);
+    
+    if ( mesh->info.imprim && nw+ns+nm )
+      fprintf(stdout,"     %8d IMPROVED  %8d SWAPPED  %8d MOVED\n",nw,ns,nm);
+  }
+  while ( ns+nm/*(ns && (ns > 0.005*mesh->ne || it < 5))*/ && ++it < maxtou );
+ 
+  return(1);
+}
+
+
+int MMG_mmg3d9(pMesh mesh,pSol sol,int *alert) {   
+  pPoint    ppt;
+  pTetra   pt;
+  double   declic;
+  double    *m,*mold,qworst;
+  int      k,nm,iter,maxiter;
+  int      base,nnd,nns,sit,maxtou,ns,iadr,iold;
+  short    t,i,it,alpha;
+  
+  if ( abs(mesh->info.imprim) > 3 )
+    fprintf(stdout,"  ** MOVING MESH\n");
+  
+  /*alloc et init metold*/
+  sol->metold = (double*)M_calloc(sol->npmax+1,sol->offset*sizeof(double),"MMG_mmg3d9");
+  assert(sol->metold);
+  mesh->disp->cold = (double*)M_calloc(3*(mesh->npmax + 1),sizeof(double),"MMG_mmg3d9");
+  assert(mesh->disp->cold);
+  for (k=1; k<=mesh->np; k++) {
+     ppt = &mesh->point[k];
+	 if ( ppt->tag & M_UNUSED ) continue;
+     mesh->disp->cold[3*(k-1) + 1 + 0] = ppt->c[0];
+     mesh->disp->cold[3*(k-1) + 1 + 1] = ppt->c[1];
+     mesh->disp->cold[3*(k-1) + 1 + 2] = ppt->c[2];
+   }
+  
+  switch (sol->offset) {
+  case 1:
+    for (k=1; k<=sol->np; k++)  {
+      sol->metold[k] = sol->met[k];
+    }
+    break;
+
+  case 6:
+    for (k=1; k<=mesh->np; k++) {
+      iadr = (k-1)*sol->offset + 1;
+      m    = &sol->met[iadr];
+      mold = &sol->metold[iadr];
+      for (i=0; i<sol->offset; i++)  mold[i] = m[i];
+    }
+    break;
+  default:
+    fprintf(stderr,"  ## SPECIFIC DATA NOT USED.\n");
+    exit(2);
+  }
+
+  
+  /* move grid nodes */
+  t       = SHORT_MAX;
+  alpha   = 0;
+  iter    = 0;
+  maxiter = 200;
+  declic  = 1.1/ALPHAD;
+  iold    = 1;
+  
+  /* move grid nodes */
+  t = SHORT_MAX;
+  if (  MMG_dikomv(mesh,sol,t) ) {
+    if ( mesh->info.imprim )  fprintf(stdout,"     %7d NODES MOVED\n",mesh->np);
+  }
+  else {
+    fprintf(stdout,"     TRYING DICHO\n");
+    while (alpha < SHORT_MAX && iter < maxiter) {
+      t = SHORT_MAX - alpha;
+      i = 0;
+      do {
+        nm = MMG_dikomv(mesh,sol,t);
+        if ( nm )  {
+	      alpha += t;
+	      break;
+	    } 
+	    t = t >> 1;     
+      } while (i++ < 10);
+  
+      /*si pas de mouvement 2 iter de suite stop*/
+      if ( (i==11) && (iold==11)) {
+        fprintf(stdout,"  NO MOVEMENT ## UNCOMPLETE DISPLACEMENT\n");
+        return(0);
+       }
+       iold = i;
+       /* update quality */
+	   qworst = 0.;
+       for (k=1; k<=mesh->ne; k++) {
+         pt = &mesh->tetra[k];
+		 if ( !pt->v[0] ) continue;
+         pt->qual = MMG_caltet(mesh,sol,k);
+		 qworst = M_MAX(qworst,pt->qual);
+       }
+      
+     
+      if ( mesh->info.imprim && nm )
+        fprintf(stdout,"     %7d NODES MOVED\n",nm);
+
+      printf("%%%% ITER %d alpha (%d) %d < %d\n",iter,i,alpha,SHORT_MAX);
+            
+      if ( i>1 ) {
+        fprintf(stdout,"     CAN'T MOVED\n");
+        if(!mesh->info.noswap) MMG_optfacespeau(mesh,sol);
+        nnd = 0;
+        nns = 0;
+        sit = 0;
+        maxtou = 10;
+        do {
+          it   = 0;
+          base = mesh->flag;
+		  ns   = 0;//MMG_cendel(mesh,sol,declic,base);
+          if(!mesh->info.noswap) MMG_optfacespeau(mesh,sol);
+          if ( ns < 0 ) {
+            *alert = 1;
+            ns     = -ns;
+          }
+          nns += ns;
+          if ( ns && abs(mesh->info.imprim) > 4 )
+            fprintf(stdout,"      %7d SWAPPED\n",ns);
+        }
+        while ( ns && ++sit < maxtou );
+
+        if ( nnd+nns && abs(mesh->info.imprim) < 3 ) {
+          fprintf(stdout,"     %7d REMOVED  %7d SWAPPED\n",nnd,nns);
+        }
+      }
+      
+      if ( qworst < 10./ALPHAD ) { 
+        MMG_optra4(mesh,sol);
+      } else {
+		MMG_optra9(mesh,sol);
+      }
+      if(!mesh->info.noswap) MMG_optfacespeau(mesh,sol);
+      MMG_outqua(mesh,sol);
+      iter++;
+
+    }
+
+    /* check mesh */
+    if ( iter==maxiter && !MMG_chkmov(mesh,1) ) {
+      fprintf(stdout,"  ## UNCOMPLETE DISPLACEMENT\n");
+      return(0);
+    }
+  }
+  
+  if(!mesh->info.noswap) MMG_optfacespeau(mesh,sol);
+
+  /* update quality */
+  for (k=1; k<=mesh->ne; k++) {
+    pt = &mesh->tetra[k];
+    if ( pt->v[0] )
+      pt->qual = MMG_caltet(mesh,sol,k);
+  }
+
+  if ( mesh->info.imprim < 0 ) {
+    MMG_outqua(mesh,sol);
+    MMG_prilen(mesh,sol);
+  }
+  
+ // M_free(sol->metold);
+/*  M_free(mesh->disp);
+  mesh->disp = 0;
+  */return(1);
+}
+
diff --git a/contrib/mmg3d/build/sources/mmg3dConfig.h b/contrib/mmg3d/build/sources/mmg3dConfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..6fc584d764994ca3d96393facbd7e6adbff67be8
--- /dev/null
+++ b/contrib/mmg3d/build/sources/mmg3dConfig.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+// the configured options and settings for Tutorial
+#define Tutorial_VERSION_MAJOR 
+#define Tutorial_VERSION_MINOR 
+
+
diff --git a/contrib/mmg3d/build/sources/mmg3dlib.c b/contrib/mmg3d/build/sources/mmg3dlib.c
new file mode 100644
index 0000000000000000000000000000000000000000..b03e3c0ff5466bf181cf448db659410ac8f07513
--- /dev/null
+++ b/contrib/mmg3d/build/sources/mmg3dlib.c
@@ -0,0 +1,494 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+/*
+mmg3dlib(int option, ): to use mmg3d via a library
+
+option = 
+  fprintf(stdout,"  1      adaptation\n");
+  fprintf(stdout,"  9      moving mesh\n");
+  fprintf(stdout," -n      turn off optimisation\n");
+
+*/
+#include "compil.date"
+#include "mesh.h"
+#include "eigenv.h"
+
+TIM_mytime         MMG_ctim[TIMEMAX];
+short	       MMG_imprim;
+
+static void MMG_excfun(int sigid) {
+  switch (sigid) {
+  case SIGFPE:
+    fprintf(stderr,"  ## FP EXCEPTION. STOP\n");
+    break;
+  case SIGILL:
+    fprintf(stderr,"  ## ILLEGAL INSTRUCTION. STOP\n");
+    break;
+  case SIGSEGV:
+    fprintf(stderr,"  ## SEGMENTATION FAULT. STOP\n");
+    break;
+  case SIGABRT:
+  case SIGTERM:
+  case SIGINT:
+    fprintf(stderr,"  ## ABNORMAL END. STOP\n");
+    break;
+  }
+  exit(1);
+}
+
+void MMG_endcod() {
+  double   ttot,ttim[TIMEMAX];
+  int      k,call[TIMEMAX];
+
+  TIM_chrono(OFF,&MMG_ctim[0]);
+  
+  for (k=0; k<TIMEMAX; k++) {
+    call[k] = MMG_ctim[k].call;
+    ttim[k] = MMG_ctim[k].call ? TIM_gttime(MMG_ctim[k]) : 0.0;
+  }
+  ttot    = ttim[1]+ttim[2]+ttim[3]+ttim[4];
+  ttim[0] = M_MAX(ttim[0],ttot);
+
+  if ( abs(MMG_imprim) > 5 ) {
+    fprintf(stdout,"\n  -- CPU REQUIREMENTS\n");
+    fprintf(stdout,"  in/out    %8.2f %%    %3d. calls,   %7.2f sec/call\n",
+	    100.*ttim[1]/ttim[0],call[1],ttim[1]/(float)call[1]);
+    fprintf(stdout,"  analysis  %8.2f %%    %3d. calls,   %7.2f sec/call\n",
+	    100.*ttim[2]/ttim[0],call[2],ttim[2]/(float)call[2]);
+    fprintf(stdout,"  optim     %8.2f %%    %3d. calls,   %7.2f sec/call\n",
+	    100.*ttim[3]/ttim[0],call[3],ttim[3]/(float)call[3]);
+    fprintf(stdout,"  total     %8.2f %%    %3d. calls,   %7.2f sec/call\n",
+	    100.*ttot/ttim[0],call[0],ttot/(float)call[0]);
+  }
+  fprintf(stdout,"\n   ELAPSED TIME  %.2f SEC.  (%.2f)\n",ttim[0],ttot);
+}
+
+
+int MMG_inputdata(pMesh mesh,pSol sol) {
+  pPoint 	ppt;
+  int		k;
+  
+  
+  mesh->npfixe = mesh->np;
+  mesh->ntfixe = mesh->nt;
+  mesh->nefixe = mesh->ne;
+  
+  /* keep track of empty links */
+  mesh->npnil = mesh->np + 1;
+  mesh->nenil = mesh->ne + 1;
+  for (k=mesh->npnil; k<mesh->npmax-1; k++)
+    mesh->point[k].tmp  = k+1;
+  for (k=mesh->nenil; k<mesh->nemax-1; k++)
+    mesh->tetra[k].v[3] = k+1;
+  if ( mesh->nt ) {
+    mesh->ntnil = mesh->nt + 1;
+    for (k=mesh->ntnil; k<mesh->ntmax-1; k++)
+      mesh->tria[k].v[2] = k+1;
+  }
+  /*tag points*/
+  for (k=1; k<=mesh->np; k++) {
+      ppt = &mesh->point[k];
+      ppt->tag  = M_UNUSED;
+  }
+ return(1);
+}
+
+int MMG_tassage(pMesh mesh,pSol sol) {
+  pTetra	pt,ptnew;
+  pTria		pt1;
+  pPoint	ppt,pptnew;
+  int 		np,k,ne,nbl,isol,isolnew,i;
+  
+  /*rebuild triangles*/
+	MMG_markBdry(mesh);
+
+  /* compact vertices */
+  np=0;
+  for (k=1; k<=mesh->np; k++) {
+    ppt = &mesh->point[k];
+    if ( ppt->tag & M_UNUSED )  continue;
+    ppt->tmp = ++np;
+  }
+  
+ 
+  /* compact triangles */
+  for (k=1; k<=mesh->nt; k++) {
+    pt1  = &mesh->tria[k];
+    pt1->v[0] = mesh->point[pt1->v[0]].tmp;
+    pt1->v[1] = mesh->point[pt1->v[1]].tmp;
+    pt1->v[2] = mesh->point[pt1->v[2]].tmp;
+  }
+ 
+  /* compact tetrahedra */
+  ne  = 0;
+  nbl = 1;
+  for (k=1; k<=mesh->ne; k++) {
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  {
+      continue;
+    }
+		for(i=0 ; i<4 ; i++)
+		  pt->bdryref[i] = -1;
+    pt->v[0] = mesh->point[pt->v[0]].tmp;
+    pt->v[1] = mesh->point[pt->v[1]].tmp;
+    pt->v[2] = mesh->point[pt->v[2]].tmp;
+    pt->v[3] = mesh->point[pt->v[3]].tmp; 
+		ne++; 
+			//     if(k!=nbl) {
+			// printf("on voudrait tasser\n");
+			//       ptnew = &mesh->tetra[nbl];
+			//       memcpy(ptnew,pt,sizeof(Tetra));
+			//       nbl++;
+			//     }               
+			// 
+		// for(i=0 ; i<4 ; i++)
+		//   ptnew->bdryref[i] = 0;
+		//     if(k != nbl) {
+		//       memset(pt,0,sizeof(Tetra));
+		//       pt->qual = 0.0;
+		//       pt->edge = 0; 
+		//     }
+		//     nbl++;
+  }
+  // mesh->ne = ne;
+  
+  /* compact metric */
+  nbl = 1;
+  for (k=1; k<=mesh->np; k++) {
+    ppt = &mesh->point[k];
+    if ( ppt->tag & M_UNUSED )  continue;
+    isol    = (k-1) * sol->offset + 1;    
+    isolnew = (nbl-1) * sol->offset + 1;
+    
+    for (i=0; i<sol->offset; i++)
+      sol->met[isolnew + i] = sol->met[isol + i];
+    ++nbl;
+  }
+  
+   
+  /*compact vertices*/
+   np  = 0;
+   nbl = 1;
+   for (k=1; k<=mesh->np; k++) {
+     ppt = &mesh->point[k];
+     if ( ppt->tag & M_UNUSED )  continue;
+     pptnew = &mesh->point[nbl];
+     memcpy(pptnew,ppt,sizeof(Point));
+     ppt->tag   &= ~M_UNUSED;
+     assert(ppt->tmp == nbl);
+     np++;
+     if(k != nbl) {
+       ppt = &mesh->point[k];
+       memset(ppt,0,sizeof(Point));
+       ppt->tag    = M_UNUSED;
+     }
+     nbl++;
+   }
+   mesh->np = np;
+   sol->np  = np;
+   
+  for(k=1 ; k<=mesh->np ; k++)
+    mesh->point[k].tmp = 0;
+    
+  mesh->npnil = mesh->np + 1;
+  for (k=mesh->npnil; k<mesh->npmax-1; k++)
+    mesh->point[k].tmp  = k+1;
+  
+  mesh->nenil = mesh->ne + 1;
+  for (k=mesh->nenil; k<mesh->nemax-1; k++)
+    mesh->tetra[k].v[3] = k+1;
+ 
+  mesh->ntnil = mesh->nt + 1;
+  for (k=mesh->ntnil; k<mesh->ntmax-1; k++)
+    mesh->tria[k].v[2] = k+1;
+  
+
+  
+ return(1);
+}
+
+int MMG_mmg3dlib(int opt[9],MMG_pMesh mesh,MMG_pSol sol) {
+  int           alert;
+  Info     	*info;
+  short		imprim;
+  int k,iadr,i,jj,kk,ii,im;
+  double	lambda[3],v[3][3],*mold,*m;
+  fprintf(stdout,"  -- MMG3d, Release %s (%s) \n",M_VER,M_REL);
+  fprintf(stdout,"     Copyright (c) LJLL/IMB, 2010\n");
+  fprintf(stdout,"    %s\n",COMPIL);
+  
+  
+  signal(SIGABRT,MMG_excfun);
+  signal(SIGFPE,MMG_excfun);
+  signal(SIGILL,MMG_excfun);
+  signal(SIGSEGV,MMG_excfun);
+  signal(SIGTERM,MMG_excfun);
+  signal(SIGINT,MMG_excfun);
+ /* atexit(MMG_endcod);
+*/
+
+  TIM_tminit(MMG_ctim,TIMEMAX);
+  TIM_chrono(ON,&MMG_ctim[0]);
+  TIM_chrono(OFF,&MMG_ctim[0]);
+  /* default values */
+  info = &mesh->info;
+
+  info->imprim   = opt[6];
+  info->memory   = 0;
+  info->ddebug   = opt[1];
+  info->option   = opt[0];
+  info->bucksiz  = opt[2];
+  info->noswap   = opt[3];
+  info->nomove   = opt[5];
+  info->noinsert = opt[4];
+	info->rn2      = opt[7];//3;
+	info->rn       = opt[8];//500;
+  alert          = 0;
+  info->dt       = 1.;
+  info->bdry     = 0;
+
+  imprim         = info->imprim;
+  MMG_imprim   = imprim;
+ 
+  if ( imprim )   fprintf(stdout,"\n  -- INPUT DATA\n");
+  TIM_chrono(ON,&MMG_ctim[1]);
+  MMG_inputdata(mesh,sol);
+  if ( sol->np && sol->np != mesh->np ) {
+    fprintf(stdout,"  ## WARNING: WRONG SOLUTION NUMBER. IGNORED\n");
+    sol->np = 0;
+  }
+  /*read displacement*/
+  if ( abs(info->option) == 9 && !mesh->disp)  {
+    //M_free(mesh->adja);
+    fprintf(stdout,"  ## WARNING: NO DISPLACEMENT. IGNORED\n");
+    return(0);
+  }  
+  if ( !MMG_setfunc(sol->offset) ) return(1);
+  if ( !MMG_scaleMesh(mesh,sol) )  return(1);
+  TIM_chrono(OFF,&MMG_ctim[1]);
+  if ( imprim )
+    fprintf(stdout,"  -- DATA READING COMPLETED.     %.2f sec.\n",
+            TIM_gttime(MMG_ctim[1]));
+
+  alert = MMG_outqua(mesh,sol);
+  if(alert) {
+    fprintf(stdout,"\n \n    ## INVALID MESH. STOP\n");
+    exit(1);  
+  }
+  if(MMG_imprim < 0) MMG_outquacubic(mesh,sol);
+
+  fprintf(stdout,"\n  %s\n   MODULE MMG3D-LJLL/IMB : %s (%s)  %s\n  %s\n",
+          M_STR,M_VER,M_REL,sol->offset == 1 ? "ISO" : "ANISO",M_STR);
+  fprintf(stdout,"  MAXIMUM NUMBER OF POINTS    (NPMAX) : %8d\n",mesh->npmax);
+  fprintf(stdout,"  MAXIMUM NUMBER OF TRIANGLES (NTMAX) : %8d\n",mesh->ntmax);
+  fprintf(stdout,"  MAXIMUM NUMBER OF ELEMENTS  (NEMAX) : %8d\n",mesh->nemax);
+
+  /* mesh analysis */
+  TIM_chrono(ON,&MMG_ctim[2]);
+  if ( MMG_imprim )   fprintf(stdout,"\n  -- PHASE 1 : ANALYSIS\n");
+  if ( !MMG_hashTetra(mesh) )    return(1);
+  if ( !MMG_markBdry(mesh) )     return(1);
+  if (abs(mesh->info.option)==10) {
+    MMG_saveMesh(mesh,"tetra.mesh");
+    return(0);
+  }           
+  if ( !sol->np) {
+    fprintf(stdout,"  WARNING NO METRIC FOUND %d\n",sol->np);    
+    im = 1;
+    if(!MMG_doSol(mesh,sol) ) return(1);
+  } else
+    im = 0;
+    
+  TIM_chrono(OFF,&MMG_ctim[2]);
+  if ( MMG_imprim )
+    fprintf(stdout,"  -- PHASE 1 COMPLETED.     %.2f sec.\n",
+            TIM_gttime(MMG_ctim[2]));
+  if ( info->ddebug )  MMG_chkmsh(mesh,1,1);
+  
+  if ( abs(MMG_imprim) > 4 )  {
+	  MMG_prilen(mesh,sol);
+    MMG_ratio(mesh,sol,NULL);        
+  }                       
+
+#ifdef USE_SCOTCH
+  /* renumbering begin */
+   if ( info->rn2 & 1 )  { 
+     TIM_chrono(ON,&MMG_ctim[5]); 
+     if ( MMG_imprim < -6)
+       fprintf(stdout,"renumbering");
+     renumbering(info->rn, mesh, sol);  
+    
+     if ( !MMG_hashTetra(mesh) )    return(1);    
+     TIM_chrono(OFF,&MMG_ctim[5]); 
+     if ( MMG_imprim < -6)
+       fprintf(stdout,"  -- PHASE RENUMBERING COMPLETED.     %.2f sec.\n",
+               TIM_gttime(MMG_ctim[5]));
+     if ( info->ddebug ) MMG_chkmsh(mesh,1,0);
+   }
+   /* renumbering end */
+#endif 
+
+  /* mesh optimization */
+  if ( info->option ) {
+    TIM_chrono(ON,&MMG_ctim[3]);
+    if ( MMG_imprim )   fprintf(stdout,"\n  -- PHASE 2 : UNIT MESH\n");
+    if ( abs(info->option) == 9 ) {  
+      if(!MMG_mmg3d9(mesh,sol,&alert)) {
+        if ( !MMG_unscaleMesh(mesh,sol) )  return(1);
+        MMG_saveMesh(mesh,"errormoving.mesh");
+	      //MMG_saveSol(mesh,sol,mesh->outf);
+	      return(1);
+      }
+      /*puts("appel 1");
+      MMG_mmg3d1(mesh,sol,&alert);*/ 
+      for (k=1; k<=mesh->np; k++) {
+        iadr = (k-1)*sol->offset + 1;
+        m    = &sol->met[iadr];      
+        /*calcul du log de M*/
+        if ( !eigenv(1,m,lambda,v) ) {
+             puts("pbs eigen"); 
+         return(0);
+        }
+        for (i=0; i<3; i++) lambda[i] = log(lambda[i]);
+        mold    = &sol->metold[iadr]; 
+        kk = 0;
+      for (ii=0; ii<3; ii++) {
+           for (jj=ii; jj<3; jj++) {
+              mold[kk] = lambda[0]*v[0][ii]*v[0][jj] + 
+                         lambda[1]*v[1][ii]*v[1][jj] +
+                         lambda[2]*v[2][ii]*v[2][jj]; 
+              kk = kk+1;
+           }                     
+         }
+      }
+    } 
+    
+    if(!info->noinsert) {
+      if(abs(info->option) == 4){ 
+        MMG_mmg3d4(mesh,sol,&alert);
+      } else {
+        MMG_mmg3d1(mesh,sol,&alert);
+      }
+    }
+      
+    TIM_chrono(OFF,&MMG_ctim[3]);
+    if ( MMG_imprim )
+      fprintf(stdout,"  -- PHASE 2 COMPLETED.     %.2f sec.\n",
+              TIM_gttime(MMG_ctim[3]));
+  }
+
+  /* mesh regularisation */
+  if ( info->option > -1 ) {
+#ifdef USE_SCOTCH
+    /* renumbering begin */
+    /*MMG_chkmsh(mesh,0,-1); 
+    puts("3er chk ok");
+    */
+    if ( info->rn2 & 2 )  { 
+      TIM_chrono(ON,&MMG_ctim[6]); 
+      if ( MMG_imprim < -6)
+        fprintf(stdout,"renumbering"); 
+			renumbering(info->rn, mesh, sol);
+      if ( !MMG_hashTetra(mesh) )    return(1);    
+      TIM_chrono(OFF,&MMG_ctim[6]); 
+      if ( MMG_imprim < -6)
+        fprintf(stdout,"  -- PHASE RENUMBERING COMPLETED.     %.2f sec.\n",
+              TIM_gttime(MMG_ctim[6]));
+      if ( info->ddebug ) MMG_chkmsh(mesh,1,0);
+    } 
+    /* renumbering end */   
+#endif
+    TIM_chrono(ON,&MMG_ctim[4]);
+    if ( MMG_imprim )  fprintf(stdout,"\n  -- PHASE 3 : OPTIMIZATION\n");
+    if ( !alert )  {
+      if ( info->option == 9 ) { 
+         MMG_optra4(mesh,sol); 
+      } else {
+         MMG_optra4(mesh,sol); 
+      }
+    }
+    
+    if ( info->ddebug )  MMG_chkmsh(mesh,1,1);
+    TIM_chrono(OFF,&MMG_ctim[4]);
+    if ( MMG_imprim )
+      fprintf(stdout,"  -- PHASE 3 COMPLETED.     %.2f sec.\n",
+              TIM_gttime(MMG_ctim[4]));
+  }
+
+
+  if ( info->option > -1 || abs(MMG_imprim) > 3 ) {
+    MMG_outqua(mesh,sol);
+    if(MMG_imprim < 0) MMG_outquacubic(mesh,sol);
+    MMG_prilen(mesh,sol);
+    MMG_ratio(mesh,sol,NULL);
+  }
+  fprintf(stdout,"\n  %s\n   END OF MODULE MMG3D \n  %s\n",M_STR,M_STR);
+  if ( alert )
+    fprintf(stdout,"\n  ## WARNING: INCOMPLETE MESH  %d , %d\n",
+            mesh->np,mesh->ne);
+
+  if ( MMG_imprim )  fprintf(stdout,"\n  -- SAVING DATA FILE \n");
+  TIM_chrono(ON,&MMG_ctim[1]);
+  if ( !MMG_unscaleMesh(mesh,sol) )  return(1);
+  MMG_tassage(mesh,sol);
+  
+  TIM_chrono(OFF,&MMG_ctim[1]);
+  if ( MMG_imprim ) {
+    fprintf(stdout,"     NUMBER OF GIVEN VERTICES   %8d\n",mesh->npfixe);
+    if ( mesh->ntfixe )
+      fprintf(stdout,"     NUMBER OF GIVEN TRIANGLES  %8d\n",mesh->ntfixe);
+    fprintf(stdout,"     NUMBER OF GIVEN ELEMENTS   %8d\n",mesh->nefixe);
+    fprintf(stdout,"     TOTAL NUMBER OF VERTICES   %8d\n",mesh->np);
+    fprintf(stdout,"     TOTAL NUMBER OF TRIANGLES  %8d\n",mesh->nt);
+    fprintf(stdout,"     TOTAL NUMBER OF ELEMENTS   %8d\n",mesh->ne);
+  }
+
+  if ( MMG_imprim )  fprintf(stdout,"  -- SAVING COMPLETED\n");
+
+  if ( MMG_imprim < -4 || info->ddebug )  M_memDump();
+
+  return(alert);
+}
diff --git a/contrib/mmg3d/build/sources/movevertex.c b/contrib/mmg3d/build/sources/movevertex.c
new file mode 100644
index 0000000000000000000000000000000000000000..207afc28f4f8c1ace239d3bfd5ec1803f5af7cbe
--- /dev/null
+++ b/contrib/mmg3d/build/sources/movevertex.c
@@ -0,0 +1,366 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+int MMG_movevertex_ani(pMesh mesh,pSol sol,int k,int ib) {
+  pTetra 	pt,pt1;
+  pPoint 	ppa,ppb,p1,p2,p3;
+  List  	list;
+  int    	j,iadr,ipb,iter,maxiter,l,lon,iel,i1,i2,i3;
+  double  	*mp,coe;
+  double 	ax,ay,az,bx,by,bz,nx,ny,nz,dd,len,qual,oldc[3];    
+  assert(k);
+  assert(ib<4);
+  pt = &mesh->tetra[k];
+  ppa  = &mesh->point[pt->v[ib]];
+  iadr = (pt->v[ib]-1)*sol->offset + 1;
+  mp   = &sol->met[iadr];
+  
+  /*compute normal*/
+  i1 = pt->v[MMG_idir[ib][0]];
+  i2 = pt->v[MMG_idir[ib][1]];
+  i3 = pt->v[MMG_idir[ib][2]];
+  p1 = &mesh->point[i1];
+  p2 = &mesh->point[i2];
+  p3 = &mesh->point[i3];
+  
+  ax = p3->c[0] - p1->c[0];
+  ay = p3->c[1] - p1->c[1];
+  az = p3->c[2] - p1->c[2];
+
+  bx = p2->c[0] - p1->c[0];
+  by = p2->c[1] - p1->c[1];
+  bz = p2->c[2] - p1->c[2];
+
+  nx = (ay*bz - az*by);
+  ny = (az*bx - ax*bz);
+  nz = (ax*by - ay*bx);
+    
+  dd = sqrt(nx*nx+ny*ny+nz*nz);  
+  dd = 1./dd;
+  nx *=dd;
+  ny *=dd;
+  nz *=dd;
+  len = 0;
+  for (j=0; j<3; j++) {
+    ipb = pt->v[ MMG_idir[ib][j] ];
+    ppb = &mesh->point[ipb];
+
+    ax  = ppb->c[0] - ppa->c[0];
+    ay  = ppb->c[1] - ppa->c[1];
+    az  = ppb->c[2] - ppa->c[2];
+
+    dd =       mp[0]*ax*ax + mp[3]*ay*ay + mp[5]*az*az \
+  	+ 2.0*(mp[1]*ax*ay + mp[2]*ax*az + mp[4]*ay*az);
+    assert(dd>0);
+    len += sqrt(dd);
+  }	
+    
+  dd  = 1.0 / (double)3.;
+  len = 1.0 / len;
+  len *= dd;
+  memcpy(oldc,ppa->c,3*sizeof(double));
+  	    
+  lon = MMG_boulep(mesh,k,ib,&list);
+  if(mesh->info.imprim < 0 ) if(lon < 4 && lon) printf("lon petit : %d\n",lon);
+  if(!lon) return(0);
+  
+  coe	  = 1.;
+  iter    = 0;
+  maxiter = 20;
+  do {
+    ppa->c[0] = oldc[0] + coe * nx * len;
+    ppa->c[1] = oldc[1] + coe * ny * len;
+    ppa->c[2] = oldc[2] + coe * nz * len;
+
+    for (l=1; l<=lon; l++) {
+      iel = list.tetra[l] >> 2;
+      pt1 = &mesh->tetra[iel];
+
+      qual = MMG_caltet(mesh,sol,iel);
+       if ( !((qual < pt1->qual) || (qual < pt->qual /2.)) )  break;
+       list.qual[l] = qual;
+
+     }
+     if ( l > lon )  break;
+     coe *= 0.5;
+   }
+   while ( ++iter <= maxiter );
+   if ( iter > maxiter) {
+     memcpy(ppa->c,oldc,3*sizeof(double));
+     return(0);
+   }
+   
+   for (l=1; l<=lon; l++) {
+      iel = list.tetra[l] >> 2;
+      pt1 = &mesh->tetra[iel];
+      pt1->qual = list.qual[l];
+//    if ( pt1->qual < declic )
+//	MMG_kiudel(queue,iel);
+   }
+   return(1);
+ 
+}
+
+
+int MMG_movevertex_iso(pMesh mesh,pSol sol,int k,int ib) {
+  pTetra pt,pt1;
+  pPoint ppa,ppb,p1,p2,p3;
+  List  list;
+  int    j,iadr,ipb,iter,maxiter,l,lon,iel,i1,i2,i3;
+  double  hp,coe,crit;
+  double ax,ay,az,bx,by,bz,nx,ny,nz,dd,len,qual,oldc[3];
+  
+  assert(k);
+  assert(ib<4);
+  pt = &mesh->tetra[k];
+   
+  ppa  = &mesh->point[pt->v[ib]];
+  iadr = (pt->v[ib]-1)*sol->offset + 1;
+  hp   = sol->met[iadr];
+  
+  /*compute normal*/
+  i1 = pt->v[MMG_idir[ib][0]];
+  i2 = pt->v[MMG_idir[ib][1]];
+  i3 = pt->v[MMG_idir[ib][2]];
+  p1 = &mesh->point[i1];
+  p2 = &mesh->point[i2];
+  p3 = &mesh->point[i3];
+  
+  ax = p3->c[0] - p1->c[0];
+  ay = p3->c[1] - p1->c[1];
+  az = p3->c[2] - p1->c[2];
+
+  bx = p2->c[0] - p1->c[0];
+  by = p2->c[1] - p1->c[1];
+  bz = p2->c[2] - p1->c[2];
+
+  nx = (ay*bz - az*by);
+  ny = (az*bx - ax*bz);
+  nz = (ax*by - ay*bx);
+    
+  dd = sqrt(nx*nx+ny*ny+nz*nz); 
+  dd = 1./dd;
+  nx *=dd;
+  ny *=dd;
+  nz *=dd;
+  len = 0;
+  for (j=0; j<3; j++) {
+    ipb = pt->v[ MMG_idir[ib][j] ];
+    ppb = &mesh->point[ipb];
+
+    ax  = ppb->c[0] - ppa->c[0];
+    ay  = ppb->c[1] - ppa->c[1];
+    az  = ppb->c[2] - ppa->c[2];
+
+    dd    =   sqrt(ax*ax +ay*ay +az*az);
+    len  +=   dd/hp;
+  }	
+   
+  dd  = 1.0 / (double)3.;
+  len *= dd; 
+  if(len > 0.) len = 1.0 / len;
+  else printf("MMG_movevertex len %e\n",len);
+
+  memcpy(oldc,ppa->c,3*sizeof(double));
+  	    
+  lon = MMG_boulep(mesh,k,ib,&list);
+  if(mesh->info.imprim < 0) if(lon < 4 && lon) printf("lon petit : %d\n",lon);
+  if(!lon) return(0);
+
+  /*qual crit*/
+  crit = pt->qual;
+  for (l=2; l<=lon; l++) {
+    iel = list.tetra[l] >> 2;
+    pt1 = &mesh->tetra[iel];
+    if ( pt1->qual > crit )  crit = pt1->qual;
+  }
+ /* if ( (crit > 100/ALPHAD) ) {
+    crit *= 1.1;
+  } else 
+   */ crit *= 0.99;
+  
+  coe	  = 1.;
+  iter    = 0;
+  maxiter = 20;
+  do {
+
+    ppa->c[0] = oldc[0] + coe * nx * len;
+    ppa->c[1] = oldc[1] + coe * ny * len;
+    ppa->c[2] = oldc[2] + coe * nz * len;
+    for (l=1; l<=lon; l++) {
+      iel = list.tetra[l] >> 2;
+      pt1 = &mesh->tetra[iel];
+      qual = MMG_caltet(mesh,sol,iel);
+      if ( qual > crit )  break;
+       list.qual[l] = qual;
+
+     }
+     if ( l > lon )  break;
+     coe *= 0.5;
+   }
+   while ( ++iter <= maxiter );
+   if ( iter > maxiter) {
+     memcpy(ppa->c,oldc,3*sizeof(double));
+     return(-2);
+   }
+   
+   for (l=1; l<=lon; l++) {
+      iel = list.tetra[l] >> 2;
+      pt1 = &mesh->tetra[iel];
+      pt1->qual = list.qual[l];
+//    if ( pt1->qual < declic )
+//	MMG_kiudel(queue,iel);
+   }
+   return(1);
+ 
+}
+
+
+int MMG_movevertexbdry(pMesh mesh,pSol sol,int k,int ib) {
+  pTetra 	pt,pt1;
+  pPoint 	ppa,ppb,p1,p2,p3;
+  List  	list;
+  int    	j,ipb,iter,maxiter,l,lon,iel,i1,i2,i3;
+  double    coe,crit;
+  double 	ax,ay,az,bx,by,bz,nx,ny,nz,dd,len,qual,oldc[3];
+  
+  assert(k);
+  assert(ib<4);
+  pt = &mesh->tetra[k];
+    
+  ppa  = &mesh->point[pt->v[ib]];
+  
+  /*compute normal*/
+  i1 = pt->v[MMG_idir[ib][0]];
+  i2 = pt->v[MMG_idir[ib][1]];
+  i3 = pt->v[MMG_idir[ib][2]];
+  p1 = &mesh->point[i1];
+  p2 = &mesh->point[i2];
+  p3 = &mesh->point[i3];
+  
+  ax = p3->c[0] - p1->c[0];
+  ay = p3->c[1] - p1->c[1];
+  az = p3->c[2] - p1->c[2];
+
+  bx = p2->c[0] - p1->c[0];
+  by = p2->c[1] - p1->c[1];
+  bz = p2->c[2] - p1->c[2];
+
+  nx = (ay*bz - az*by);
+  ny = (az*bx - ax*bz);
+  nz = (ax*by - ay*bx);
+    
+  dd = sqrt(nx*nx+ny*ny+nz*nz);  
+  dd = 1./dd;
+  nx *=dd;
+  ny *=dd;
+  nz *=dd;
+  len = 0;
+  for (j=0; j<3; j++) {
+    ipb = pt->v[ MMG_idir[ib][j] ];
+    ppb = &mesh->point[ipb];
+
+    ax  = ppb->c[0] - ppa->c[0];
+    ay  = ppb->c[1] - ppa->c[1];
+    az  = ppb->c[2] - ppa->c[2];
+
+    dd   = ax*ax + ay*ay + az*az;
+    len += sqrt(dd);
+  }	
+    
+  dd  = 1.0 / (double)3.;
+  len = 1.0 / len;
+  len *= dd;
+  memcpy(oldc,ppa->c,3*sizeof(double));
+  	    
+  lon = MMG_boulep(mesh,k,ib,&list);
+  if(mesh->info.imprim < 0 ) if(lon < 4 && lon) printf("lon petit : %d\n",lon);
+  if(!lon) return(0);
+  crit = pt->qual;
+  for (l=2; l<=lon; l++) {
+    iel = list.tetra[l] >> 2;
+    pt1 = &mesh->tetra[iel];
+    if ( pt1->qual > crit )  crit = pt1->qual;
+  }
+  coe	  = 0.5;
+  iter    = 0;
+  maxiter = 50;
+  do {
+    ppa->c[0] = oldc[0] + coe * nx * len;
+    ppa->c[1] = oldc[1] + coe * ny * len;
+    ppa->c[2] = oldc[2] + coe * nz * len;
+
+    for (l=1; l<=lon; l++) {
+      iel = list.tetra[l] >> 2;
+      pt1 = &mesh->tetra[iel];
+
+      qual = MMG_caltet(mesh,sol,iel);
+      if ( !((qual < crit)) )  break;
+      list.qual[l] = qual;
+
+    }
+    if ( l > lon )  break;
+    coe *= 0.5;
+  }
+  while ( ++iter <= maxiter );
+  if ( iter > maxiter) {
+    memcpy(ppa->c,oldc,3*sizeof(double));
+    return(0);
+  }
+   
+   for (l=1; l<=lon; l++) {
+      iel = list.tetra[l] >> 2;
+      pt1 = &mesh->tetra[iel];
+      pt1->qual = list.qual[l];
+//    if ( pt1->qual < declic )
+//	MMG_kiudel(queue,iel);
+   }
+   return(1);
+ 
+}
+
+
diff --git a/contrib/mmg3d/build/sources/optbdry.c b/contrib/mmg3d/build/sources/optbdry.c
new file mode 100644
index 0000000000000000000000000000000000000000..71152ccec560924002e60c2096aa2ecbb11de8a9
--- /dev/null
+++ b/contrib/mmg3d/build/sources/optbdry.c
@@ -0,0 +1,272 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+#define OCRIT    0.99
+
+int MMG_movevertexbdry(pMesh mesh,pSol sol,int k,int ib);
+int MMG_colpoi2(pMesh mesh,pSol sol,int iel,int ia,int ib,double coef);
+
+int MMG_optbdry(pMesh mesh,pSol sol,int k) {
+  pTetra pt;
+  int    ia,ib,i,*adja,iadr,ipb;
+
+  
+  
+  pt = &mesh->tetra[k];
+  iadr = 4*(k-1) + 1;
+  adja = &mesh->adja[iadr];
+      
+  /*essai de collapse du point qui n'est pas sur la peau*/
+  for(i=0 ; i<4 ; i++) if(!adja[i]) break;
+  
+  ib  = i;
+  ipb = pt->v[ib];
+  if(!mesh->info.noinsert) {
+    for(i=1 ; i<4 ; i++) {
+      ia = (ib+i)%4;
+      if(MMG_colpoi2(mesh,sol,k,ia,ib,QDEGRAD)) {
+        MMG_delPt(mesh,ipb);
+        break;
+      }
+    }
+  } else {
+    i=4;
+  }
+  
+  /*try to move the 4th vertex*/
+  if(i==4) {
+//if(k==402140) printf("colpoi refused, try move %d %d %d\n",k,ib,pt->v[ib]);
+    if(!MMG_movevertexbdry(mesh,sol,k,ib)) return(0);
+    return(2);
+  }
+   
+  return(1);
+    
+}
+int MMG_opt2peau(pMesh mesh,pSol sol,pQueue queue,int k,double declic) {
+  pTetra    pt,pt1;
+  pPoint    pa,pb,pc,pd;
+  List      list;
+  double    abx,aby,abz,acx,acy,acz,adx,ady,adz,v1,v2,v3,vol;
+  double    bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz,h[6];
+  double     crit;
+  double    s[4],dd,rapmin,rapmax;
+  int       i,ia,ib,ic,id,iarmax,iarmin;
+  int       lon,l,iel,ier;
+
+  ier = 0;
+  
+  pt = &mesh->tetra[k];
+  if ( !pt->v[0] )  return(-1);
+
+  ia = pt->v[0];
+  ib = pt->v[1];
+  ic = pt->v[2];
+  id = pt->v[3];
+  pa = &mesh->point[ia];
+  pb = &mesh->point[ib];
+  pc = &mesh->point[ic];
+  pd = &mesh->point[id];
+
+  /* volume */
+  abx = pb->c[0] - pa->c[0]; 
+  aby = pb->c[1] - pa->c[1]; 
+  abz = pb->c[2] - pa->c[2]; 
+
+  acx = pc->c[0] - pa->c[0]; 
+  acy = pc->c[1] - pa->c[1]; 
+  acz = pc->c[2] - pa->c[2]; 
+
+  adx = pd->c[0] - pa->c[0]; 
+  ady = pd->c[1] - pa->c[1]; 
+  adz = pd->c[2] - pa->c[2]; 
+
+  v1  = acy*adz - acz*ady;
+  v2  = acz*adx - acx*adz;
+  v3  = acx*ady - acy*adx;
+  vol = abx * v1 + aby * v2 + abz * v3;
+
+  /* max edge */
+  h[0] = abx*abx + aby*aby + abz*abz;
+  h[1] = acx*acx + acy*acy + acz*acz;
+  h[2] = adx*adx + ady*ady + adz*adz;
+
+  bcx = pc->c[0] - pb->c[0];
+  bcy = pc->c[1] - pb->c[1];
+  bcz = pc->c[2] - pb->c[2];
+
+  bdx = pd->c[0] - pb->c[0];
+  bdy = pd->c[1] - pb->c[1];
+  bdz = pd->c[2] - pb->c[2];
+
+  cdx = pd->c[0] - pc->c[0];
+  cdy = pd->c[1] - pc->c[1];
+  cdz = pd->c[2] - pc->c[2];
+
+  h[3] = bcx*bcx + bcy*bcy + bcz*bcz;
+  h[4] = bdx*bdx + bdy*bdy + bdz*bdz;
+  h[5] = cdx*cdx + cdy*cdy + cdz*cdz;
+
+  /* face areas */
+  dd = cdy*bdz - cdz*bdy; 
+  s[0] = dd * dd;
+  dd = cdz*bdx - cdx*bdz;
+  s[0] = s[0] + dd * dd;
+  dd = cdx*bdy - cdy*bdx;
+  s[0] = s[0] + dd * dd;
+  s[0] = sqrt(s[0]);
+
+  s[1] = sqrt(v1*v1 + v2*v2 + v3*v3);
+
+  dd = bdy*adz - bdz*ady;
+  s[2] = dd * dd;
+  dd = bdz*adx - bdx*adz;
+  s[2] = s[2] + dd * dd;
+  dd = bdx*ady - bdy*adx;
+  s[2] = s[2] + dd * dd;
+  s[2] = sqrt(s[2]);
+
+  dd = aby*acz - abz*acy;
+  s[3] = dd * dd;
+  dd = abz*acx - abx*acz;
+  s[3] = s[3] + dd * dd;
+  dd = abx*acy - aby*acx;
+  s[3] = s[3] + dd * dd;
+  s[3] = sqrt(s[3]);
+
+  /* classification */
+  rapmin = h[0];
+  rapmax = h[0];
+  iarmin = 0;
+  iarmax = 0;
+  for (i=1; i<6; i++) {
+    if ( h[i] < rapmin ) {
+      rapmin = h[i];
+      iarmin = i;
+    }
+    else if ( h[i] > rapmax ) {
+      rapmax = h[i];
+      iarmax = i;
+    }
+  }
+  rapmin = sqrt(rapmin);
+  rapmax = sqrt(rapmax);
+  
+  if(mesh->info.imprim < -9) printf("edge : %d %d\n",pt->v[MMG_iare[iarmax][0]],pt->v[MMG_iare[iarmax][1]]);
+  /*split edge*/
+  lon = MMG_coquil(mesh,k,iarmax,&list);
+  if(mesh->info.imprim < 0) {
+    //printf("lon %d\n",lon);
+    //if(!lon) printf("colle peau, edge peau\n");
+  }
+  
+  if(!lon) {  
+   for(i=0 ; i<6 ; i++) {
+     lon = MMG_coquil(mesh,k,i,&list);
+     if ( lon > 2 ) {
+       if ( !MMG_zaldy4(&list.hedg,3*LONMAX) ) {
+         fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM MMG_optbdry.\n");
+         MMG_kiufree(queue);
+         return(0);
+       }
+       crit = pt->qual;
+       for (l=2; l<=lon; l++) {
+         iel = list.tetra[l] / 6;
+         pt1 = &mesh->tetra[iel];
+         if ( pt1->qual > crit )  crit = pt1->qual;
+       }
+       crit *= OCRIT;
+       //crit = min(1000/ALPHAD,crit*1.3);
+       ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,1e9);
+       if(ier) {/*printf("on a reussi a l'enlever par MMG_swap\n");*/break;}
+       if ( ier == 0 && !mesh->info.noinsert) { 
+         crit = M_MIN(100./ALPHAD,crit*1.5);
+         ier = MMG_spledg(mesh,sol,queue,&list,lon,/*1.8**/crit,declic);
+       }
+       if(ier) {/*printf("on a reussi a l'enlever par split \n");*/break;}
+      
+       M_free(list.hedg.item);
+      }
+    }
+    
+    //M_free(list.hedg.item);
+
+    if(ier) {
+      M_free(list.hedg.item);
+      return(1);
+    }
+    else return(0);
+  } else {
+ 
+    if ( !MMG_zaldy4(&list.hedg,3*LONMAX) ) {
+      fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM MMG_optbdry.\n");
+      MMG_kiufree(queue);
+      return(0);
+    }
+    if ( lon > 2 ) {
+      crit = pt->qual;
+      for (l=2; l<=lon; l++) {
+        iel = list.tetra[l] / 6;
+        pt1 = &mesh->tetra[iel];
+        if ( pt1->qual > crit )  crit = pt1->qual;
+      }
+      crit *= OCRIT;
+      // crit = min(1000/ALPHAD,crit*1.3);
+      ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,1e9);
+      if ( ier == 0 && !mesh->info.noinsert) {
+        crit = M_MIN(100./ALPHAD,crit*1.5);
+        ier = MMG_spledg(mesh,sol,queue,&list,lon,/*1.8**/crit,declic);
+      }
+    }
+   
+  
+    M_free(list.hedg.item);
+    if(ier) return(1);
+    else return(0);
+ }
+  return(1);
+    
+}
diff --git a/contrib/mmg3d/build/sources/optcoq.c b/contrib/mmg3d/build/sources/optcoq.c
new file mode 100644
index 0000000000000000000000000000000000000000..c63a74d25f647a4a0d3e0e51f43b53f5538a59f9
--- /dev/null
+++ b/contrib/mmg3d/build/sources/optcoq.c
@@ -0,0 +1,120 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+#define SCRIT    0.95
+
+
+/* optim coquilles 3 a 7 */
+int MMG_optcoq(pMesh mesh,pSol sol) {
+  pTetra     pt,pt1;
+  pPoint     p1,p2;
+  List       list;
+  double     crit;
+  int       *adja,adj,iadr,i,j,k,ia,ib,jel,lon,ns,nss,it,maxtou;
+  char       tabar;
+int npp;
+
+  maxtou = 10;
+  nss    = 0;
+  it     = 0;
+
+  do {
+    ns  = 0;
+    npp =0;
+    
+    for (k=1; k<=mesh->ne; k++) {
+      pt = &mesh->tetra[k];
+      if ( !pt->v[0] )  continue;
+npp++;
+      /* mark internal edges */
+      tabar = 0;
+      iadr  = 4*(k-1) + 1;
+      adja  = &mesh->adja[iadr];
+      for (i=0; i<4; i++) {
+        adj = adja[i] >> 2;
+        if ( !adj || pt->ref != mesh->tetra[adj].ref ) {
+          tabar |= 1 << MMG_iarf[i][0];
+          tabar |= 1 << MMG_iarf[i][1];
+          tabar |= 1 << MMG_iarf[i][2];
+        }
+      }
+      if ( tabar == ALL_BDRY )  continue;
+
+      /* longest edge */
+      for (i=0; i<6; i++) {
+        if ( tabar & 1<<i )  continue;
+
+        ia = pt->v[ MMG_iare[i][0] ];
+        ib = pt->v[ MMG_iare[i][1] ];
+        p1 = &mesh->point[ia];
+        p2 = &mesh->point[ib];
+
+        lon  = MMG_coquil(mesh,k,i,&list);
+        if ( lon < 3 || lon > 7 )  continue;
+
+        /* qual crit */
+        crit = pt->qual;
+        for (j=2; j<=lon; j++) {
+          jel  = list.tetra[j] / 6;
+          pt1  = &mesh->tetra[jel];
+          if ( pt1->qual > crit )  crit = pt1->qual;
+        }
+        crit *= SCRIT;
+        /*
+        if ( MMG_swapar(mesh,sol,0,k,i,&list,lon,crit) ) {
+          ns++;
+          break;
+        }*/
+      }
+    }
+printf("  prop %d   swapped %d\n",npp,ns);
+    nss += ns;
+  }
+  while ( ns > 0 && ++it < maxtou );
+
+  return(nss);
+}
diff --git a/contrib/mmg3d/build/sources/optcte.c b/contrib/mmg3d/build/sources/optcte.c
new file mode 100644
index 0000000000000000000000000000000000000000..6651abd33bc15b4d7a109046a14e5a05b762d4c4
--- /dev/null
+++ b/contrib/mmg3d/build/sources/optcte.c
@@ -0,0 +1,275 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+#define  HQCOEF    0.45
+#define  HCRIT     0.8
+
+int MMG_optlentmp(pMesh mesh,pSol sol,double declic,int base) {
+  pTetra    pt,pt1;
+  pPoint    ppa,ppb;
+  pQueue    queue;
+  List      list;
+  double    cal,ctg,cx,cy,cz,ux,uy,uz,cpx,cpy,cpz,coe;
+  double    oldc[3],dd,dd1,dd2,len,lmi,lma;
+  double    *mp,*mb;
+  int       i,j,k,l,iel,lon,nm;
+  int       ipa,ipb,nb,nk,npp,iadr,iter,maxtou;
+
+  /* queueing tetrahedra */
+  queue = MMG_kiuini(mesh,mesh->ne,declic,base);
+  assert(queue);
+  mesh->flag++;
+
+  maxtou = 5;
+  nm  = 0;
+  npp = 0;
+  do {
+    k = MMG_kiupop(queue);
+    if ( !k )  break;
+
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+
+    for (i=0; i<4; i++) {
+      ipa = pt->v[i];
+      ppa = &mesh->point[ipa];
+      if ( ppa->tag & M_BDRY )  continue;
+      else if ( ppa->flag > mesh->flag )  continue;
+      npp++;
+
+      lon = MMG_boulep(mesh,k,i,&list);
+      if ( lon < 4 )  continue;
+
+      /* optimal point */
+      iadr = (ipa-1)*sol->offset + 1;
+      mp   = &sol->met[iadr];
+      cx  = 0.0;
+      cy  = 0.0;
+      cz  = 0.0;
+      nb  = 0;
+      cal = pt->qual;
+      lmi = LSHORT;
+      lma = LLONG;
+      for (l=1; l<=lon; l++) {
+        iel = list.tetra[l] >> 2;
+        nk  = list.tetra[l] % 4;
+        pt1 = &mesh->tetra[iel];
+        if ( pt1->qual > cal )  cal = pt1->qual;
+
+        for (j=0; j<3; j++) {
+          ipb = pt1->v[ MMG_idir[nk][j] ];
+          ppb = &mesh->point[ipb];
+
+          iadr = (ipb-1)*sol->offset + 1;
+          mb   = &sol->met[iadr];
+
+          ux  = ppb->c[0] - ppa->c[0];
+          uy  = ppb->c[1] - ppa->c[1];
+          uz  = ppb->c[2] - ppa->c[2];
+
+          dd1 =      mp[0]*ux*ux + mp[3]*uy*uy + mp[5]*uz*uz \
+              + 2.0*(mp[1]*ux*uy + mp[2]*ux*uz + mp[4]*uy*uz);
+          
+          dd2 =      mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \
+              + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz);
+          len = 0.5*(dd1+dd2);
+          if ( len < lmi )      lmi = len;
+          else if (len > lma )  lma = len;
+
+          /* optimal point */
+          len = 1.0 / sqrt(dd1);
+          cx += ppa->c[0] + ux * len;
+          cy += ppa->c[1] + uy * len;
+          cz += ppa->c[2] + uz * len;
+          nb++;
+        }
+      }
+      if ( nb < 3 )  continue;
+      dd  = 1.0 / (double)nb;
+      cpx = cx*dd - ppa->c[0];
+      cpy = cy*dd - ppa->c[1];
+      cpz = cz*dd - ppa->c[2];
+
+      /* adjust position */
+      coe  = HQCOEF;
+      iter = 1;
+      if ( cal > 10.0 / ALPHAD )
+        ctg = cal * HCRIT;
+      else if ( cal > 5.0 / ALPHAD )
+        ctg = cal * 0.95;
+      else
+        ctg = cal * 0.975;
+      memcpy(oldc,ppa->c,3*sizeof(double));
+
+ctg = 1000. / ALPHAD;
+
+      do {
+        ppa->c[0] = oldc[0] + coe * cpx;
+        ppa->c[1] = oldc[1] + coe * cpy;
+        ppa->c[2] = oldc[2] + coe * cpz;
+
+        for (l=1; l<=lon; l++) {
+          iel = list.tetra[l] >> 2;
+          nk  = list.tetra[l] % 4;
+          pt1 = &mesh->tetra[iel];
+
+          cal = MMG_caltet(mesh,sol,iel);
+          if ( cal > ctg )  break;
+          list.qual[l] = cal;
+
+          /* check MMG_length */
+          for (j=0; j<3; j++) {
+            ipb = pt1->v[ MMG_idir[nk][j] ];
+            ppb = &mesh->point[ipb];
+
+            iadr = (ipb-1)*sol->offset + 1;
+            mb   = &sol->met[iadr];
+
+            ux  = ppb->c[0] - ppa->c[0];
+            uy  = ppb->c[1] - ppa->c[1];
+            uz  = ppb->c[2] - ppa->c[2];
+
+            dd1 =      mp[0]*ux*ux + mp[3]*uy*uy + mp[5]*uz*uz \
+                + 2.0*(mp[1]*ux*uy + mp[2]*ux*uz + mp[4]*uy*uz);
+          
+            dd2 =      mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \
+                + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz);
+            len = 0.5*(dd1+dd2);
+
+            if ( len < lmi || len > lma )  break;
+          }
+          if ( j < 3 )  break;
+        }
+        if ( l > lon )  break;
+        coe *= 0.5;
+      }
+      while ( ++iter <= maxtou );
+      if ( iter > maxtou ) {
+        memcpy(ppa->c,oldc,3*sizeof(double));
+        continue;
+      }
+
+      /* update tetra */
+      for (l=1; l<=lon; l++) {
+        iel = list.tetra[l] >> 2;
+        nk  = list.tetra[l] % 4;
+        pt1 = &mesh->tetra[iel];
+        pt1->qual = list.qual[l];
+        pt1->flag = mesh->flag;
+        /*if ( pt1->qual < declic )
+          MMG_kiudel(queue,iel);
+        else if ( coe > 0.1 )
+          MMG_kiuput(queue,iel); */
+      }
+
+      /* interpol metric */
+      ppa->flag = mesh->flag + 1;
+      nm++;
+      break;
+    }
+  }
+  while ( k );
+
+  if ( mesh->info.imprim < -4 )
+    fprintf(stdout,"     %7d PROPOSED  %7d MOVED\n",npp,nm);
+
+  MMG_kiufree(queue);
+  return(nm);
+}
+
+
+
+
+
+int MMG_optcte(pMesh mesh,pSol sol) {
+  double	declicw;
+  double	declic;
+  int		base,nm,ns,it,maxtou,alert,nw;
+
+
+  alert  = 0;
+
+  /* optim coquil */
+  declic = 1. / ALPHAD;
+  maxtou = 10;
+  base   = -1;
+  it     = 0;
+
+  do {
+  
+    nw = 0;
+    declicw = 5./ALPHAD;
+//    if (!mesh->info.noswap) nw = MMG_opttyp(mesh,sol,declicw,&alert);   
+    
+    nm = MMG_optlentmp(mesh,sol,declic,-1);
+//     ns = 0;
+//     if ( !alert && !mesh->info.noswap ) {
+//       ns = MMG_cendel(mesh,sol,declic,base);
+//       if ( ns < 0 ) {
+//         alert = 1;
+// 	ns    = -ns;
+//       }
+//     }
+//     base = ++mesh->flag;
+//     
+//     if ( !mesh->disp ) if(it<2) MMG_optlap(mesh,sol);
+    
+ns = 0;    
+    if ( mesh->info.imprim && nm+ns )
+      fprintf(stdout,"     %8d MOVED  %8d SWAPPED\n",nm,ns);
+  }
+  while ( nm > 0.01*mesh->np && ++it < maxtou );
+    
+ 
+  MMG_outqua(mesh,sol);
+  MMG_prilen(mesh,sol);
+  puts("-------- APPEL MMG_optra4");
+  MMG_optra4(mesh,sol);
+  
+  return(1);
+}
+
diff --git a/contrib/mmg3d/build/sources/optlap.c b/contrib/mmg3d/build/sources/optlap.c
new file mode 100644
index 0000000000000000000000000000000000000000..6a81bbba3af390306fc2e98ef73512b300e43a22
--- /dev/null
+++ b/contrib/mmg3d/build/sources/optlap.c
@@ -0,0 +1,284 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+#define  LLAMBDA   0.33  /*0.33*/
+#define  LMU       0.331   /*0.34*/
+
+int MMG_optlap(pMesh mesh,pSol sol) {
+  pTetra    pt,pt1;
+  pPoint    ppt,pptb,ppta;
+  pDispl    pdisp;
+  List      list;
+  int       it,i,k,lon,l,iel,ipt;
+  int       maxiter,ipta,iptb,ipt0,ipt1,ipt2,ipt3;
+  double    vol,ax,ay,az,bx,by,bz;
+  double    *nv,res,dd,ox,oy,oz,declic;
+
+  if(!mesh->disp) {
+	  mesh->disp = (pDispl)M_calloc(1,sizeof(Displ),"MMG_zaldy.displ");
+	  assert(mesh->disp);
+	  mesh->disp->mv = (double*)M_calloc(3*(mesh->npmax + 1),sizeof(double),"MMG_zaldy.displ");
+	  assert(mesh->disp->mv);
+	  mesh->disp->alpha = (short*)M_calloc(mesh->npmax+1,sizeof(short),"MMG_zaldy.displ");
+	  assert(mesh->disp->alpha);
+  }
+  maxiter = 3;  
+  nv = (double*)M_calloc(mesh->np+1,3*sizeof(double),"movlap.nv");
+  assert(nv);
+  
+  pdisp         = mesh->disp;	
+
+  it  = 1;
+  declic = 3./ALPHAD;
+  do {
+  
+    /*initialisation*/
+    for(i = 1 ; i<=mesh->np ; i++) {
+      ppt          = &mesh->point[i];
+      pdisp->alpha[i] = 0;
+      pdisp->mv[3*(i-1) + 1 + 0] = 0.;
+      pdisp->mv[3*(i-1) + 1 + 1] = 0.;
+      pdisp->mv[3*(i-1) + 1 + 2] = 0.;
+      
+    }
+
+    /*1st stage : laplacian*/    
+    for(k = 1 ; k<=mesh->ne ; k++) {
+      pt = &mesh->tetra[k];
+      if (!pt->v[0]) continue;
+      if (pt->qual > declic) continue;
+
+      for(i=0 ; i<6 ; i++) {
+        ipta   = pt->v[MMG_iare[i][0]];
+        ppta   = &mesh->point[ipta];
+        
+		iptb   = pt->v[MMG_iare[i][1]];
+        pptb   = &mesh->point[iptb];
+	
+		if(!(ppta->tag & M_BDRY)) {
+	  		pdisp->mv[3*(ipta-1) + 1 + 0] += pptb->c[0];
+	  		pdisp->mv[3*(ipta-1) + 1 + 1] += pptb->c[1];
+	  		pdisp->mv[3*(ipta-1) + 1 + 2] += pptb->c[2];
+	  		pdisp->alpha[ipta]++;
+		}
+		if(!(pptb->tag & M_BDRY)) {
+	  		pdisp->mv[3*(iptb-1) + 1 + 0] += ppta->c[0];
+	  		pdisp->mv[3*(iptb-1) + 1 + 1] += ppta->c[1];
+	  		pdisp->mv[3*(iptb-1) + 1 + 2] += ppta->c[2];
+	  		pdisp->alpha[iptb]++;
+		}
+      }
+    }
+
+    for(i=1 ; i<=mesh->np ; i++) {  
+      ppt           = &mesh->point[i];
+      if(pdisp->alpha[i]) {
+        dd            = 1./(double) pdisp->alpha[i];
+        pdisp->mv[3*(i-1) + 1 + 0] *= dd;
+        pdisp->mv[3*(i-1) + 1 + 1] *= dd;
+        pdisp->mv[3*(i-1) + 1 + 2] *= dd;
+        nv[3*(i-1) + 1] = ppt->c[0] + LLAMBDA * (ppt->c[0] - pdisp->mv[3*(i-1) + 1 + 0]);
+        nv[3*(i-1) + 2] = ppt->c[1] + LLAMBDA * (ppt->c[1] - pdisp->mv[3*(i-1) + 1 + 1]);
+        nv[3*(i-1) + 3] = ppt->c[2] + LLAMBDA * (ppt->c[2] - pdisp->mv[3*(i-1) + 1 + 2]);
+      } else {
+        nv[3*(i-1) + 1] = ppt->c[0];
+        nv[3*(i-1) + 2] = ppt->c[1];
+        nv[3*(i-1) + 3] = ppt->c[2];
+      
+      }
+      pdisp->alpha[i] = 0;
+      pdisp->mv[3*(i-1) + 1 + 0] = 0.;
+      pdisp->mv[3*(i-1) + 1 + 1] = 0.;
+      pdisp->mv[3*(i-1) + 1 + 2] = 0.;
+      
+    }
+
+    /*2nd stage : anti-laplacian*/
+    for(k = 1 ; k<=mesh->ne ; k++) {
+      pt = &mesh->tetra[k];
+      if (!pt->v[0]) continue;
+      if (pt->qual > declic) continue;
+      
+      for(i=0 ; i<6 ; i++) {
+        ipta   = pt->v[MMG_iare[i][0]];
+        ppta   = &mesh->point[ipta];
+       
+    	iptb   = pt->v[MMG_iare[i][1]];
+        pptb   = &mesh->point[iptb];
+	
+	if(!(ppta->tag & M_BDRY)) {
+	  pdisp->mv[3*(ipta-1) + 1 + 0] += nv[3*(iptb-1) + 1];
+	  pdisp->mv[3*(ipta-1) + 1 + 1] += nv[3*(iptb-1) + 2];
+	  pdisp->mv[3*(ipta-1) + 1 + 2] += nv[3*(iptb-1) + 3];
+	  pdisp->alpha[ipta]++;
+	}
+	if(!(pptb->tag & M_BDRY)) {
+	  pdisp->mv[3*(iptb-1) + 1 + 0] += nv[3*(ipta-1) + 1];
+	  pdisp->mv[3*(iptb-1) + 1 + 1] += nv[3*(ipta-1) + 2];
+	  pdisp->mv[3*(iptb-1) + 1 + 2] += nv[3*(ipta-1) + 3];
+	  pdisp->alpha[iptb]++;
+	}
+      }
+    }
+    
+    res= 0.;
+    for(i=1 ; i<=mesh->np ; i++) {  
+      ppt           = &mesh->point[i];
+      if(pdisp->alpha[i]) {
+        dd            = 1./(double) pdisp->alpha[i];
+        pdisp->mv[3*(i-1) + 1 + 0] *= dd;
+        pdisp->mv[3*(i-1) + 1 + 1] *= dd;
+        pdisp->mv[3*(i-1) + 1 + 2] *= dd;
+        ox = nv[3*(i-1) + 1];
+        oy = nv[3*(i-1) + 2];
+        oz = nv[3*(i-1) + 3];
+        nv[3*(i-1) + 1] = nv[3*(i-1) + 1] - LMU * (nv[3*(i-1) + 1] - pdisp->mv[3*(i-1) + 1 + 0]);
+        nv[3*(i-1) + 2] = nv[3*(i-1) + 2] - LMU * (nv[3*(i-1) + 2] - pdisp->mv[3*(i-1) + 1 + 1]);
+        nv[3*(i-1) + 3] = nv[3*(i-1) + 3] - LMU * (nv[3*(i-1) + 3] - pdisp->mv[3*(i-1) + 1 + 2]);
+	
+        dd = (nv[3*(i-1) + 1]-ox)*(nv[3*(i-1) + 1]-ox) 
+           + (nv[3*(i-1) + 2]-oy)*(nv[3*(i-1) + 2]-oy)
+	   + (nv[3*(i-1) + 3]-oz)*(nv[3*(i-1) + 3]-oz);
+        res +=dd;     
+      
+      } 
+      
+      
+      pdisp->alpha[i] = 0;
+      pdisp->mv[3*(i-1) + 1 + 0] = 0.;
+      pdisp->mv[3*(i-1) + 1 + 1] = 0.;
+      pdisp->mv[3*(i-1) + 1 + 2] = 0.;
+    }    
+/*    printf("---------- iter %d  res %e\r",it,res);
+    fflush(stdout); 
+*/    
+    /*check new coor*/
+    for(k = 1 ; k<=mesh->ne ; k++) {
+      pt = &mesh->tetra[k];
+      if(!pt->v[0]) continue;
+      
+      for(i=0 ; i<4 ; i++) {
+        ipt   = pt->v[i];
+        ppt   = &mesh->point[ipt];
+    	if(ppt->tag & M_BDRY) continue;
+	    if(ppt->tmp2) continue;
+	    ppt->tmp2 = 1;
+	    lon = MMG_boulep(mesh,k,i,&list);
+        for (l=1; l<=lon; l++) {
+          iel    = list.tetra[l] >> 2;
+          pt1    = &mesh->tetra[iel];
+	      ipt0   = 3*(pt1->v[0] - 1);
+	      ipt1   = 3*(pt1->v[1] - 1);
+	      ipt2   = 3*(pt1->v[2] - 1);
+	      ipt3   = 3*(pt1->v[3] - 1);
+	  
+          ax = nv[ipt2 + 1] - nv[ipt0 + 1];
+          ay = nv[ipt2 + 2] - nv[ipt0 + 2];
+          az = nv[ipt2 + 3] - nv[ipt0 + 3];
+  
+          bx = nv[ipt3 + 1] - nv[ipt0 + 1];
+          by = nv[ipt3 + 2] - nv[ipt0 + 2];
+          bz = nv[ipt3 + 3] - nv[ipt0 + 3];
+  
+          vol = (nv[ipt1 + 1] - nv[ipt0 + 1]) * (ay*bz - az*by) \
+              + (nv[ipt1 + 2] - nv[ipt0 + 2]) * (az*bx - ax*bz) \
+              + (nv[ipt1 + 3] - nv[ipt0 + 3]) * (ax*by - ay*bx);
+          if(vol < 0) {/*printf("reject1 %e\n",vol);*/break;}
+        }
+	if(l<=lon) {
+	  memcpy(&pdisp->mv[3*(ipt-1) + 1],ppt->c,3*sizeof(double));
+          for (l=1; l<=lon; l++) {
+            iel    = list.tetra[l] >> 2;
+            pt1    = &mesh->tetra[iel];
+	    ipt0   = 3*(pt1->v[0] - 1);
+	    ipt1   = 3*(pt1->v[1] - 1);
+	    ipt2   = 3*(pt1->v[2] - 1);
+	    ipt3   = 3*(pt1->v[3] - 1);
+	  
+            ax = nv[ipt2 + 1] - nv[ipt0 + 1];
+            ay = nv[ipt2 + 2] - nv[ipt0 + 2];
+            az = nv[ipt2 + 3] - nv[ipt0 + 3];
+  
+            bx = nv[ipt3 + 1] - nv[ipt0 + 1];
+            by = nv[ipt3 + 2] - nv[ipt0 + 2];
+            bz = nv[ipt3 + 3] - nv[ipt0 + 3];
+  
+            vol = (nv[ipt1 + 1] - nv[ipt0 + 1]) * (ay*bz - az*by) \
+                + (nv[ipt1 + 2] - nv[ipt0 + 2]) * (az*bx - ax*bz) \
+                + (nv[ipt1 + 3] - nv[ipt0 + 3]) * (ax*by - ay*bx);
+            if(vol < 0) {/*printf("reject %e\n",vol);*/break;}
+          }
+	  if(l<=lon) break;
+	}
+      }
+      if(i<4) break;
+    }  
+    if(k > mesh->ne) { 
+      /*update coor*/
+      for(i=1 ; i<=mesh->np ; i++) {
+        ppt   = &mesh->point[i];
+        ppt->c[0] = nv[3*(i-1) + 1];
+        ppt->c[1] = nv[3*(i-1) + 2];
+        ppt->c[2] = nv[3*(i-1) + 3];
+      }
+      for(k=1 ; k<=mesh->ne ; k++) {
+        pt = &mesh->tetra[k];
+	if(!pt->v[0]) continue;
+	pt->qual = MMG_caltet(mesh,sol,k);
+      }
+      if(mesh->info.imprim < 0) fprintf(stdout,"              LAPLACIAN : %8f\n",res);      
+    } else {     
+      if(mesh->info.imprim < 0) fprintf(stdout,"              NO LAPLACIAN\n");
+      break;
+    }
+    if(res<1e-5) break;
+   
+  } while(it++ < maxiter);
+
+  M_free(nv);
+  return(1);
+}
diff --git a/contrib/mmg3d/build/sources/optlen.c b/contrib/mmg3d/build/sources/optlen.c
new file mode 100644
index 0000000000000000000000000000000000000000..ab8b07a26ac5f90a86d4c387f87b35330e2a3b7a
--- /dev/null
+++ b/contrib/mmg3d/build/sources/optlen.c
@@ -0,0 +1,610 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+#define  HQCOEF    0.9 
+#define  HCRIT     0.98
+
+double MMG_rao(pMesh mesh,int k,int inm);
+int MMG_optlen_ani(pMesh mesh,pSol sol,double declic,int base) {
+  pTetra    pt,pt1;
+  pPoint    ppa,ppb;
+  pQueue    queue;
+  List      list;
+  double    cal,ctg,cx,cy,cz,ux,uy,uz,cpx,cpy,cpz,coe;
+  double    oldc[3],dd,dd1,dd2,len,lmi,lma;
+  double    *mp,*mb,wcal;
+  int       i,j,k,l,iel,lon,nm;
+  int       ipa,ipb,nb,nk,npp,iadr,iter,maxtou;
+
+  /* queueing tetrahedra */
+  queue = MMG_kiuini(mesh,mesh->ne,declic,base - 1);
+  assert(queue);
+  
+  maxtou = 3;
+  nm     = 0;
+  npp    = 0;
+  wcal   = 5. / ALPHAD;
+  
+  do {
+    k = MMG_kiupop(queue);
+    if ( !k )  break;
+
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+    else if ( pt->flag != base - 1 )  continue;
+    
+    for (i=0; i<4; i++) {
+      ipa = pt->v[i];
+      ppa = &mesh->point[ipa];
+      if ( ppa->tag & M_BDRY )  continue;
+      else if ( ppa->flag != base - 1)  continue;
+      npp++;
+
+      lon = MMG_boulep(mesh,k,i,&list);
+      if ( lon < 4 )  continue;
+
+      /* optimal point */
+      iadr = (ipa-1)*sol->offset + 1;
+      mp   = &sol->met[iadr];
+      cx  = 0.0;
+      cy  = 0.0;
+      cz  = 0.0;
+      nb  = 0;
+      cal = pt->qual;
+      lmi = LSHORT;
+      lma = LLONG;
+      for (l=1; l<=lon; l++) {
+        iel = list.tetra[l] >> 2;
+        nk  = list.tetra[l] % 4;
+        pt1 = &mesh->tetra[iel];
+        if ( pt1->qual > cal )  cal = pt1->qual;
+
+        for (j=0; j<3; j++) {
+          ipb = pt1->v[ MMG_idir[nk][j] ];
+          ppb = &mesh->point[ipb];
+
+          iadr = (ipb-1)*sol->offset + 1;
+          mb   = &sol->met[iadr];
+
+          ux  = ppb->c[0] - ppa->c[0];
+          uy  = ppb->c[1] - ppa->c[1];
+          uz  = ppb->c[2] - ppa->c[2];
+
+          dd1 =      mp[0]*ux*ux + mp[3]*uy*uy + mp[5]*uz*uz \
+              + 2.0*(mp[1]*ux*uy + mp[2]*ux*uz + mp[4]*uy*uz);
+          
+          dd2 =      mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \
+              + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz);
+          len = 0.5*(dd1+dd2);
+          if ( len < lmi )      lmi = len;
+          else if (len > lma )  lma = len;
+
+          /* optimal point */
+          len = 1.0 / sqrt(dd1);
+          cx += ppa->c[0] + ux * len;
+          cy += ppa->c[1] + uy * len;
+          cz += ppa->c[2] + uz * len;
+          nb++;
+        }
+      }
+      if ( nb < 3 )  continue;
+      dd  = 1.0 / (double)nb;
+      cpx = cx*dd - ppa->c[0];
+      cpy = cy*dd - ppa->c[1];
+      cpz = cz*dd - ppa->c[2];
+
+      /* adjust position */
+      coe  = HQCOEF;
+      iter = 1;
+      /*if ( cal > 10.0 / ALPHAD )
+        ctg = cal * HCRIT;
+      else*/ 
+        ctg = cal * HCRIT;//0.975;
+      memcpy(oldc,ppa->c,3*sizeof(double));
+
+      do {
+        ppa->c[0] = oldc[0] + coe * cpx;
+        ppa->c[1] = oldc[1] + coe * cpy;
+        ppa->c[2] = oldc[2] + coe * cpz;
+
+        for (l=1; l<=lon; l++) {
+          iel = list.tetra[l] >> 2;
+          nk  = list.tetra[l] % 4;
+          pt1 = &mesh->tetra[iel];
+
+          cal = MMG_caltet(mesh,sol,iel);
+          if ( cal > ctg )  break;
+          list.qual[l] = cal;
+
+          /* check length */
+        /*  for (j=0; j<3; j++) {
+            ipb = pt1->v[ MMG_idir[nk][j] ];
+            ppb = &mesh->point[ipb];
+            
+            iadr = (ipb-1)*sol->offset + 1;
+            mb   = &sol->met[iadr];
+
+            ux  = ppb->c[0] - ppa->c[0];
+            uy  = ppb->c[1] - ppa->c[1];
+            uz  = ppb->c[2] - ppa->c[2];
+
+            dd1 =      mp[0]*ux*ux + mp[3]*uy*uy + mp[5]*uz*uz \
+                + 2.0*(mp[1]*ux*uy + mp[2]*ux*uz + mp[4]*uy*uz);
+          
+            dd2 =      mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \
+                + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz);
+            len = 0.5*(dd1+dd2);
+
+            if ( len < lmi || len > lma )  break;
+          }
+          if ( j < 3 )  break;*/
+        }
+        if ( l > lon )  break;
+        coe *= 0.5;
+      }
+      while ( ++iter <= maxtou );
+      if ( iter > maxtou ) {
+        memcpy(ppa->c,oldc,3*sizeof(double));
+	    ppa->flag = base - 2;
+        continue;
+      }
+
+      /* update tetra */
+      for (l=1; l<=lon; l++) {
+        iel = list.tetra[l] >> 2;
+        nk  = list.tetra[l] % 4;
+        pt1 = &mesh->tetra[iel];
+        pt1->qual = list.qual[l];
+        pt1->flag = base;
+		for(i=0; i<4; i++)  mesh->point[pt1->v[i]].flag = base; 
+        if ( pt1->qual < declic )
+          MMG_kiudel(queue,iel);
+        else if ( coe > 0.1 )
+          MMG_kiuput(queue,iel); 
+      }
+
+      /* interpol metric */
+      ppa->flag = base + 1;
+      nm++;
+      break;
+    }
+  }
+  while ( k );
+
+  if ( mesh->info.imprim < -4 )
+    fprintf(stdout,"     %7d PROPOSED  %7d MOVED\n",npp,nm);
+
+  MMG_kiufree(queue);
+  return(nm);
+}
+
+
+/* optimise using heap */
+int MMG_optlen_iso(pMesh mesh,pSol sol,double declic,int base) {
+  pTetra    pt,pt1;
+  pPoint    ppa,ppb;
+  pQueue    queue;
+  List      list;
+  double    oldc[3],cal,ctg,cx,cy,cz,ux,uy,uz,cpx,cpy,cpz,coe,dd,len;
+  double    hb,hp,*ca,*cb;
+  int       i,j,k,l,iel,lon,nm;
+  int       ipa,ipb,nb,nk,npp,iadr,iter,maxtou;
+int nrj;    
+double tmp1,tmp2,tmp3;
+  /* queue on quality */
+  queue = MMG_kiuini(mesh,mesh->ne,declic,base - 1);
+  assert(queue);
+
+  maxtou = 10;
+  nm     = 0;
+  npp    = 0;
+nrj = 0;  
+  do {
+    k = MMG_kiupop(queue);
+    if ( !k )  break;
+    npp++;
+
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+   //	else if ( pt->flag != base - 1 ) continue;
+    for (i=0; i<4; i++) {
+      ipa = pt->v[i];
+      ppa = &mesh->point[ipa];
+      if ( ppa->tag & M_BDRY )  continue;
+    //  else if ( ppa->flag != base - 1 )  continue;
+
+      lon = MMG_boulep(mesh,k,i,&list);
+      if ( lon < 4 )  continue;
+
+      /* optimal point */
+      ca   = &ppa->c[0];
+      iadr = (ipa-1)*sol->offset + 1;
+      hp   = sol->met[iadr];
+      cx   = 0.0;
+      cy   = 0.0;
+      cz   = 0.0;
+      nb   = 0;
+      cal  = pt->qual;
+      for (l=1 ; l<=lon; l++) {
+        iel = list.tetra[l] >> 2;
+        nk  = list.tetra[l] % 4;
+        pt1 = &mesh->tetra[iel];
+        if ( pt1->qual > cal )  cal = pt1->qual;
+		tmp1 = 0;
+		tmp2 = 0;
+		tmp3 = 0;
+        for (j=0; j<3; j++) {
+          ipb  = pt1->v[ MMG_idir[nk][j] ];
+          ppb  = &mesh->point[ipb]; 
+/*if(ppb->mark < 0) continue;
+ppb->mark = -ppb->mark;*/      
+//printf("on prend en compte point %d\n",ipb);
+	      cb   = &ppb->c[0];
+          iadr = (ipb-1)*sol->offset + 1;
+          hb   = sol->met[iadr];
+
+          len = MMG_length(ca,cb,&hp,&hb); 
+
+/*len = MMG_length(&(mesh->point[pt1->v[MMG_idir[nk][0]]].c[0]),&(mesh->point[pt1->v[MMG_idir[nk][1]]].c[0]),&hp,&hb); 
+len += MMG_length(&(mesh->point[pt1->v[MMG_idir[nk][0]]].c[0]),&(mesh->point[pt1->v[MMG_idir[nk][2]]].c[0]),&hp,&hb); 
+len += MMG_length(&(mesh->point[pt1->v[MMG_idir[nk][1]]].c[0]),&(mesh->point[pt1->v[MMG_idir[nk][2]]].c[0]),&hp,&hb); 
+len /= 3.;
+len = 1./len;
+len *=  MMG_length(ca,cb,&hp,&hb); */  	
+          /* optimal point */
+	      ux  = ppb->c[0] - ppa->c[0];
+          uy  = ppb->c[1] - ppa->c[1];
+          uz  = ppb->c[2] - ppa->c[2];
+          cx += ppa->c[0] + ux*(1. - 1./len);//ux * len;
+          cy += ppa->c[1] + uy*(1. - 1./len);//uy * len;
+          cz += ppa->c[2] + uz*(1. - 1./len);//uz * len; 
+		tmp1 +=ux*(1. - 1./len);
+		tmp2 +=uy*(1. - 1./len);
+		tmp3 +=uz*(1. - 1./len);
+/*memcpy(oldc,ppa->c,3*sizeof(double));
+ppa->c[0] = oldc[0] + ux*(1. - 1./len);//ppb->c[0] - (ux/MMG_length(oldc,cb,&hp,&hb))*len;
+ppa->c[1] = oldc[1] + uy*(1. - 1./len);//ppb->c[1] - (uy/MMG_length(oldc,cb,&hp,&hb))*len;
+ppa->c[2] = oldc[2] + uz*(1. - 1./len);//ppb->c[2] - (uz/MMG_length(oldc,cb,&hp,&hb))*len; 
+printf("%d len %e (%e)\n",j,MMG_length(ca,cb,&hp,&hb),len);
+memcpy(ppa->c,oldc,3*sizeof(double));            
+  */ 	
+          nb++;
+        }
+/*check amelioration*/
+/*memcpy(oldc,ppa->c,3*sizeof(double));
+ppa->c[0] = oldc[0] + tmp1/3.;
+ppa->c[1] = oldc[1] + tmp2/3.;
+ppa->c[2] = oldc[2] + tmp3/3.;
+if(MMG_caltet(mesh,sol,iel) > pt1->qual) {
+	printf("oups %d -- cal of %d ( %d ) %e > %e\n",nb,iel,ipa,pt1->qual,MMG_caltet(mesh,sol,iel)); 
+
+	//exit(0);
+	}
+else {
+//printf("%d -- cal of %d ( %d ) %e > %e\n",nb,iel,ipa,pt1->qual,MMG_caltet(mesh,sol,iel)); 
+}
+memcpy(ppa->c,oldc,3*sizeof(double));
+*/  
+      }
+/*for (l=1 ; l<=lon; l++) {
+  iel = list.tetra[l] >> 2;
+  nk  = list.tetra[l] % 4;
+  pt1 = &mesh->tetra[iel];
+
+  for (j=0; j<3; j++) {
+    ipb  = pt1->v[ MMG_idir[nk][j] ];
+    ppb  = &mesh->point[ipb]; 
+    ppb->mark = abs(ppb->mark);
+  }
+} */
+
+      if ( nb < 3 )  continue;
+      dd  = 1.0 / (double)nb;
+      cpx = cx*dd - ppa->c[0];
+      cpy = cy*dd - ppa->c[1];
+      cpz = cz*dd - ppa->c[2];
+
+      /* adjust position */
+      coe  = HQCOEF;
+      iter = 1; 
+      if(cal > 100./ALPHAD) {
+        ctg  = 0.99 * cal;  
+      } else {
+        ctg  = cal * HCRIT;   
+      }
+      memcpy(oldc,ppa->c,3*sizeof(double));
+      do {
+        ppa->c[0] =/* (1. - coe) * */oldc[0] + coe * cpx;
+        ppa->c[1] =/* (1. - coe) * */oldc[1] + coe * cpy;
+        ppa->c[2] =/* (1. - coe) * */oldc[2] + coe * cpz;
+
+        for (l=1; l<=lon; l++) {
+          iel = list.tetra[l] >> 2;
+          nk  = list.tetra[l] % 4;
+          pt1 = &mesh->tetra[iel];
+        
+          cal = MMG_caltet(mesh,sol,iel);
+          if ( cal > ctg )  break;
+          list.qual[l] = cal;
+        }
+        if ( l > lon )  break;
+        coe *= 0.5;
+      }
+      while ( ++iter <= maxtou );
+      if ( iter > maxtou ) {
+        memcpy(ppa->c,oldc,3*sizeof(double));
+	    ppa->flag = base - 2;   
+	    //if(k==154529) printf("cal(%d) %e %e %e\n",iel,cal,ctg,ctg/0.99);
+		/*exit(0);*/ nrj++;	
+        continue;
+      }
+
+      /* update tetra */
+      for (l=1; l<=lon; l++) {
+        iel = list.tetra[l] >> 2;
+        nk  = list.tetra[l] % 4;
+        pt1 = &mesh->tetra[iel];
+        pt1->qual = list.qual[l];
+        pt1->flag = base;
+	    for(i=0; i<4; i++)  mesh->point[pt1->v[i]].flag = base; 
+        //if(iel==154529) printf("on a traite %d (%d) %e %d\n",iel,k,pt1->qual,iter);
+
+        if ( pt1->qual < declic )
+          MMG_kiudel(queue,iel);
+        else if ( coe > 0.1 )
+          MMG_kiuput(queue,iel);
+      }
+
+      /* interpol metric */
+      ppa->flag = base + 1;
+      nm++;
+      break;
+    }
+  }
+  while ( k );
+
+  if ( mesh->info.imprim < - 4 )
+    fprintf(stdout,"     %7d PROPOSED  %7d MOVED %d REJ \n",npp,nm,nrj);
+
+  MMG_kiufree(queue);
+  return(nm);
+}
+
+/* optimise using heap : point position on normal*/
+int MMG_optlen_iso_new(pMesh mesh,pSol sol,double declic,int base) {
+  pTetra    pt,pt1;
+  pPoint    ppa,ppb,p1,p2,p3;
+  pQueue    queue;
+  List      list;
+  double    oldc[3],cal,ctg,cx,cy,cz,ux,uy,uz,cpx,cpy,cpz,coe,dd,len;
+  double    hb,hp,*ca,ax,ay,az,bx,by,bz,nx,ny,nz;
+  int       i,j,k,l,iel,lon,nm;
+  int       ipa,ipb,nb,nk,npp,iadr,iter,maxtou;
+int nrj,i1,i2,i3; 
+//double co1,co2,ddd;
+  /* queue on quality */
+  queue = MMG_kiuini(mesh,mesh->ne,declic,base - 1);
+  assert(queue);
+
+  maxtou = 3;
+  nm     = 0;
+  npp    = 0;
+nrj = 0;  
+  do {
+    k = MMG_kiupop(queue);
+    if ( !k )  break;
+    npp++;
+
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+   	//else if ( pt->flag != base - 1 ) continue;
+    
+    for (i=0; i<4; i++) {
+      ipa = pt->v[i];
+      ppa = &mesh->point[ipa];
+      if ( ppa->tag & M_BDRY )  continue;
+      //else if ( ppa->flag != base - 1 )  continue;
+
+      lon = MMG_boulep(mesh,k,i,&list);
+      if ( lon < 4 )  continue;
+
+      /* optimal point : length 1 sur la normal a la face*/
+      ca   = &ppa->c[0];
+      iadr = (ipa-1)*sol->offset + 1;
+      hp   = sol->met[iadr];
+      cx   = 0.0;
+      cy   = 0.0;
+      cz   = 0.0;
+      ux   = 0.0;
+      uy   = 0.0;
+      uz   = 0.0;
+      nb   = 0;
+      cal  = pt->qual;  
+      for (l=1 ; l<=lon; l++) {
+        iel = list.tetra[l] >> 2;
+        nk  = list.tetra[l] % 4;
+        pt1 = &mesh->tetra[iel];
+        if ( pt1->qual > cal )  cal = pt1->qual;
+	
+//printf("lon %d cal %e %e\n",kel,pt1->qual,MMG_caltet_iso(mesh,sol,iel));
+//printf("boule :   %d : %e %e %e\n",l,pt1->qual,pt1->qual*ALPHAD,MMG_rao(mesh,iel,0));
+				
+        /*compute normal*/
+        i1 = pt->v[MMG_idir[nk][0]];
+        i2 = pt->v[MMG_idir[nk][1]];
+        i3 = pt->v[MMG_idir[nk][2]];
+        p1 = &mesh->point[i1];
+        p2 = &mesh->point[i2];
+        p3 = &mesh->point[i3];
+  
+        ax = p3->c[0] - p1->c[0];
+        ay = p3->c[1] - p1->c[1];
+        az = p3->c[2] - p1->c[2];
+
+        bx = p2->c[0] - p1->c[0];
+        by = p2->c[1] - p1->c[1];
+        bz = p2->c[2] - p1->c[2];
+
+        nx = (ay*bz - az*by);
+        ny = (az*bx - ax*bz);
+        nz = (ax*by - ay*bx);
+    
+        dd = sqrt(nx*nx+ny*ny+nz*nz); 
+        dd = 1./dd;
+        nx *= dd;
+        ny *= dd;
+        nz *= dd; 
+
+		len = 0;
+        ux  = 0;
+        uy  = 0;
+        uz  = 0;
+        for (j=0; j<3; j++) {
+          ipb  = pt1->v[ MMG_idir[nk][j] ];
+          ppb  = &mesh->point[ipb];
+          iadr = (ipb-1)*sol->offset + 1;
+          hb   = sol->met[iadr];  
+          
+          ax  = ppb->c[0] - ppa->c[0];
+          ay  = ppb->c[1] - ppa->c[1];
+          az  = ppb->c[2] - ppa->c[2]; 
+          
+          /* centre de gravite de la face*/
+          ux += ppb->c[0];
+          uy += ppb->c[1];
+          uz += ppb->c[2];          
+
+          dd    =   sqrt(ax*ax +ay*ay +az*az);
+          len  +=   dd/hb;
+        }
+        dd  = 1.0 / (double)3.;
+        len *= dd; 
+        ux  *= dd;
+        uy  *= dd;
+        uz  *= dd;
+        if(len > 0.) len = 1.0 / len;
+        else printf("optlennew len %e\n",len);		
+       
+        /* optimal point */
+        cx += ux + nx * len;
+        cy += uy + ny * len;
+        cz += uz + nz * len;
+        nb++;        
+
+      }
+      if ( nb < 3 )  continue;
+      dd  = 1.0 / (double)nb;
+      cpx = cx*dd;
+      cpy = cy*dd;
+      cpz = cz*dd;
+
+      /* adjust position */
+      coe  = HQCOEF;
+      iter = 1;
+      if(cal > 100./ALPHAD) {
+        ctg  = 0.99 * cal;  
+      } else {
+        ctg  = cal * HCRIT;   
+      }
+      maxtou =  10;
+	  memcpy(oldc,ppa->c,3*sizeof(double));
+      do {
+        ppa->c[0] = (1. - coe) *oldc[0] + coe * cpx;
+        ppa->c[1] = (1. - coe) *oldc[1] + coe * cpy;
+        ppa->c[2] = (1. - coe) *oldc[2] + coe * cpz;
+
+        for (l=1; l<=lon; l++) {
+          iel = list.tetra[l] >> 2;
+          nk  = list.tetra[l] % 4;
+          pt1 = &mesh->tetra[iel];
+        
+          cal = MMG_caltet(mesh,sol,iel); 
+//printf("l %d cal %e %e\n",l,cal,MMG_rao(mesh,iel,0));
+          if ( cal > ctg )  break;
+          list.qual[l] = cal;
+        }
+        if ( l > lon )  break;
+		coe *= 0.5;
+      }
+      while ( ++iter <= maxtou );
+      if ( iter > maxtou ) {
+        memcpy(ppa->c,oldc,3*sizeof(double));
+	    ppa->flag = base - 2;   
+//printf("arg  cal %e %e %e\n",cal,ctg,ctg/0.98);  
+		nrj++;	
+        continue;
+      }
+
+      /* update tetra */
+      for (l=1; l<=lon; l++) {
+        iel = list.tetra[l] >> 2;
+        nk  = list.tetra[l] % 4;
+        pt1 = &mesh->tetra[iel];
+        pt1->qual = list.qual[l];
+        pt1->flag = base;
+	    for(i=0; i<4; i++)  mesh->point[pt1->v[i]].flag = base; 
+
+        if ( pt1->qual < declic )
+          MMG_kiudel(queue,iel);
+        else if ( coe > 0.1 )
+          MMG_kiuput(queue,iel);
+      }
+
+      /* interpol metric */
+      ppa->flag = base + 1;
+      nm++;
+      break;
+    }
+  }
+  while ( k );
+
+  if ( mesh->info.imprim < - 4 )
+    fprintf(stdout,"     %7d PROPOSED  %7d MOVED %d REJ \n",npp,nm,nrj);
+
+  MMG_kiufree(queue);
+  return(nm);
+}
diff --git a/contrib/mmg3d/build/sources/optlentet.c b/contrib/mmg3d/build/sources/optlentet.c
new file mode 100644
index 0000000000000000000000000000000000000000..380ed42c2f2dbcf14722cd9d2de90765f7d3f039
--- /dev/null
+++ b/contrib/mmg3d/build/sources/optlentet.c
@@ -0,0 +1,349 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+#define  HQCOEF    0.45
+#define  HCRIT     0.8
+
+
+int MMG_optlentet_ani(pMesh mesh,pSol sol,pQueue queue,double declic,int base,int k) {
+  pTetra    pt,pt1;
+  pPoint    ppa,ppb;
+  List      list;
+  double    cal,ctg,cx,cy,cz,ux,uy,uz,cpx,cpy,cpz,coe;
+  double    oldc[3],dd,dd1,dd2,len,lmi,lma;
+  double    *mp,*mb;
+  int       i,j,l,iel,lon;
+  int       ipa,ipb,nb,nk,iadr,iter,maxtou;
+
+  pt = &mesh->tetra[k];
+  if ( !pt->v[0] )  return(0);
+
+
+  maxtou = 2;
+
+  for (i=0; i<4; i++) {
+    ipa = pt->v[i];
+    ppa = &mesh->point[ipa];
+    if ( ppa->tag & M_BDRY )  continue;
+    else if ( ppa->flag > mesh->flag )  continue;
+
+    lon = MMG_boulep(mesh,k,i,&list);
+    if ( lon < 4 )  continue;
+
+    /* optimal point */
+    iadr = (ipa-1)*sol->offset + 1;
+    mp   = &sol->met[iadr];
+    cx  = 0.0;
+    cy  = 0.0;
+    cz  = 0.0;
+    nb  = 0;
+    cal = pt->qual;
+    lmi = LSHORT;
+    lma = LLONG;
+    for (l=1; l<=lon; l++) {
+      iel = list.tetra[l] >> 2;
+      nk  = list.tetra[l] % 4;
+      pt1 = &mesh->tetra[iel];
+      if ( pt1->qual > cal )  cal = pt1->qual;
+
+      for (j=0; j<3; j++) {
+  	ipb = pt1->v[ MMG_idir[nk][j] ];
+  	ppb = &mesh->point[ipb];
+
+  	iadr = (ipb-1)*sol->offset + 1;
+  	mb   = &sol->met[iadr];
+
+  	ux  = ppb->c[0] - ppa->c[0];
+  	uy  = ppb->c[1] - ppa->c[1];
+  	uz  = ppb->c[2] - ppa->c[2];
+
+  	dd1 =	   mp[0]*ux*ux + mp[3]*uy*uy + mp[5]*uz*uz \
+  	    + 2.0*(mp[1]*ux*uy + mp[2]*ux*uz + mp[4]*uy*uz);
+  	
+  	dd2 =	   mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \
+  	    + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz);
+  	len = 0.5*(dd1+dd2);
+  	if ( len < lmi )      lmi = len;
+  	else if (len > lma )  lma = len;
+
+  	/* optimal point */
+  	len = 1.0 / sqrt(dd1);
+  	cx += ppa->c[0] + ux * len;
+  	cy += ppa->c[1] + uy * len;
+  	cz += ppa->c[2] + uz * len;
+  	nb++;
+      }
+    }
+    if ( nb < 3 )  continue;
+    dd  = 1.0 / (double)nb;
+    cpx = cx*dd - ppa->c[0];
+    cpy = cy*dd - ppa->c[1];
+    cpz = cz*dd - ppa->c[2];
+
+    /* adjust position */
+    coe  = HQCOEF;
+    iter = 1;
+    if ( cal > 10.0 / ALPHAD )
+      ctg = cal * HCRIT;
+    else if ( cal > 5.0 / ALPHAD )
+      ctg = cal * 0.95;
+    else
+      ctg = cal * 0.975;
+    memcpy(oldc,ppa->c,3*sizeof(double));
+
+    do {
+      ppa->c[0] = oldc[0] + coe * cpx;
+      ppa->c[1] = oldc[1] + coe * cpy;
+      ppa->c[2] = oldc[2] + coe * cpz;
+
+      for (l=1; l<=lon; l++) {
+  	iel = list.tetra[l] >> 2;
+  	nk  = list.tetra[l] % 4;
+  	pt1 = &mesh->tetra[iel];
+
+  	cal = MMG_caltet(mesh,sol,iel);
+  	if ( cal > ctg )  break;
+  	list.qual[l] = cal;
+
+  	/* check length */
+  	for (j=0; j<3; j++) {
+  	  ipb = pt1->v[ MMG_idir[nk][j] ];
+  	  ppb = &mesh->point[ipb];
+
+  	  iadr = (ipb-1)*sol->offset + 1;
+  	  mb   = &sol->met[iadr];
+
+  	  ux  = ppb->c[0] - ppa->c[0];
+  	  uy  = ppb->c[1] - ppa->c[1];
+  	  uz  = ppb->c[2] - ppa->c[2];
+
+  	  dd1 =      mp[0]*ux*ux + mp[3]*uy*uy + mp[5]*uz*uz \
+  	      + 2.0*(mp[1]*ux*uy + mp[2]*ux*uz + mp[4]*uy*uz);
+  	
+  	  dd2 =      mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \
+  	      + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz);
+  	  len = 0.5*(dd1+dd2);
+
+  	  if ( len < lmi || len > lma )  break;
+  	}
+  	if ( j < 3 )  break;
+      }
+      if ( l > lon )  break;
+      coe *= 0.5;
+    }
+    while ( ++iter <= maxtou );
+    if ( iter > maxtou ) {
+      memcpy(ppa->c,oldc,3*sizeof(double));
+      continue;
+    }
+
+    /* update tetra */
+    for (l=1; l<=lon; l++) {
+      iel = list.tetra[l] >> 2;
+      nk  = list.tetra[l] % 4;
+      pt1 = &mesh->tetra[iel];
+      pt1->qual = list.qual[l]; 
+      pt1->flag = mesh->flag;
+      if ( pt1->qual < declic )
+  	MMG_kiudel(queue,iel);
+      else 
+  	MMG_kiuput(queue,iel); 
+    }
+
+    /* interpol metric */
+    ppa->flag = mesh->flag + 1;
+    break;
+  }
+  
+  
+  if(i!=4) return(1);
+  
+  return(0);
+}
+
+
+int MMG_optlentet_iso(pMesh mesh,pSol sol,pQueue queue,double declic,int base,int k) {
+  pTetra    pt,pt1;
+  pPoint    ppa,ppb;
+  List      list;
+  double    cal,ctg,cx,cy,cz,ux,uy,uz,cpx,cpy,cpz,coe;
+  double    oldc[3],dd,len,lmi,lma,*ca,*cb,hp,hb;
+  int       i,j,l,iel,lon;
+  int       ipa,ipb,nb,nk,iadr,iter,maxtou;
+
+  pt = &mesh->tetra[k];
+  if ( !pt->v[0] )  return(0);
+  maxtou = 5;
+
+  for (i=0; i<4; i++) {
+    ipa = pt->v[i];
+    ppa = &mesh->point[ipa];
+    if ( ppa->tag & M_BDRY )  continue;
+    else if ( ppa->flag > mesh->flag )  continue;
+
+    lon = MMG_boulep(mesh,k,i,&list);
+    if ( lon < 4 )  continue;
+     
+    /* optimal point */
+    ca   = &ppa->c[0];
+    iadr = (ipa-1)*sol->offset + 1;
+    hp   = sol->met[iadr];
+    cx   = 0.0;
+    cy   = 0.0;
+    cz   = 0.0;
+    nb   = 0;
+    cal  = pt->qual;
+    lmi  = 0.6; //LSHORT;
+    lma  = 1.4; //LLONG;
+    for (l=1; l<=lon; l++) {
+      iel = list.tetra[l] >> 2;
+      nk  = list.tetra[l] % 4;
+      pt1 = &mesh->tetra[iel];
+      if ( pt1->qual > cal )  cal = pt1->qual;
+
+      for (j=0; j<3; j++) {
+    	ipb  = pt1->v[ MMG_idir[nk][j] ];
+    	ppb  = &mesh->point[ipb];
+    	iadr = (ipb-1)*sol->offset + 1;
+    	hb   = sol->met[iadr];
+        cb   = &ppb->c[0]; 
+    	len  = MMG_length(ca,cb,&hp,&hb);
+        if ( len < lmi )       lmi = len;
+    	else if ( len > lma )  lma = len;
+
+        /* optimal point */
+        ux  = cb[0] - ca[0];
+    	uy  = cb[1] - ca[1];
+    	uz  = cb[2] - ca[2];
+
+        len = 1.0 / len;
+    	cx += ca[0] + ux * len;
+    	cy += ca[1] + uy * len;
+    	cz += ca[2] + uz * len;
+    	nb++;
+      }
+    }
+    if ( nb < 3 )  continue;
+    dd  = 1.0 / (double)nb;
+    cpx = cx*dd - ca[0];
+    cpy = cy*dd - ca[1];
+    cpz = cz*dd - ca[2];
+
+    /* adjust position */
+    coe  = HQCOEF;
+    iter = 1;
+    if ( cal > 10.0 / ALPHAD )
+      ctg = cal * HCRIT;
+    else if ( cal > 5.0 / ALPHAD )
+      ctg = cal * 0.95;
+    else
+      ctg = cal * 0.9975;
+    memcpy(oldc,ppa->c,3*sizeof(double));
+
+    do {
+      ca[0] = oldc[0] + coe * cpx;
+      ca[1] = oldc[1] + coe * cpy;
+      ca[2] = oldc[2] + coe * cpz;
+
+      for (l=1; l<=lon; l++) {
+    	iel = list.tetra[l] >> 2;
+    	nk  = list.tetra[l] % 4;
+    	pt1 = &mesh->tetra[iel];
+      
+    	cal = MMG_caltet(mesh,sol,iel);
+    	if ( cal > ctg )  break;
+    	list.qual[l] = cal;
+
+    	/* check length */
+    	for (j=0; j<3; j++) {
+    	  ipb = pt1->v[ MMG_idir[nk][j] ];
+    	  ppb = &mesh->point[ipb];
+          cb  = &ppb->c[0];
+	   
+    	  iadr = (ipb-1)*sol->offset + 1;
+    	  hb   = sol->met[iadr];
+          len  = MMG_length(ca,cb,&hp,&hb);
+          if ( len < lmi || len > lma ) {
+            break;
+    	  }
+        }
+    	if ( j < 3 )  break;
+      }
+      if ( l > lon )  break;
+      coe *= 0.5;
+    }
+    while ( ++iter <= maxtou );
+    if ( iter > maxtou ) {
+      memcpy(ppa->c,oldc,3*sizeof(double));
+      continue;
+    }
+
+    /* update tetra */
+    for (l=1; l<=lon; l++) {
+      iel = list.tetra[l] >> 2;
+      nk  = list.tetra[l] % 4;
+      pt1 = &mesh->tetra[iel];
+      pt1->qual = list.qual[l];
+      pt1->flag = mesh->flag;
+
+      if ( pt1->qual < declic )
+    	MMG_kiudel(queue,iel);
+      else 
+    	MMG_kiuput(queue,iel);
+    }
+
+
+    /* interpol metric */
+    ppa->flag = mesh->flag + 1;
+    break;
+  }
+  
+  
+  if(i!=4) return(1);
+  
+  return(0);
+}
diff --git a/contrib/mmg3d/build/sources/optra4.c b/contrib/mmg3d/build/sources/optra4.c
new file mode 100644
index 0000000000000000000000000000000000000000..0b0a6650674281ed80e35946f43bb112f482fdc1
--- /dev/null
+++ b/contrib/mmg3d/build/sources/optra4.c
@@ -0,0 +1,106 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+int MMG_pretreat(pMesh ,pSol ,double ,int *);
+
+int MMG_optra4(pMesh mesh,pSol sol) {
+  double	declicw;
+  double	declic;
+  int		base,nm,ns,it,maxtou,alert,nw,nwold,k;
+  
+  /* optim coquil */
+  alert  = 0;
+  maxtou = 20;//0;
+  it     = 0;
+  
+  MMG_caltet = ( sol->offset==6 ) ? MMG_caltet_ani:MMG_caltet_iso;
+  MMG_caltet2 = ( sol->offset==6 ) ? MMG_caltet2_ani:MMG_caltet2_iso;
+    
+  for (k=1; k<=mesh->ne; k++) {
+    mesh->tetra[k].flag = mesh->flag;
+    mesh->tetra[k].qual = MMG_caltet(mesh,sol,k);
+  }
+  for (k=1; k<=mesh->np; k++) mesh->point[k].flag = mesh->flag;
+  declicw = 5./ALPHAD;
+  declic  = 1.5/ ALPHAD;
+            
+  do {
+    base = ++mesh->flag;
+//MMG_ratio(mesh,sol,NULL); 
+    ns = 0;
+    if ( !alert && !mesh->info.noswap ) {
+        ns = MMG_cendel(mesh,sol,declic,base);
+      if ( ns < 0 ) {
+        alert = 1;
+    	ns    = -ns;
+      }
+    }
+    nw = 0;
+    /*if (!mesh->info.noinsert)  nw = MMG_pretreat(mesh,sol,declicw,&alert);
+    */
+    /*sur des surfaces courbes, il existe des tetras ayant  4 points de peau avec Q=3*/
+    if ( it < 10 )  {
+      nwold = nw;
+      nw += MMG_opttyp(mesh,sol,declicw,&alert);
+	  declicw *= 1.05;
+         
+    }
+	nm = 0;    
+    if (!mesh->info.nomove) {          
+        nm = MMG_optlen(mesh,sol,declic,base);  
+    }
+    
+    //if(!mesh->info.nomove && it<2) MMG_optlap(mesh,sol);
+    if ( mesh->info.imprim && nw+ns+nm )
+      fprintf(stdout,"     %8d IMPROVED  %8d SWAPPED  %8d MOVED\n",nw,ns,nm);     
+    }
+  //while ( (ns && ((ns > 0.005*mesh->ne /*&& nwold > nw*/) || it < 5)) && ++it < maxtou );
+  while ( ns+nm && ++it < maxtou );
+ 
+  return(1);
+}
+
diff --git a/contrib/mmg3d/build/sources/opttet.c b/contrib/mmg3d/build/sources/opttet.c
new file mode 100644
index 0000000000000000000000000000000000000000..eabe29da115cf986b2cf3c241f0d4e74fbd48004
--- /dev/null
+++ b/contrib/mmg3d/build/sources/opttet.c
@@ -0,0 +1,133 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+int    MMG_swaptet(pMesh mesh,pSol sol,pQueue queue, double declic,int iel);
+
+int MMG_opttet(pMesh mesh,pSol sol) {
+  pQueue     queue;
+  double    declic;
+  int      base,nm,ns,it,maxtou,alert,ier,k;
+double worst;
+double declicw;
+int iterworst,nw;
+  worst = 1e20;
+
+
+
+  /* optim tet */
+  alert = 0;
+  declic = 1.7 / ALPHAD; //ALPHAD cte pour qualite interne
+  maxtou = 10;
+  base   = -1;
+  it     = 0;
+
+  do {
+   ns = 0;
+   nm = 0;
+   
+   iterworst = 0;
+   nw = 0;
+   declicw = 9./ALPHAD;
+   do {
+//printf("--------------- iter %d : declicw %e\n",iterworst,declicw*ALPHAD);
+//MMG_outqua(mesh,sol);
+     if (!mesh->info.noswap) 
+     	nw = MMG_opttyp(mesh,sol,declicw,&alert);
+   } while((iterworst++ < 0) && nw);
+   MMG_outqua(mesh,sol);
+   puts("  ");
+   
+   worst = MMG_priworst(mesh,sol);
+   
+   /* queueing tetrahedra */
+   queue = MMG_kiuini(mesh,mesh->ne,declic,base);
+   assert(queue);
+   mesh->flag++;
+   do {
+     k = MMG_kiupop(queue);
+     if ( !k )  break;
+     /*try MMG_swap*/
+     ier = 0;
+     if((!mesh->info.noswap)) ier = MMG_swaptet(mesh,sol,queue,declic,k);
+     if(ier < 0) {
+       alert = 1;
+     } else if(ier) {
+       ns++;
+       continue;
+     }
+     
+     /*try move*/
+     if(MMG_optlentet(mesh,sol,queue,declic,base,k)) {
+       nm++;
+       continue;
+     } 
+     
+     }
+   while ( k );
+    
+   MMG_kiufree(queue);
+   base = ++mesh->flag;
+
+   if ( mesh->info.imprim && nm+ns )
+     fprintf(stdout,"     %8d MOVED  %8d SWAPPED\n",nm,ns);
+  }
+  while ( nm > 0.01*mesh->np && ++it < maxtou );
+
+printf("------------------------ on est arrive a maxtou ?: %d %d\n",it,maxtou);
+   worst = MMG_priworst(mesh,sol);
+
+// #warning A ENLEVER
+//   for(it=1 ; it<=mesh->ne ; it++) {
+//     pt = &mesh->tetra[it];
+//     if(pt->qual < declic) continue;
+//     pt->ref = ALPHAD*pt->qual;
+//   } 
+
+  return(1);
+}
+
+    
diff --git a/contrib/mmg3d/build/sources/opttyp.c b/contrib/mmg3d/build/sources/opttyp.c
new file mode 100644
index 0000000000000000000000000000000000000000..f1c9a5e138d6b34e114d203f54e51bc21730e944
--- /dev/null
+++ b/contrib/mmg3d/build/sources/opttyp.c
@@ -0,0 +1,821 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+#define OCRIT    0.99
+#undef  QDEGRAD
+#define QDEGRAD 2.
+
+int MMG_colpoi2(pMesh mesh,pSol sol,int iel,int ia,int ib,double coef);
+
+/* optimize mesh quality based on element type */
+int MMG_opttyp(pMesh mesh,pSol sol,double declic,int *alert) {
+  pTetra     pt,pt1;
+  pPoint     pa,pb;
+  List       list;
+  pQueue     queue;
+  double      crit;
+  double     len,*ca,*cb,*ma,*mb;
+  int       *adja,i,k,l,iar,ia,ib,iel,iadr,ier,item[2],nd,base,ityp,np;
+  int        npeau,cs[10],ds[10],dsb[3],lon,sombdry,dpeau;
+  int        ipa,ipb,iarmin,iarmax,ndd,nbt,j;
+double LLONG2;
+
+  /*classification des mauvais : 0 si pas sur la peau*/
+  /*				 1 si au moins une face de peau */
+  /*				 2 si au moins une arete sur la peau */
+  if(mesh->info.imprim < -5 ) {
+    puts("  ");
+ 
+    nd = 0;
+    memset(cs,0,10*sizeof(int)); 
+    memset(ds,0,10*sizeof(int));
+    nbt = 0;
+    for(k=1 ; k<=mesh->ne ; k++) {
+      pt = &mesh->tetra[k];
+//if(k== 40117) printf("tetra %d %e : %d %d %d %d\n",k,pt->qual*ALPHAD,pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
+      if(!pt->v[0] || pt->qual < declic) continue;
+      nbt++;
+//if(k== 40117) printf("tetra %d %e : %d %d %d %d\n",k,pt->qual*ALPHAD,pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
+   
+      iadr = 4*(k-1) + 1;
+      adja = &mesh->adja[iadr];
+      for(i=0 ; i<4 ; i++) {
+        if(!adja[i])break;     
+      }
+      if(i==4) {
+         for(i = 0 ; i<6 ; i++) 
+           if(!MMG_coquil(mesh,k,i,&list)) break;
+
+         if ( i==6 )  cs[0]++;
+         else cs[2]++;
+      } else cs[1]++;
+    }
+
+    printf("  tetra interne        = %5d / %5d  %6.2f %%\n",cs[0],nbt,100.0*cs[0]/nbt);
+    printf("  tetra face peau      = %5d / %5d  %6.2f %%\n",cs[1],nbt,100.0*cs[1]/nbt);
+    printf("  tetra arete peau     = %5d / %5d  %6.2f %%\n",cs[2],nbt,100.0*cs[2]/nbt);
+  
+    printf("\n");
+  
+  }
+  
+  
+  /*traitement des mauvais*/
+  base  = mesh->flag;
+  ier   = 0;
+  queue = MMG_kiuini(mesh,mesh->nemax,declic,base - 1);
+  assert(queue);
+
+  memset(cs,0,10*sizeof(int)); 
+  memset(ds,0,10*sizeof(int));
+  memset(dsb,0,3*sizeof(int));
+  nd   = 0;
+
+  if ( !MMG_zaldy4(&list.hedg,3*LONMAX) ) {
+    fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM MMG_OPTTYP.\n");
+    MMG_kiufree(queue);
+    return(0);
+  }
+
+  np = 0;
+  do {
+    k = MMG_kiupop(queue);
+    if ( !k )  break;
+    np++;
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+    else if ( pt->qual < declic )  continue;
+	  else if ( pt->flag != base - 1 ) continue;
+	
+    LLONG2 = 0.1;
+
+    crit = pt->qual * OCRIT;
+    ityp = MMG_typelt(mesh,k,item);
+cs[ityp]++;
+//if(k==175494) printf("tetra %d (%d) %e : %d %d %d %d\n",k,ityp,pt->qual*ALPHAD,pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
+    iadr = 4*(k-1) + 1;
+    adja = &mesh->adja[iadr];
+    /*optim bdry tetra*/
+    npeau = 0;
+    for(i=0 ; i<4 ; i++) {
+      if(!adja[i])npeau++;     
+    }
+      
+    if(npeau>1 && !mesh->info.noswap) {
+      if(mesh->info.imprim<-4) printf("%d faces de peau!!!! %d (typ %d) %e\n",npeau,k,ityp,pt->qual * ALPHAD);
+      dsb[0]++;
+      if(MMG_opt2peau(mesh,sol,queue,k,declic)){ 
+        nd++; 
+        continue;
+      }
+    }  
+    if(npeau) {       
+      dpeau = MMG_optbdry(mesh,sol,k);
+      dsb[dpeau]++;
+      if(dpeau) { 
+        nd++;
+        ds[ityp]++;
+	    continue;
+      }
+    } 
+    if(mesh->info.noswap) continue;
+    switch(ityp) {
+    case 1:  /* sliver */
+      iar = item[0];
+      lon = MMG_coquil(mesh,k,iar,&list);
+      if ( lon > 2 ) {
+        crit = pt->qual;
+        for (l=2; l<=lon; l++) {
+          iel = list.tetra[l] / 6;
+          pt1 = &mesh->tetra[iel];
+          if ( pt1->qual > crit )  crit = pt1->qual;
+        }
+        /*impossible de dégrader à cause des swap 4-4*/
+        crit *= OCRIT;
+	    ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,declic);
+        if ( ier == 0 && !mesh->info.noinsert) {
+		  if ( MMG_voltet(mesh,k) < 5.e-9 ) {
+		    crit *= 2.;
+		    crit = M_MIN(crit,8e+8);
+		  } 
+          ia  = MMG_iare[iar][0];
+          ib  = MMG_iare[iar][1];
+          ipa = pt->v[ia];
+          ipb = pt->v[ib];
+          ca  = &mesh->point[ipa].c[0];
+          cb  = &mesh->point[ipb].c[0];
+          
+	      iadr = (ipa-1)*sol->offset + 1;
+          ma   = &sol->met[iadr];
+          iadr = (ipb-1)*sol->offset + 1;
+          mb   = &sol->met[iadr];
+	  
+	      len = MMG_length(ca,cb,ma,mb);
+	      if(len > LLONG2)
+	        ier = MMG_spledg(mesh,sol,queue,&list,lon,crit,declic);
+	      
+	      if ( ier ) {
+   	        pt1  = &mesh->tetra[mesh->point[ier].tmp];  
+		    for(j=0 ; j<4 ; j++) {
+		      if(pt1->v[j] == ier) break;	
+		    }
+		    assert(j<4);
+            ier = MMG_movevertex(mesh,sol,mesh->point[ier].tmp,j);
+		    if ( ier==1 ) {
+		    } else {
+		      ier = 1;
+		    }
+	      }
+	    }
+	    if ( ier > 0 ) {
+           nd++;
+          ds[1]++;
+          break;
+        }
+	    else if ( ier < 0 ) {
+	      *alert = 1;
+	      break;
+	    }
+      }
+      for(i=0 ; i<6 ; i++) {
+      	if(i==item[0]) continue;
+        lon = MMG_coquil(mesh,k,i,&list);
+        if ( lon > 2 ) {
+          crit = pt->qual;
+          for (l=2; l<=lon; l++) {
+            iel = list.tetra[l] / 6;
+            pt1 = &mesh->tetra[iel];
+            if ( pt1->qual > crit )  crit = pt1->qual;
+          }
+          crit *= OCRIT;
+          
+          ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,declic);
+
+	      if ( ier == 0 && !mesh->info.noinsert) {
+           	/*if ( MMG_voltet(mesh,k) < 5.e-9 ) {     //degrade trop les maillages!!!
+			  crit *= 2.;
+			  crit = M_MIN(crit,8e+8);
+			} */
+		    ia  = MMG_iare[i][0];
+            ib  = MMG_iare[i][1];
+            ipa = pt->v[ia];
+            ipb = pt->v[ib];
+            ca  = &mesh->point[ipa].c[0];
+            cb  = &mesh->point[ipb].c[0];
+          
+	        iadr = (ipa-1)*sol->offset + 1;
+            ma   = &sol->met[iadr];
+            iadr = (ipb-1)*sol->offset + 1;
+            mb   = &sol->met[iadr];
+	  
+	        len = MMG_length(ca,cb,ma,mb);
+	        if(len > LLONG2)
+	          ier = MMG_spledg(mesh,sol,queue,&list,lon,crit,declic);	  
+	        
+	        if ( ier ) {
+		      pt1  = &mesh->tetra[mesh->point[ier].tmp];
+		      for(j=0 ; j<4 ; j++) {
+		        if(pt1->v[j] == ier) break;	
+		      }
+		      assert(j<4);
+			  ier = MMG_movevertex(mesh,sol,mesh->point[ier].tmp,j);
+		      if ( ier==1 ) {
+		      } else {
+				ier = 1;
+		      }
+		    } /*end if ier for movevertex*/         
+          } /*end if ier == 0 */
+	  
+	      if ( ier > 0 ) {
+            nd++;
+            ds[1]++;
+	        break;
+          }
+	      else if ( ier < 0 )
+	        *alert = 1; 
+        } /*end if lon==2*/
+      } /*end for i*/
+      if(i<6) break;
+      /*move vertex*/
+      for(i=0 ; i<4 ; i++) {
+        if(MMG_movevertex(mesh,sol,k,i)) {
+          nd++;
+	      ds[ityp]++;
+	      break;
+        }	  
+      }
+      break;
+
+    case 2:  /* chapeau */
+      /*on essaie de decoller le point de l'arete*/
+      iar = item[0];
+      if((sol->offset!=1) && MMG_movevertex(mesh,sol,k,iar)) {
+        nd++;
+	ds[ityp]++;
+      } else {
+        for(i=0 ; i<4 ; i++) {
+	  if(iar==i) continue;
+          if((sol->offset!=1) && MMG_movevertex(mesh,sol,k,i)) {
+            nd++;
+	    ds[ityp]++;
+	    break;
+          }	  
+	}
+      }
+      break;
+
+    case 3:  /* aileron */
+      iar = item[1];
+      ier = MMG_simu23(mesh,sol,k,iar,crit);
+      if ( ier > 0 ) {
+       	MMG_swap23(mesh,sol,queue,k,iar,crit);
+	nd++;
+        ds[ityp]++;
+	break;
+      }
+      else if ( ier < 0 ) {
+	*alert = 1;
+	break;
+      }
+
+      iar = item[0];
+      lon = MMG_coquil(mesh,k,iar,&list);
+//if(!lon) printf("arete de bord!!!!!!!!!!!!!\n");
+      if ( lon > 2 ) {
+        crit = pt->qual;
+        for (l=2; l<=lon; l++) {
+          iel = list.tetra[l] / 6;
+          pt1 = &mesh->tetra[iel];
+          if ( pt1->qual > crit )  crit = pt1->qual;
+        }
+        crit *= OCRIT;
+        ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,declic);
+	if ( ier == 0 && !mesh->info.noinsert) {
+          ia  = MMG_iare[iar][0];
+          ib  = MMG_iare[iar][1];
+          ipa = pt->v[ia];
+          ipb = pt->v[ib];
+          ca  = &mesh->point[ipa].c[0];
+          cb  = &mesh->point[ipb].c[0];
+          
+	  iadr = (ipa-1)*sol->offset + 1;
+          ma   = &sol->met[iadr];
+          iadr = (ipb-1)*sol->offset + 1;
+          mb   = &sol->met[iadr];
+	  
+	  len = MMG_length(ca,cb,ma,mb);
+	  if(len > LLONG2)
+	    ier = MMG_spledg(mesh,sol,queue,&list,lon,crit,declic);
+	  
+	}
+ 	if ( ier > 0 ) {
+          nd++;
+          ds[3]++;
+        }
+	else if ( ier < 0 )
+	  *alert = 1;
+      }
+      
+      if(ier) break;
+      
+//       /*try collapse one edge*/
+//       iar = item[0];
+//       for(i=0 ; i<6 ; i++) {
+// 	ia = MMG_iare[i][0];
+// 	ib = MMG_iare[i][1];
+// 	ipa = pt->v[ia];
+// 	ipb = pt->v[ib];
+//         if(MMG_colpoi2(mesh,sol,k,ia,ib,QDEGRAD)) {
+//          MMG_delPt(mesh,ipb);
+// 	  //printf("1 : on a reussi a supprimer le tetra mauvais \n");
+//           break;
+//         } else if(MMG_colpoi2(mesh,sol,k,ib,ia,QDEGRAD)) {
+//           MMG_delPt(mesh,ipa);
+// 	  //printf("2 : on a reussi a supprimer le tetra mauvais\n");
+//           break;
+//         }
+// 	
+//       }
+
+      /*move vertex*/
+      for(i=0 ; i<4 ; i++) {
+        if(MMG_movevertex(mesh,sol,k,i)) {
+          nd++;
+	  ds[ityp]++;
+	  break;
+        }	  
+      }
+
+      break;
+
+    case 4:  /* berlingot */
+      iar = item[0];
+      ia  = MMG_iare[iar][0];
+      ib  = MMG_iare[iar][1];
+      ipa = pt->v[ia];
+      ipb = pt->v[ib];
+      pa  = &mesh->point[ipa];
+      pb  = &mesh->point[ipb];
+      if ( !mesh->info.noinsert && !(pb->tag & M_BDRY) && MMG_colpoi2(mesh,sol,k,ia,ib,QDEGRAD) ) {
+        nd++;
+        MMG_delPt(mesh,ipb);
+        ds[ityp]++;
+        break;
+      } 
+      else if( !mesh->info.noinsert && !(pa->tag & M_BDRY) && MMG_colpoi2(mesh,sol,k,ib,ia,QDEGRAD) ) {
+        nd++;
+        MMG_delPt(mesh,ipa);
+        ds[ityp]++;
+        break; 
+      }
+      if( (sol->offset!=1) && !(pb->tag & M_BDRY)) {
+        if(MMG_movevertex(mesh,sol,k,ib)) {
+	  nd++;
+	  ds[ityp]++;
+	  break;
+	}
+      }	
+      if( (sol->offset!=1) && !(pa->tag & M_BDRY)) {
+        if(MMG_movevertex(mesh,sol,k,ia)) {
+	  nd++;
+	  ds[ityp]++;
+	  break;
+	}
+      }	
+
+      break;
+
+    case 5:  /* 0 good face: split largest edge + node move */
+      break;
+
+    case 6:  /* O good face: move away closest vertices */
+      /*collapse item[0]*/
+      ier = 0;
+      iar = item[0];
+      ia  = MMG_iare[iar][0];
+      ib  = MMG_iare[iar][1];
+      ipa = pt->v[ia];
+      ipb = pt->v[ib];
+      ca  = &mesh->point[ipa].c[0];
+      cb  = &mesh->point[ipb].c[0];
+      iadr = (ipa-1)*sol->offset + 1;
+      ma  = &sol->met[iadr];
+      iadr = (ipb-1)*sol->offset + 1;
+      mb  = &sol->met[iadr];
+      if ( (MMG_length(ca,cb,ma,mb) < LSHORT) ) {
+        pa  = &mesh->point[ipa];
+        pb  = &mesh->point[ipb];
+        if ( !mesh->info.noinsert && !(pb->tag & M_BDRY) && MMG_colpoi2(mesh,sol,k,ia,ib,QDEGRAD) ) {
+          ier = 2;
+	  nd++;
+          MMG_delPt(mesh,ipb);
+          ds[ityp]++;
+          break;
+        } 
+        else if( !mesh->info.noinsert && !(pa->tag & M_BDRY) && MMG_colpoi2(mesh,sol,k,ib,ia,QDEGRAD) ) {
+          ier = 2;
+	  nd++;
+          MMG_delPt(mesh,ipa);
+          ds[ityp]++;
+          break; 
+        }
+      }
+       
+      /*split item[1]*/
+      iar = item[1];
+      lon = MMG_coquil(mesh,k,iar,&list);
+      if ( lon <= 2 ) break;
+      
+      crit = pt->qual;
+      for (l=2; l<=lon; l++) {
+        iel = list.tetra[l] / 6;
+        pt1 = &mesh->tetra[iel];
+        if ( pt1->qual > crit )  crit = pt1->qual;
+      }  
+      crit *= OCRIT;
+      ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,declic);
+      if ( ier == 0 && !mesh->info.noinsert) {
+          ia  = MMG_iare[iar][0];
+          ib  = MMG_iare[iar][1];
+          ipa = pt->v[ia];
+          ipb = pt->v[ib];
+          ca  = &mesh->point[ipa].c[0];
+          cb  = &mesh->point[ipb].c[0];
+          
+	  iadr = (ipa-1)*sol->offset + 1;
+          ma   = &sol->met[iadr];
+          iadr = (ipb-1)*sol->offset + 1;
+          mb   = &sol->met[iadr];
+	  
+	  len = MMG_length(ca,cb,ma,mb);
+	  if(len > LLONG2)
+	    ier = MMG_spledg(mesh,sol,queue,&list,lon,crit,declic);
+      }
+      if ( ier > 0 ) {
+        nd++;
+        ds[ityp]++;
+        break;
+      }
+      else if ( ier < 0 ) {
+        *alert = 1;
+        break;
+      }        
+      break;
+    
+    case 7:
+      /*collapse d'une des 2 petites aretes*/
+      ier    = 0;
+      iarmin = item[0];
+      iarmax = item[1];
+      ia  = MMG_iare[iarmin][0];
+      ib  = MMG_iare[iarmin][1];
+      ipa = pt->v[ia];
+      ipb = pt->v[ib];
+      ca  = &mesh->point[ipa].c[0];
+      cb  = &mesh->point[ipb].c[0];
+      iadr = (ipa-1)*sol->offset + 1;
+      ma  = &sol->met[iadr];
+      iadr = (ipb-1)*sol->offset + 1;
+      mb  = &sol->met[iadr];
+
+      i = 6;
+      if(!mesh->info.noinsert && (MMG_length(ca,cb,ma,mb) < LSHORT)) {
+        pa  = &mesh->point[ipa];
+        pb  = &mesh->point[ipb];
+        if ( !(pb->tag & M_BDRY) && MMG_colpoi2(mesh,sol,k,ia,ib,QDEGRAD) ) {
+         ier = 2;
+	  nd++;
+          MMG_delPt(mesh,ipb);
+          ds[ityp]++;
+	  i = 0;
+          break;
+        } 
+        else if( !(pa->tag & M_BDRY) && MMG_colpoi2(mesh,sol,k,ib,ia,QDEGRAD) ) {
+          ier = 2;
+	  nd++;
+          MMG_delPt(mesh,ipa);
+          ds[ityp]++;
+	  i = 0;
+          break; 
+        }
+      }
+      if(ier) break;
+           
+      lon = MMG_coquil(mesh,k,iarmax,&list);
+      if ( lon <= 2 ) break;
+      if (!mesh->info.noinsert) {
+        lon = MMG_coquil(mesh,k,iarmax,&list);
+        if ( lon <= 2 ) break;
+        crit = pt->qual;
+        for (l=2; l<=lon; l++) {
+          iel = list.tetra[l] / 6;
+          pt1 = &mesh->tetra[iel];
+          if ( pt1->qual > crit )  crit = pt1->qual;
+        }  
+        crit *= OCRIT;
+
+        ia  = MMG_iare[iarmax][0];
+        ib  = MMG_iare[iarmax][1];
+        ipa = pt->v[ia];
+        ipb = pt->v[ib];
+        ca  = &mesh->point[ipa].c[0];
+        cb  = &mesh->point[ipb].c[0];
+        
+	iadr = (ipa-1)*sol->offset + 1;
+        ma   = &sol->met[iadr];
+        iadr = (ipb-1)*sol->offset + 1;
+        mb   = &sol->met[iadr];
+	
+	len = MMG_length(ca,cb,ma,mb);
+	if(len > LLONG2)
+	  ier = MMG_spledg(mesh,sol,queue,&list,lon,crit,declic);
+	
+	if ( ier > 0 ) {
+           nd++;
+          ds[ityp]++;
+          break;
+        }
+      }
+
+      /*boucle sur les autres aretes != de iarmax et de iarmin*/
+      for(i=0 ; i<6 ; i++) {
+        if(i==iarmin) continue;
+	if(i==iarmax) continue;
+        ia  = MMG_iare[i][0];
+        ib  = MMG_iare[i][1];
+        ipa = pt->v[ia];
+        ipb = pt->v[ib];
+	ca  = &mesh->point[ipa].c[0];
+        cb  = &mesh->point[ipb].c[0];
+        iadr = (ipa-1)*sol->offset + 1;
+        ma  = &sol->met[iadr];
+        iadr = (ipb-1)*sol->offset + 1;
+        mb  = &sol->met[iadr];
+
+        len = MMG_length(ca,cb,ma,mb);
+        if(!mesh->info.noinsert && (len < LSHORT)) {
+          pa  = &mesh->point[ipa];
+          pb  = &mesh->point[ipb];
+          if ( !(pb->tag & M_BDRY) && MMG_colpoi2(mesh,sol,k,ia,ib,QDEGRAD) ) {
+            ier = 3;
+	    nd++;
+            MMG_delPt(mesh,ipb);
+            ds[ityp]++;
+            break;
+          } 
+          else if( !(pa->tag & M_BDRY) && MMG_colpoi2(mesh,sol,k,ib,ia,QDEGRAD) ) {
+            ier = 3;
+	    nd++;
+            MMG_delPt(mesh,ipa);
+            ds[ityp]++;
+            break; 
+          }
+        } else if(!mesh->info.noinsert && (len > LLONG)) {
+          lon = MMG_coquil(mesh,k,i,&list);
+          if ( lon <= 2 ) break;
+          crit = pt->qual;
+          for (l=2; l<=lon; l++) {
+            iel = list.tetra[l] / 6;
+            pt1 = &mesh->tetra[iel];
+            if ( pt1->qual > crit )  crit = pt1->qual;
+          }  
+          crit *= OCRIT;
+          if (!mesh->info.noinsert)
+            ier = MMG_spledg(mesh,sol,queue,&list,lon,crit,declic);
+          if ( ier > 0 ) {
+             nd++;
+            ds[ityp]++;
+            break;
+          }
+	}
+      }
+      
+      if(i<6) break;
+      if(ier) break;
+      /*MMG_swap arete*/
+      for(i=0 ; i<6 ; i++) {
+	lon = MMG_coquil(mesh,k,i,&list);
+        if ( lon > 2 ) {
+	  crit = pt->qual;
+          for (l=2; l<=lon; l++) {
+            iel = list.tetra[l] / 6;
+            pt1 = &mesh->tetra[iel];
+            if ( pt1->qual > crit )  crit = pt1->qual;
+          }
+          crit *= OCRIT;
+          ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,declic);
+	  if(ier) {	    
+            nd++;
+            ds[ityp]++;
+	    break;
+	  }  
+        }
+      }
+            
+      break;
+    default:
+/*
+      for (i=0; i<4; i++) {
+        adj  = adja[i] >> 2;
+        if ( adj && pt->ref == mesh->tetra[adj].ref ) {
+          lon  = MMG_coquil(mesh,k,i,list);
+          if ( MMG_swapar(mesh,sol,queue,k,i,list,lon,declic) ) {
+            nsw++;
+ds[ityp]++;
+            break;
+          }
+        }
+      }
+*/
+      break;
+    }
+     
+  }
+  while ( k && *alert == 0 );
+
+  if(mesh->info.imprim<0) { 
+	
+    for (k=0; k<=7; k++)
+      if ( cs[k] )
+        printf("  optim [%d]      = %5d   %5d  %6.2f %%\n",k,cs[k],ds[k],100.0*ds[k]/cs[k]);
+
+    sombdry = dsb[0]+dsb[1]+dsb[2];
+    for (k=1; k<=2; k++)
+      if ( dsb[k] )
+        printf("\n  optim bdry [%d] = %5d   %5d  %6.2f %%\n",k,dsb[k],sombdry,100.0*dsb[k]/sombdry);
+    
+    printf(" PROP %d  TREATED %d\n",np,ds[0]+ds[1]+ds[2]+ds[3]+ds[4]+ds[5]+ds[6]+ds[7]);
+
+  }
+
+   M_free(list.hedg.item);
+   MMG_kiufree(queue);
+   
+   if (!mesh->info.noswap) {
+     base   = -1;
+     *alert = 0;
+     ndd     = MMG_cendel(mesh,sol,declic,base);
+     if ( mesh->info.imprim < 0 && ndd > 0 )
+       fprintf(stdout,"      %7d SWAPPED\n",ndd);
+     else if ( ndd < 0 )
+       *alert = 1;     
+   }
+
+
+
+ /* base  = -1;
+  ier   = 0;
+  queue = MMG_kiuini(mesh,mesh->nemax,declic,base);
+  assert(queue);
+
+  do {
+    k = MMG_kiupop(queue);
+    if ( !k )  break;
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+    else if ( pt->qual < declic )  continue;
+    
+    crit = M_MIN(2.*pt->qual,8e+8);
+    
+    for (i=0; i<4; i++) {
+      if(MMG_simu23(mesh,sol,k,i,crit)) {
+      printf("je swap\n");
+        MMG_swap23(mesh,sol,queue,k,i,1e+9);
+        break;
+      }
+    }
+
+  }
+  while ( k && *alert == 0 );
+  MMG_kiufree(queue);*/
+
+
+  return(nd);
+}
+
+
+/* insert point in bad tetra */
+int MMG_pretreat(pMesh mesh,pSol sol,double declic,int *alert) {
+  pTetra     pt,pt1;
+  List       list;
+  pQueue     queue;
+  double      crit;
+  double     len,*ca,*cb,*ma,*mb;
+  int        i,k,l,ia,ib,iel,ier,nd,base,wqual;
+  int        lon,iadr,ipa,ipb;
+
+  wqual = 30. / ALPHAD;
+
+  /*queue*/
+  base  = -1;
+  queue = MMG_kiuini(mesh,mesh->nemax,declic,base);
+  assert(queue);
+
+  nd   = 0;
+
+  if ( !MMG_zaldy4(&list.hedg,3*LONMAX) ) {
+    fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM MMG_OPTTYP.\n");
+    MMG_kiufree(queue);
+    return(0);
+  }
+
+  do {
+    k = MMG_kiupop(queue);
+    if ( !k )  break;
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+    else if ( pt->qual < declic )  continue;
+
+    crit = pt->qual * OCRIT;
+
+    for(i=0 ; i<6 ; i++) {
+      ia   = MMG_iare[i][0];
+      ib   = MMG_iare[i][1];
+      ipa  = pt->v[ia];
+      ipb  = pt->v[ib];
+      ca   = &mesh->point[ipa].c[0];
+      cb   = &mesh->point[ipb].c[0];
+      iadr = (ipa-1)*sol->offset + 1;
+      ma   = &sol->met[iadr];
+      iadr = (ipb-1)*sol->offset + 1;
+      mb   = &sol->met[iadr];
+
+      len = MMG_length(ca,cb,ma,mb);
+      
+      if(!mesh->info.noinsert && (len > LLONG)) {
+        lon = MMG_coquil(mesh,k,i,&list);
+        if ( lon <= 2 ) break;
+        crit = pt->qual;
+        for (l=2; l<=lon; l++) {
+          iel = list.tetra[l] / 6;
+          pt1 = &mesh->tetra[iel];
+          if ( pt1->qual > crit )  crit = pt1->qual;
+        }
+	/*if(crit > wqual) {  
+          crit *= 2.;
+	} else {
+	  crit *= 1.05;
+	}                          */
+	crit = M_MIN(crit,8.e+8);  
+	ier = 0;
+        if (!mesh->info.noinsert)
+          ier = MMG_spledg(mesh,sol,queue,&list,lon,crit,declic);
+        if ( ier > 0 ) {
+          nd++;
+          break;
+        }
+      }
+    }
+  }  
+  while ( k && *alert == 0 );
+
+   M_free(list.hedg.item);
+   MMG_kiufree(queue);
+
+  return(nd);
+}
+
diff --git a/contrib/mmg3d/build/sources/outqua.c b/contrib/mmg3d/build/sources/outqua.c
new file mode 100644
index 0000000000000000000000000000000000000000..7d811c7d8c60161c1c24bad1bab9ef20d4938c4b
--- /dev/null
+++ b/contrib/mmg3d/build/sources/outqua.c
@@ -0,0 +1,318 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+/* print mesh quality histo */
+int MMG_outqua(pMesh mesh,pSol sol) {
+  pTetra    pt;
+  double    coef,rap4,rapl,rapmin,rapmax,rapavg,dcal;
+  int       his10[11],his01[33],rapnum,iout;
+  int       k,i,j,imax,iel,ir,nn,nex,ielreal,tmp;
+  
+  iout = 0;
+  
+  if(mesh->info.imprim < 0) MMG_priworst(mesh,sol);
+  
+  rapmin  =  1.e20;
+  rapmax  = -1.e20;
+  rapavg  = 0.0;
+  rapnum  = 0;
+  iel     = 0;
+  ielreal = 0;
+  nn      = 0;
+
+  for (k=0; k<=32; k++)  his01[k] = 0;
+  for (k=0; k<=10; k++)  his10[k] = 0;
+
+  coef = ALPHAD;
+  nex  = 0;
+  for (k=1; k<=mesh->ne; k++) {
+    pt = &mesh->tetra[k];
+    if( !pt->v[0] ) {
+      nex++;
+      continue;
+    }
+    nn++;     
+    dcal = MMG_caltet(mesh,sol,k);//(sol->offset==6) ? MMG_caltet_ani(mesh,sol,k) : MMG_caltet_iso(mesh,sol,k);             
+    rap4 = coef * dcal; 
+    if(dcal == CALLIM) {
+      //printf("Wrong elt %d : %d %d %d %d (qual %e %e)\n",k,pt->v[0],pt->v[1],pt->v[2],pt->v[3],rap4,MMG_voltet(mesh,k));
+      tmp = pt->v[2];
+      pt->v[2] = pt->v[3];
+      pt->v[3] = tmp;
+      dcal = MMG_caltet(mesh,sol,k);//(sol->offset==6) ? MMG_caltet_ani(mesh,sol,k) : MMG_caltet_iso(mesh,sol,k);             
+      rap4 = coef * dcal; 
+      if(dcal == CALLIM) {
+        printf("Wrong elt %d : %d %d %d %d (qual %e (%e) %13.12f)\n",k,pt->v[0],pt->v[1],pt->v[2],pt->v[3],rap4,rap4/coef,MMG_voltet(mesh,k));
+        printf("vextex 0 : %e %e %e\n",mesh->point[pt->v[0]].c[0],mesh->point[pt->v[0]].c[1],mesh->point[pt->v[0]].c[2]);
+        printf("vextex 1 : %e %e %e\n",mesh->point[pt->v[1]].c[0],mesh->point[pt->v[1]].c[1],mesh->point[pt->v[1]].c[2]);
+        printf("vextex 2 : %e %e %e\n",mesh->point[pt->v[2]].c[0],mesh->point[pt->v[2]].c[1],mesh->point[pt->v[2]].c[2]);
+        printf("vextex 3 : %e %e %e\n",mesh->point[pt->v[3]].c[0],mesh->point[pt->v[3]].c[1],mesh->point[pt->v[3]].c[2]);
+        //MMG_saveMesh(mesh,"titi.mesh");
+        //exit(0); 
+        iout += 1;
+      }
+			if(abs(mesh->info.imprim) > 5) printf("reorient tet %d\n",k);
+      //iout += 1;
+    }
+    //rap4 = M_MIN(rap4,1.0e9);
+    ir   = (int)rap4;
+    if ( rap4 > rapmax ) {
+      rapmax = rap4; 
+      iel     = k;
+      ielreal = k - nex;
+    }
+    rapavg += rap4; 
+    rapnum++;
+
+    if ( rap4 > 1.0 && rap4 < 17e10 ) {
+      rapmin = M_MIN(rapmin,rap4);
+      if ( rap4 < 10.0 ) {
+        his10[ir] += 1;
+	    his01[0]  += 1;
+      }
+      else if ( rap4 < 17e10 ) {
+        rapl = M_MIN(log10(rap4),32.0);
+        his01[(int)rapl] += 1;
+	    his01[0]  += 1;
+      } 
+    }
+  }
+
+  /* print histo */
+  fprintf(stdout,"\n  -- MESH QUALITY   %d \n",rapnum);
+  if ( (rapavg > 0) && (rapavg / rapnum < 100.0) )
+    fprintf(stdout,"     AVERAGE QUALITY        %12.4f\n",rapavg / rapnum);
+  fprintf(stdout,"     BEST  ELEMENT QUALITY  %12.4f\n",rapmin);
+  if ( rapmax < 1.e7 )
+    fprintf(stdout,"     WORST ELEMENT QUALITY  %12.4f\n",rapmax);
+  else
+    fprintf(stdout,"     WORST ELEMENT QUALITY  %12.4E\n",rapmax);
+  pt = &mesh->tetra[iel];
+  fprintf(stdout,"     WORST ELEMENT   %d (%d)   %d %d %d %d\n",
+	  iel,ielreal,pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
+
+  if ( abs(mesh->info.imprim) < 5 )  return(0);
+
+  fprintf(stdout,"\n     HISTOGRAMM\n");
+  j = 0;
+  for (i=1; i<32; i++)
+    j += his01[i];
+
+  if(rapmax > 1e+9) 
+    imax = 9;
+  else 
+    imax = M_MIN((int)rapmax,9);  
+    
+  for (i=M_MAX((int)rapmin,1); i<=imax; i++) {
+    fprintf(stdout,"     %5d < Q < %5d   %7d   %6.2f %%\n",
+	    i,i+1,his10[i],100.*(his10[i]/(float)his01[0]));
+  }
+
+  /* quality per interval */
+  if (j != 0) {
+    fprintf(stdout,"\n");
+    imax = (int)(M_MIN(3,log10(rapmax)));
+
+    for (i=1; i<=imax; i++) {
+      fprintf(stdout,"     %5.0f < Q < %5.0f   %7d   %6.2f %%\n",
+	      pow(10.,i),pow(10.,i+1),his01[i],100.*(his01[i]/(float)his01[0]));
+    }
+    for (i=4; i<=(int)log10(rapmax); i++) {
+      fprintf(stdout,"    10**%2d < Q < 10**%2d  %7d   %6.2f %%\n",
+	      i,i+1,his01[i],100.*(his01[i]/(float)his01[0]));
+    }
+  }
+  return(iout);
+}
+
+double MMG_priworst(pMesh mesh, pSol sol) { 
+  pTetra pt;
+  int    k,nbad,nreal,nex;
+  double bad;
+  
+  /*worst quality*/
+  bad   = 1.;
+  nbad  = 0; 
+  nex   = 0;
+  nreal = 0;
+  for(k=1 ; k<=mesh->ne ; k++) {
+    pt = &mesh->tetra[k];
+    if(!pt->v[0]) {
+      nex++;
+      continue;
+    }
+    if( pt->qual > bad) {
+      bad   = pt->qual;
+      nbad  = k - nex;
+      nreal = k;
+    }
+  }   
+  
+  if(nreal) printf("     worst quality %d (%d): %e %e\n",nreal,nbad,bad*ALPHAD,ALPHAC*MMG_calte1(mesh,sol,nreal));
+
+  return((&mesh->tetra[nreal])->qual);
+}
+/* print mesh quality histo */
+int MMG_outquacubic(pMesh mesh,pSol sol) {
+  pTetra    pt;
+  double    rapmin,rapmax,rapavg,dcal,som;
+  int       his10[11],his01[5],rapnum,iout;
+  int       k,i,j,iel,ir,nn,nex,ielreal,hismin;
+  
+  iout = 0;
+    
+  rapmin  = 0.;
+  rapmax  = 1.;
+  rapavg  = 0.0;
+  rapnum  = 0;
+  iel     = 0;
+  ielreal = 0;
+  nn      = 0;
+
+  for (k=0; k<=5; k++)  his01[k] = 0;
+  for (k=0; k<=10; k++)  his10[k] = 0;
+
+  nex  = 0;
+  for (k=1; k<=mesh->ne; k++) {
+    pt = &mesh->tetra[k];
+    if( !pt->v[0] ) {
+      nex++;
+      continue;
+    }
+    nn++;     
+    dcal = MMG_caltetcubic(mesh,sol,k); 
+    if(dcal > 1) {
+      //printf("argggggg %d %e %e\n",k,dcal,MMG_caltet(mesh,sol,k)*ALPHAD);
+      dcal = 1.;
+    }   
+    if(dcal == 0.) {
+      printf("Wrong elt %d (qual %e)\n",k,dcal);
+      iout += 1;
+    }
+    ir   = (int)(dcal*10);
+    if ( dcal < rapmax ) {
+      rapmax = dcal;  
+      iel     = k;
+      ielreal = k - nex;
+    }
+    rapavg += dcal;
+    rapnum++;
+
+    if ( dcal <= 1.0 && dcal >= 1e-12 ) {
+      rapmin = M_MAX(rapmin,dcal);
+      if ( dcal > 0.1 ) {
+        his10[ir] += 1;
+	    his01[0]  += 1;
+      }
+      else if ( dcal > 1e-12 ) {   
+        if(dcal > 0.01) {
+          his01[1] += 1;
+        } else if  (dcal > 0.001) {
+          his01[2] += 1;
+        } else if  (dcal > 0.0001) {
+          his01[3] += 1;
+        } else 
+          his01[4] += 1;
+	    his01[0]  += 1;
+      } 
+    }
+  }
+
+  /* print histo */
+  fprintf(stdout,"\n  -- MESH QUALITY (CUBIC)  %d\n",rapnum);
+  if ( rapavg / rapnum > 0.1 )
+    fprintf(stdout,"     AVERAGE QUALITY        %12.4f\n",rapavg / rapnum);
+  fprintf(stdout,"     BEST  ELEMENT QUALITY  %12.4f\n",rapmin);
+  if ( rapmin > 1.e-6 )
+    fprintf(stdout,"     WORST ELEMENT QUALITY  %12.4f\n",rapmax);
+  else
+    fprintf(stdout,"     WORST ELEMENT QUALITY  %12.4E\n",rapmax);
+  pt = &mesh->tetra[iel];
+  fprintf(stdout,"     WORST ELEMENT   %d (%d)   %d %d %d %d\n",
+	  iel,ielreal,pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
+
+  if ( abs(mesh->info.imprim) < 5 )  return(0);
+
+  fprintf(stdout,"\n     HISTOGRAMM\n");
+  j = 0;
+  for (i=1; i<4; i++)
+    j += his01[i];
+  hismin = M_MIN((int)(rapmin*10),1);  
+  som = 0;   
+  if( hismin == 1) { 
+    fprintf(stdout,"     0.9   < Q <   1.0   %7d   %6.2f %%\n",
+        his10[9]+his10[10],100.*((his10[9]+his10[10])/(float)his01[0]));
+    hismin = 9;                          
+    som += 100.*((his10[9]+his10[10])/(float)his01[0]);
+  }
+  for (i=hismin; i>M_MAX((int)(rapmax*10),1); i--) {
+    fprintf(stdout,"     0.%d   < Q <   0.%d   %7d   %6.2f %%\n",
+	    i-1,i,his10[i-1],100.*(his10[i-1]/(float)his01[0])); 
+	som += 100.*(his10[i-1]/(float)his01[0]);        
+  } 
+
+  /* quality per interval */
+  if (j != 0) {
+    fprintf(stdout,"\n"); 
+    j -= his01[1];
+    if(his01[1]!=0)
+      fprintf(stdout,"     0.01   < Q <  0.1   %7d   %6.2f %%\n",
+	      his01[1],100.*(his01[1]/(float)his01[0]));
+    if(j!=0)
+      fprintf(stdout,"     0.001  < Q <  0.01  %7d   %6.2f %%\n",
+  	    his01[2],100.*(his01[1]/(float)his01[0]));    
+    j -= his01[2];
+    if(j!=0)
+      fprintf(stdout,"     0.0001 < Q <  0.001 %7d   %6.2f %%\n",
+  	    his01[3],100.*(his01[1]/(float)his01[0]));
+    j -= his01[3];
+    if(j!=0)
+        fprintf(stdout,"     0.     < Q    %7d   %6.2f %%\n",
+  	      his01[4],100.*(his01[1]/(float)his01[0]));
+   }
+  return(iout);
+}
diff --git a/contrib/mmg3d/build/sources/pattern.c b/contrib/mmg3d/build/sources/pattern.c
new file mode 100644
index 0000000000000000000000000000000000000000..d0994051651d8875d220a06592d8387d6fe396f2
--- /dev/null
+++ b/contrib/mmg3d/build/sources/pattern.c
@@ -0,0 +1,2440 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+
+unsigned char MMG_arfa[3][4] = { {2,0,1,3}, {1,2,0,3}, {0,1,2,3} }; 
+extern int MMG_permar[10][4];
+extern int MMG_pointar[64][2];
+extern int ddebug;
+//insert ip on ia-ib
+int MMG_pattern1(pMesh mesh,pSol sol,pHedge hash,int jel) {
+  pTetra     pt,pt1;
+  int        iel,ia,ib,ic,id,ip,tabref[4],i; 
+  if(ddebug) printf("on cut 1\n");
+
+  pt = &mesh->tetra[jel];
+  for (i=0 ; i<4 ; i++) 
+    tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]]; 
+  
+  if(pt->tabedg != 1) {    
+    ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]];
+    ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]];
+    ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]];
+    id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]];
+  } else {
+    ia = pt->v[0];
+    ib = pt->v[1];
+    ic = pt->v[2];
+    id = pt->v[3];
+  } 
+  ip = MMG_edgePoint(hash,ia,ib);
+  assert(ip);
+  if(ddebug) printf("ia %d %d %d %d\n",ia,ib,ic,id);
+  pt->v[0] = ia;
+  pt->v[1] = ip;
+  pt->v[2] = ic;
+  pt->v[3] = id;
+  pt->qual = MMG_caltet(mesh,sol,jel); 
+  pt->tabedg = 0;
+  pt->flag = mesh->flag;  
+  pt->bdryref[0] = -1;
+  pt->bdryref[1] = tabref[1];
+  pt->bdryref[2] = tabref[2];
+  pt->bdryref[3] = tabref[3];
+  if(ddebug) printf("creationi %d : %d %d %d %d\n",jel,ia,ip,ic,id); 
+  
+  iel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[iel];
+  pt1->v[0] = ip;
+  pt1->v[1] = ib;
+  pt1->v[2] = ic;
+  pt1->v[3] = id;
+  pt1->qual = MMG_caltet(mesh,sol,iel);
+  pt1->ref  = pt->ref;
+  pt1->flag = mesh->flag; 
+  if(ddebug) printf("tabref %d %d %d %d\n",tabref[0],tabref[1],tabref[2],tabref[3]);
+  pt1->bdryref[0] = tabref[0];
+  pt1->bdryref[1] = -1;
+  pt1->bdryref[2] = tabref[2];
+  pt1->bdryref[3] = tabref[3];
+  if(ddebug) printf("creationi %d : %d %d %d %d\n",iel,ip,ib,ic,id); 
+  //if(ddebug) exit(1); 
+  return(1);
+}
+
+int MMG_pattern2(pMesh mesh,pSol sol,pHedge hash, int iel) { 
+  pTetra     pt,pt1;
+  int        jel,ia,ib,ic,id,iad,ibc,i,tabref[4];
+  
+  pt = &mesh->tetra[iel];
+  for (i=0 ; i<4 ; i++) 
+    tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]]; 
+
+  if(pt->tabedg != 12) {
+    ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]];
+    ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]];
+    ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]];
+    id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]];
+  } else {
+    ia = pt->v[0];
+    ib = pt->v[1];
+    ic = pt->v[2];
+    id = pt->v[3];
+  } 
+  iad = MMG_edgePoint(hash,ia,id); 
+  assert(iad>0);
+  ibc = MMG_edgePoint(hash,ib,ic); 
+  assert(ibc>0);
+  
+  pt->v[0] = ibc;
+  pt->v[1] = ic;
+  pt->v[2] = iad;
+  pt->v[3] = id;
+  pt->qual = MMG_caltet(mesh,sol,iel); 
+  pt->tabedg = 0;
+  pt->flag = mesh->flag; 
+  pt->bdryref[0] = tabref[1];
+  pt->bdryref[1] = -1;
+  pt->bdryref[2] = tabref[0];
+  pt->bdryref[3] = -1;
+  
+  
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ib;
+  pt1->v[1] = ibc;
+  pt1->v[2] = iad;
+  pt1->v[3] = id;
+  pt1->qual = MMG_caltet(mesh,sol,jel);
+  pt1->ref  = pt->ref;
+  pt1->flag = mesh->flag;
+  pt1->bdryref[0] = -1;
+  pt1->bdryref[1] = tabref[2];
+  pt1->bdryref[2] = tabref[0];
+  pt1->bdryref[3] = -1;
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = ibc;
+  pt1->v[2] = ic;
+  pt1->v[3] = iad;
+  pt1->qual = MMG_caltet(mesh,sol,jel);
+  pt1->ref  = pt->ref;
+  pt1->flag = mesh->flag;
+  pt1->bdryref[0] = -1;
+  pt1->bdryref[1] = tabref[1];
+  pt1->bdryref[2] = -1;
+  pt1->bdryref[3] = tabref[3];
+   
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = ib;
+  pt1->v[2] = ibc;
+  pt1->v[3] = iad;
+  pt1->qual = MMG_caltet(mesh,sol,jel);
+  pt1->ref  = pt->ref;
+  pt1->flag = mesh->flag;
+  pt1->bdryref[0] = -1;
+  pt1->bdryref[1] = -1;
+  pt1->bdryref[2] = tabref[2];
+  pt1->bdryref[3] = tabref[3];
+  return(1); 
+}
+
+int MMG_pattern22(pMesh mesh,pSol sol,pHedge hash, int iel) { 
+  pTetra     pt,pt1;
+  int        jel,ia,ib,ic,id,iab,ibd,i,tabref[4];
+  
+  pt = &mesh->tetra[iel];
+  for (i=0 ; i<4 ; i++) 
+    tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]]; 
+
+  if(pt->tabedg != 17) {
+    ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]];
+    ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]];
+    ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]];
+    id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]];
+  } else {
+    ia = pt->v[0];
+    ib = pt->v[1];
+    ic = pt->v[2];
+    id = pt->v[3];
+  } 
+  iab = MMG_edgePoint(hash,ia,ib); 
+  assert(iab>0);
+  ibd = MMG_edgePoint(hash,ib,id); 
+  assert(ibd>0);
+  pt->v[0] = iab;
+  pt->v[1] = ib;
+  pt->v[2] = ic;
+  pt->v[3] = ibd;
+  pt->qual = MMG_caltet(mesh,sol,iel); 
+  //if(pt->qual==CALLIM) puts("ahhhhhhhhh1");
+  pt->tabedg = 0;
+  pt->flag = mesh->flag;
+  pt->bdryref[0] = tabref[0];
+  pt->bdryref[1] = -1;
+  pt->bdryref[2] = tabref[2];
+  pt->bdryref[3] = tabref[3];
+  
+  if ( ia > id ) {
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iab;
+    pt1->v[1] = ibd;
+    pt1->v[2] = ic;
+    pt1->v[3] = id;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) puts("bbahhhhhhhhh1");
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[0];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ia;
+    pt1->v[1] = iab;
+    pt1->v[2] = ic;
+    pt1->v[3] = id;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) puts("ahhhhhhhhh11");
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[1];
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = tabref[3];
+  } else {
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ia;
+    pt1->v[1] = iab;
+    pt1->v[2] = ic;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) printf("ahhhvhhhhhh11 %d %d %d %d\n",ia,iab,ib,ibd);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = tabref[3];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ia;
+    pt1->v[1] = ic;
+    pt1->v[2] = id;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) puts("ahvvhhhhhhhh11");
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = tabref[0];
+    pt1->bdryref[1] = tabref[2];
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[1];
+    
+  }
+   
+  return(1); 
+}
+
+int MMG_pattern3(pMesh mesh,pSol sol,pHedge hash,int iel) {
+  pTetra     pt,pt1;
+  int        ia,ib,ic,id,iad,iab,ibd,jel,i,tabref[4];
+  
+  pt = &mesh->tetra[iel];
+  for (i=0 ; i<4 ; i++) 
+    tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]];
+     
+  if(pt->tabedg != 21) {
+    ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]];
+    ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]];
+    ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]];
+    id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]];
+  } else {
+    ia = pt->v[0];
+    ib = pt->v[1];
+    ic = pt->v[2];
+    id = pt->v[3];
+  } 
+  
+  iad = MMG_edgePoint(hash,ia,id);
+  assert(iad>0);
+  iab = MMG_edgePoint(hash,ia,ib);
+  assert(iab>0);
+  ibd = MMG_edgePoint(hash,ib,id);
+  assert(ibd>0);
+  
+  pt->v[0] = iab;
+  pt->v[1] = ib;
+  pt->v[2] = ic;
+  pt->v[3] = ibd;
+  pt->qual = MMG_caltet(mesh,sol,iel); 
+  pt->tabedg = 0;
+  pt->flag = mesh->flag;
+  pt->bdryref[0] = tabref[0];
+  pt->bdryref[1] = -1;
+  pt->bdryref[2] = tabref[2];
+  pt->bdryref[3] = tabref[3];
+  
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = iab;
+  pt1->v[2] = ic;
+  pt1->v[3] = iad;
+  pt1->qual = MMG_caltet(mesh,sol,jel);
+  pt1->ref  = pt->ref;
+  pt1->flag = mesh->flag;
+  pt1->bdryref[0] = -1;
+  pt1->bdryref[1] = tabref[1];
+  pt1->bdryref[2] = tabref[2];
+  pt1->bdryref[3] = tabref[3];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = iad;
+  pt1->v[1] = ibd;
+  pt1->v[2] = ic;
+  pt1->v[3] = id;
+  pt1->qual = MMG_caltet(mesh,sol,jel);
+  pt1->ref  = pt->ref;   
+  pt1->flag = mesh->flag;
+  pt1->bdryref[0] = tabref[0];
+  pt1->bdryref[1] = tabref[1];
+  pt1->bdryref[2] = tabref[2];
+  pt1->bdryref[3] = -1;
+  
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = iab;
+  pt1->v[1] = iad;
+  pt1->v[2] = ibd;
+  pt1->v[3] = ic;
+  pt1->qual = MMG_caltet(mesh,sol,jel);
+  pt1->ref  = pt->ref;
+  pt1->flag = mesh->flag;
+  pt1->bdryref[0] = -1;
+  pt1->bdryref[1] = -1;
+  pt1->bdryref[2] = -1;
+  pt1->bdryref[3] = tabref[2];
+  
+  return(1);
+  
+}
+
+int MMG_pattern31(pMesh mesh,pSol sol,pHedge hash,int iel) {
+  pTetra     pt,pt1;
+  int        ia,ib,ic,id,iad,icd,ibd,jel,i,tabref[4];
+  
+  pt = &mesh->tetra[iel];
+  for (i=0 ; i<4 ; i++) 
+    tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]]; 
+  if(pt->tabedg != 52) {
+    ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]];
+    ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]];
+    ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]];
+    id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]];
+  } else {
+    ia = pt->v[0];
+    ib = pt->v[1];
+    ic = pt->v[2];
+    id = pt->v[3];
+  } 
+  
+  iad = MMG_edgePoint(hash,ia,id);
+  assert(iad>0);
+  icd = MMG_edgePoint(hash,ic,id);
+  assert(icd>0);
+  ibd = MMG_edgePoint(hash,ib,id);
+  assert(ibd>0);
+
+  pt->v[0] = iad;
+  pt->v[1] = ibd;
+  pt->v[2] = icd;
+  pt->v[3] = id;
+  pt->qual = MMG_caltet(mesh,sol,iel); 
+  pt->tabedg = 0;
+  pt->flag = mesh->flag;
+  pt->bdryref[0] = tabref[0];
+  pt->bdryref[1] = tabref[1];
+  pt->bdryref[2] = tabref[2];
+  pt->bdryref[3] = pt->ref;
+  
+  if ( (ia > ib) && (ib > ic) ) {
+    assert(ia > ic);  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ia;
+    pt1->v[1] = ib;
+    pt1->v[2] = ic;
+    pt1->v[3] = iad;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = pt->ref;
+    pt1->bdryref[1] = tabref[1];
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = tabref[3];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ib;
+    pt1->v[1] = ic;
+    pt1->v[2] = iad;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;   
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = pt->ref;
+    pt1->bdryref[1] = tabref[2];
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = pt->ref;
+  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ic;
+    pt1->v[1] = iad;
+    pt1->v[2] = ibd;
+    pt1->v[3] = icd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = pt->ref;
+    pt1->bdryref[1] = tabref[0];
+    pt1->bdryref[2] = tabref[1];
+    pt1->bdryref[3] = pt->ref;
+  } 
+  else if ( (ia > ib) && (ic > ib) && (ic > ia)) {  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ib;
+    pt1->v[1] = icd;
+    pt1->v[2] = iad;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = pt->ref;
+    pt1->bdryref[1] = tabref[2];
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = pt->ref;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ic;
+    pt1->v[1] = ia;
+    pt1->v[2] = ib;
+    pt1->v[3] = icd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;   
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = pt->ref;
+    pt1->bdryref[1] = tabref[0];
+    pt1->bdryref[2] = tabref[1];
+    pt1->bdryref[3] = tabref[3];
+  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ia;
+    pt1->v[1] = ib;
+    pt1->v[2] = icd;
+    pt1->v[3] = iad;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = pt->ref;
+    pt1->bdryref[1] = tabref[1];
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = pt->ref;
+  }
+  else if ( (ia > ib) && (ic > ib) && (ia > ic)) {  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ia;
+    pt1->v[1] = ib;
+    pt1->v[2] = ic;
+    pt1->v[3] = iad;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = pt->ref;
+    pt1->bdryref[1] = tabref[1];
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = tabref[3];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ib;
+    pt1->v[1] = icd;
+    pt1->v[2] = iad;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;   
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = pt->ref;
+    pt1->bdryref[1] = tabref[2];
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = pt->ref;
+  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ib;
+    pt1->v[1] = ic;
+    pt1->v[2] = iad;
+    pt1->v[3] = icd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[1];
+    pt1->bdryref[1] = pt->ref;
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = pt->ref;
+  }
+  else if ( (ib > ia) && (ib > ic) && (ic > ia)) {  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ib;
+    pt1->v[1] = ia;
+    pt1->v[2] = ibd;
+    pt1->v[3] = ic;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = pt->ref;
+    pt1->bdryref[1] = tabref[0];
+    pt1->bdryref[2] = tabref[3];
+    pt1->bdryref[3] = tabref[2];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ic;
+    pt1->v[1] = ia;
+    pt1->v[2] = ibd;
+    pt1->v[3] = icd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;   
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = pt->ref;
+    pt1->bdryref[1] = tabref[0];
+    pt1->bdryref[2] = tabref[1];
+    pt1->bdryref[3] = pt->ref;
+  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ia;
+    pt1->v[1] = ibd;
+    pt1->v[2] = icd;
+    pt1->v[3] = iad;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = pt->ref;
+    pt1->bdryref[1] = tabref[0];
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = pt->ref;
+  }
+  else if ( (ib > ia) && (ib > ic) && (ia > ic)) {  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ib;
+    pt1->v[1] = ia;
+    pt1->v[2] = ibd;
+    pt1->v[3] = ic;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = pt->ref;
+    pt1->bdryref[1] = tabref[0];
+    pt1->bdryref[2] = tabref[3];
+    pt1->bdryref[3] = tabref[2];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = ic;
+    pt1->v[2] = ibd;
+    pt1->v[3] = ia;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;   
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = pt->ref;
+    pt1->bdryref[1] = tabref[2];
+    pt1->bdryref[2] = tabref[1];
+    pt1->bdryref[3] = pt->ref;
+  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = ic;
+    pt1->v[2] = iad;
+    pt1->v[3] = icd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[1];
+    pt1->bdryref[1] = pt->ref;
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = pt->ref;
+  }
+  else if ( (ib > ia) && (ic > ib) ) { 
+    assert(ic > ia); 
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ib;
+    pt1->v[1] = ic;
+    pt1->v[2] = ia;
+    pt1->v[3] = icd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[1];
+    pt1->bdryref[1] = pt->ref;
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = tabref[3];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ia;
+    pt1->v[1] = ibd;
+    pt1->v[2] = icd;
+    pt1->v[3] = iad;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;   
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = pt->ref;
+    pt1->bdryref[1] = tabref[1];
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = pt->ref;
+  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ia;
+    pt1->v[1] = ib;
+    pt1->v[2] = icd;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[0];
+    pt1->bdryref[1] = pt->ref;
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = pt->ref;
+  }
+  
+  return(1);
+  
+}
+
+int MMG_pattern32(pMesh mesh,pSol sol,pHedge hash,int iel) {
+  pTetra     pt,pt1;
+  int        ia,ib,ic,id,iad,ibc,ibd,jel,i,tabref[4];
+  
+  pt = &mesh->tetra[iel];
+  for (i=0 ; i<4 ; i++) 
+    tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]]; 
+  if(pt->tabedg != 28) {
+    ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]];
+    ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]];
+    ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]];
+    id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]];
+  } else {
+    ia = pt->v[0];
+    ib = pt->v[1];
+    ic = pt->v[2];
+    id = pt->v[3];
+  } 
+  
+  iad = MMG_edgePoint(hash,ia,id);
+  assert(iad>0);
+  ibc = MMG_edgePoint(hash,ib,ic); 
+  assert(ibc>0);
+  ibd = MMG_edgePoint(hash,ib,id);
+  assert(ibd>0);
+
+  if ( (ia > ib) && (ic > id) ) {
+    pt->v[0] = iad;
+    pt->v[1] = ib;
+    pt->v[2] = ia;
+    pt->v[3] = ibc;
+    pt->qual = MMG_caltet(mesh,sol,iel); 
+    //if(pt->qual==CALLIM) puts("ahhhhhhhhh1");
+    pt->tabedg = 0;
+    pt->flag = mesh->flag;
+    pt->bdryref[0] = tabref[3];
+    pt->bdryref[1] = -1;
+    pt->bdryref[2] = tabref[2];
+    pt->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ib;
+    pt1->v[1] = ibc;
+    pt1->v[2] = iad;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) puts("bahhhhhhhhh2");
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[2];
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = ibd;
+    pt1->v[2] = ibc;
+    pt1->v[3] = id;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) puts("bahhhhhhhhh3");
+    pt1->ref  = pt->ref;   
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[0];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = -1;
+  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibc;
+    pt1->v[1] = iad;
+    pt1->v[2] = id;
+    pt1->v[3] = ic;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) puts("bahhhhhhhhh4");
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[1];
+    pt1->bdryref[1] = tabref[0];
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ic;
+    pt1->v[1] = ia;
+    pt1->v[2] = ibc;
+    pt1->v[3] = iad;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) puts("bahhhhhhhhh5");
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[1];
+    pt1->bdryref[3] = tabref[3];
+  } 
+  else if ( (ia > ib) && (id > ic) ) {  
+    pt->v[0] = iad;
+    pt->v[1] = ib;
+    pt->v[2] = ia;
+    pt->v[3] = ibc;
+    pt->qual = MMG_caltet(mesh,sol,iel); 
+    //if(pt->qual==CALLIM) puts("ahhhhhhhhh1");
+    pt->tabedg = 0;
+    pt->flag = mesh->flag;
+    pt->bdryref[0] = tabref[3];
+    pt->bdryref[1] = -1;
+    pt->bdryref[2] = -1;
+    pt->bdryref[3] = tabref[2];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ib;
+    pt1->v[1] = ibc;
+    pt1->v[2] = iad;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) puts("ahhhhhhhhh2");
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[2];
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = ibc;
+    pt1->v[2] = iad;
+    pt1->v[3] = ic;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) puts("ahhhhhhhhh3");
+    pt1->ref  = pt->ref;   
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = -1;
+  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = iad;
+    pt1->v[2] = id;
+    pt1->v[3] = ic;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) puts("ahhhhhhhhh4");
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[1];
+    pt1->bdryref[1] = tabref[0];
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[2];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ic;
+    pt1->v[1] = ia;
+    pt1->v[2] = ibc;
+    pt1->v[3] = iad;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) puts("ahhhhhhhhh5");
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[1];
+    pt1->bdryref[3] = tabref[3];
+  }
+  else if ( (ib > ia) && (ic > id) ) {  
+    pt->v[0] = ia;
+    pt->v[1] = iad;
+    pt->v[2] = ibc;
+    pt->v[3] = ic;
+    pt->qual = MMG_caltet(mesh,sol,iel); 
+   // if(pt->qual==CALLIM) puts("ahhhhhhhhh6");
+    pt->tabedg = 0;
+    pt->flag = mesh->flag;
+    pt->bdryref[0] = -1;
+    pt->bdryref[1] = tabref[3];
+    pt->bdryref[2] = tabref[1];
+    pt->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibc;
+    pt1->v[1] = ic;
+    pt1->v[2] = iad;
+    pt1->v[3] = id;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) puts("ahhhhhhhhh7");
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[1];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = ibd;
+    pt1->v[2] = ia;
+    pt1->v[3] = ibc;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) puts("ahhhhhhhhh8");
+    pt1->ref  = pt->ref;   
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[2];
+  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ia;
+    pt1->v[1] = ib;
+    pt1->v[2] = ibc;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) puts("ahhhhhhhhh9");
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[0];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = tabref[3];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibc;
+    pt1->v[1] = iad;
+    pt1->v[2] = ibd;
+    pt1->v[3] = id;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) puts("ahhhhhhhhh10");
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[2];
+    pt1->bdryref[1] = tabref[0];
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = -1;
+  }
+  else if ( (ib > ia) && (id > ic) ) {  
+    pt->v[0] = iad;
+    pt->v[1] = ibd;
+    pt->v[2] = ia;
+    pt->v[3] = ic;
+    pt->qual = MMG_caltet(mesh,sol,iel); 
+    //if(pt->qual==CALLIM) puts("ahhhhhhhhh11");
+    pt->tabedg = 0;
+    pt->flag = mesh->flag;
+    pt->bdryref[0] = -1;
+    pt->bdryref[1] = tabref[1];
+    pt->bdryref[2] = -1;
+    pt->bdryref[3] = tabref[2];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ia;
+    pt1->v[1] = ib;
+    pt1->v[2] = ibc;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) puts("ahhhhhhhhh12");
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[0];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = tabref[3];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ic;
+    pt1->v[1] = iad;
+    pt1->v[2] = ibd;
+    pt1->v[3] = id;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) puts("ahhhhhhhhh13");
+    pt1->ref  = pt->ref;   
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[2];
+    pt1->bdryref[1] = tabref[0];
+    pt1->bdryref[2] = tabref[1];
+    pt1->bdryref[3] = -1;
+  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibc;
+    pt1->v[1] = ic;
+    pt1->v[2] = ia;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    //if(pt1->qual==CALLIM) puts("ahhhhhhhhh14");
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag; 
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = tabref[3];
+       
+  }
+  
+  return(1);
+  
+} 
+
+int MMG_pattern33(pMesh mesh,pSol sol,pHedge hash,int iel) {
+  pTetra     pt,pt1;
+  int        ia,ib,ic,id,iad,iac,ibd,jel,i,tabref[4];
+  
+  pt = &mesh->tetra[iel];
+  for (i=0 ; i<4 ; i++) 
+    tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]]; 
+  if(pt->tabedg != 22) {
+    ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]];
+    ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]];
+    ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]];
+    id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]];
+  } else {
+    ia = pt->v[0];
+    ib = pt->v[1];
+    ic = pt->v[2];
+    id = pt->v[3];
+  } 
+  
+  iad = MMG_edgePoint(hash,ia,id);
+  assert(iad>0);
+  iac = MMG_edgePoint(hash,ia,ic);
+  assert(iac>0);
+  ibd = MMG_edgePoint(hash,ib,id);
+  assert(ibd>0);
+
+  if ( (ia > ib) && (ic > id) ) { 
+    pt->v[0] = ia;
+    pt->v[1] = ib;
+    pt->v[2] = iac;
+    pt->v[3] = iad;
+    pt->qual = MMG_caltet(mesh,sol,iel); 
+    if(pt->qual==CALLIM) printf("tet 1\n");
+    pt->tabedg = 0;
+    pt->flag = mesh->flag;
+    pt->bdryref[0] = -1;
+    pt->bdryref[1] = tabref[1];
+    pt->bdryref[2] = tabref[2];
+    pt->bdryref[3] = tabref[3];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iac;
+    pt1->v[1] = ic;
+    pt1->v[2] = id;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    if(pt1->qual==CALLIM) printf("tet 2\n");
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[0];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[1];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = ic;
+    pt1->v[2] = ib;
+    pt1->v[3] = iac;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    if(pt1->qual==CALLIM) printf("tet 3\n");
+    pt1->ref  = pt->ref;   
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[3];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[0];
+  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = iac;
+    pt1->v[2] = ibd;
+    pt1->v[3] = ib;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    if(pt1->qual==CALLIM) printf("tet 4\n");
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[2];
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = iac;
+    pt1->v[2] = id;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    if(pt1->qual==CALLIM) printf("tet 5\n");
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[2];
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[1];
+  } 
+  else if ( (ia > ib) && (id > ic) ) {  
+    pt->v[0] = ia;
+    pt->v[1] = ib;
+    pt->v[2] = iac;
+    pt->v[3] = iad;
+    pt->qual = MMG_caltet(mesh,sol,iel); 
+    pt->tabedg = 0;
+    pt->flag = mesh->flag;
+    pt->bdryref[0] = -1;
+    pt->bdryref[1] = tabref[1];
+    pt->bdryref[2] = tabref[2];
+    pt->bdryref[3] = tabref[3];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = ic;
+    pt1->v[2] = ib;
+    pt1->v[3] = iac;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[3];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[0];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = iac;
+    pt1->v[2] = ibd;
+    pt1->v[3] = ib;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;   
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[2];
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = -1;
+  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = iac;
+    pt1->v[2] = ic;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[1];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = ic;
+    pt1->v[2] = id;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[0];
+    pt1->bdryref[1] = tabref[2];
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[1];
+  }
+  else if ( (ib > ia) && (ic > id) ) {  
+    pt->v[0] = iac;
+    pt->v[1] = ic;
+    pt->v[2] = id;
+    pt->v[3] = ibd;
+    pt->qual = MMG_caltet(mesh,sol,iel); 
+    pt->tabedg = 0;
+    pt->flag = mesh->flag;
+    pt->bdryref[0] = tabref[0];
+    pt->bdryref[1] = -1;
+    pt->bdryref[2] = -1;
+    pt->bdryref[3] = tabref[1];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = ic;
+    pt1->v[2] = ib;
+    pt1->v[3] = iac;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[3];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[0];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = iac;
+    pt1->v[2] = id;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;   
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[2];
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[1];
+  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = ibd;
+    pt1->v[2] = ia;
+    pt1->v[3] = iac;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[1];
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[2];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iac;
+    pt1->v[1] = ibd;
+    pt1->v[2] = ia;
+    pt1->v[3] = ib;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[2];
+    pt1->bdryref[1] = tabref[3];
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = -1;
+  }
+  else if ( (ib > ia) && (id > ic) ) {  
+    pt->v[0] = ibd;
+    pt->v[1] = ic;
+    pt->v[2] = ib;
+    pt->v[3] = iac;
+    pt->qual = MMG_caltet(mesh,sol,iel); 
+    pt->tabedg = 0;
+    pt->flag = mesh->flag;
+    pt->bdryref[0] = tabref[3];
+    pt->bdryref[1] = -1;
+    pt->bdryref[2] = -1;
+    pt->bdryref[3] = tabref[0];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = ibd;
+    pt1->v[2] = ia;
+    pt1->v[3] = iac;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[1];
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[2];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iac;
+    pt1->v[1] = ibd;
+    pt1->v[2] = ia;
+    pt1->v[3] = ib;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;   
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[2];
+    pt1->bdryref[1] = tabref[3];
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = -1;
+  
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = iad;
+    pt1->v[2] = ic;
+    pt1->v[3] = iac;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;    
+    pt1->bdryref[0] = tabref[1];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = ic;
+    pt1->v[2] = iad;
+    pt1->v[3] = id;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;    
+    pt1->bdryref[0] = tabref[1];
+    pt1->bdryref[1] = tabref[2];
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = -1;
+
+  }
+  
+  return(1);
+  
+}
+
+int MMG_pattern4(pMesh mesh,pSol sol,pHedge hash, int iel) { 
+  pTetra     pt,pt1;
+  int        jel,ia,ib,ic,id,iab,ibd,ibc,iad,i,tabref[4];
+  
+  pt = &mesh->tetra[iel];
+  for (i=0 ; i<4 ; i++) 
+    tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]]; 
+
+  if(pt->tabedg != 29) {
+    ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]];
+    ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]];
+    ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]];
+    id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]];
+  } else {
+    ia = pt->v[0];
+    ib = pt->v[1];
+    ic = pt->v[2];
+    id = pt->v[3];
+  } 
+  iab = MMG_edgePoint(hash,ia,ib); 
+  assert(iab>0);
+  ibd = MMG_edgePoint(hash,ib,id); 
+  assert(ibd>0);
+  iad = MMG_edgePoint(hash,ia,id); 
+  assert(iad>0);
+  ibc = MMG_edgePoint(hash,ib,ic); 
+  assert(ibc>0);
+  
+  if ( ( ic > id ) && ( ia > ic ) ) {  
+    pt->v[0] = iab;
+    pt->v[1] = ibc;
+    pt->v[2] = ic;
+    pt->v[3] = iad;
+    pt->qual = MMG_caltet(mesh,sol,iel); 
+    pt->tabedg = 0;
+    pt->flag = mesh->flag; 
+    pt->bdryref[0] = -1;
+    pt->bdryref[1] = -1;
+    pt->bdryref[2] = -1;
+    pt->bdryref[3] = tabref[3];
+    
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = id;
+    pt1->v[1] = ibd;
+    pt1->v[2] = iad;
+    pt1->v[3] = ibc;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = tabref[2];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = ibd;
+    pt1->v[2] = iab;
+    pt1->v[3] = ibc;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[2];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = iab;
+    pt1->v[2] = ibc;
+    pt1->v[3] = ib;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = tabref[3];
+    pt1->bdryref[1] = tabref[0];
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = ia;
+    pt1->v[2] = ic;
+    pt1->v[3] = iab;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = tabref[3];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = tabref[1];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = ic;
+    pt1->v[2] = id;
+    pt1->v[3] = ibc;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = tabref[0];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[1];
+  } 
+  else if ( ( ic > id ) && ( ic > ia ) ) { 
+    pt->v[0] = iad;
+    pt->v[1] = ia;
+    pt->v[2] = ibc;
+    pt->v[3] = iab;
+    pt->qual = MMG_caltet(mesh,sol,iel);  
+    if(pt->qual==CALLIM) printf("biel %d\n",iel);
+    pt->tabedg = 0;
+    pt->flag = mesh->flag; 
+    pt->bdryref[0] = tabref[3];
+    pt->bdryref[1] = -1;
+    pt->bdryref[2] = tabref[2];
+    pt->bdryref[3] = -1;
+    
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = iab;
+    pt1->v[2] = ibc;
+    pt1->v[3] = ib;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    if(pt1->qual==CALLIM) printf("ciel %d\n",iel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[2];
+    pt1->bdryref[1] = tabref[0];
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = -1;
+    
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = ibd;
+    pt1->v[2] = iab;
+    pt1->v[3] = ibc;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    if(pt1->qual==CALLIM) printf("diel %d\n",iel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[2];
+    
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ia;
+    pt1->v[1] = iad;
+    pt1->v[2] = ibc;
+    pt1->v[3] = ic;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    if(pt1->qual==CALLIM) printf("eiel %d\n",iel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[3];
+    pt1->bdryref[2] = tabref[1];
+    pt1->bdryref[3] = -1;
+    
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = id;
+    pt1->v[1] = ibd;
+    pt1->v[2] = iad;
+    pt1->v[3] = ibc;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    if(pt1->qual==CALLIM) printf("fiel %d\n",iel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = tabref[2];
+    
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = ic;
+    pt1->v[2] = id;
+    pt1->v[3] = ibc;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    if(pt1->qual==CALLIM) printf("giel %d\n",iel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = tabref[0];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[1];
+  }
+  else if ( ia > ic ) {
+    assert(id > ic); 
+    pt->v[0] = iab;
+    pt->v[1] = ibc;
+    pt->v[2] = ic;
+    pt->v[3] = iad;
+    pt->qual = MMG_caltet(mesh,sol,iel); 
+    pt->tabedg = 0;
+    pt->flag = mesh->flag; 
+    pt->bdryref[0] = -1;
+    pt->bdryref[1] = -1;
+    pt->bdryref[2] = -1;
+    pt->bdryref[3] = tabref[3];
+    
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = ibd;
+    pt1->v[2] = ibc;
+    pt1->v[3] = ic;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[0];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = ibd;
+    pt1->v[2] = iab;
+    pt1->v[3] = ibc;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[2];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iab;
+    pt1->v[1] = ib;
+    pt1->v[2] = ibc;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = tabref[0];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = tabref[3];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = ibd;
+    pt1->v[2] = ic;
+    pt1->v[3] = id;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = tabref[0];
+    pt1->bdryref[1] = tabref[1];
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ia;
+    pt1->v[1] = iab;
+    pt1->v[2] = ic;
+    pt1->v[3] = iad;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[1];
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = tabref[3];
+  }
+  else {
+    assert(id > ic);
+    assert(ic > ia); 
+    pt->v[0] = ibd;
+    pt->v[1] = ic;
+    pt->v[2] = ibc;
+    pt->v[3] = iad;
+    pt->qual = MMG_caltet(mesh,sol,iel); 
+    pt->tabedg = 0;
+    pt->flag = mesh->flag; 
+    pt->bdryref[0] = -1;
+    pt->bdryref[1] = -1;
+    pt->bdryref[2] = -1;
+    pt->bdryref[3] = tabref[0];
+    
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = ic;
+    pt1->v[2] = iad;
+    pt1->v[3] = id;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[1];
+    pt1->bdryref[1] = tabref[2];
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ia;
+    pt1->v[1] = ibc;
+    pt1->v[2] = ic;
+    pt1->v[3] = iad;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[1];
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[3];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ia;
+    pt1->v[1] = iab;
+    pt1->v[2] = ibc;
+    pt1->v[3] = iad;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = tabref[3];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iab;
+    pt1->v[1] = ib;
+    pt1->v[2] = ibc;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = tabref[0];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = tabref[3];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iad;
+    pt1->v[1] = ibd;
+    pt1->v[2] = iab;
+    pt1->v[3] = ibc;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[2];
+  }
+   
+  return(1); 
+}
+
+
+int MMG_pattern41(pMesh mesh,pSol sol,pHedge hash, int iel) { 
+  pTetra     pt,pt1;
+  int        jel,ia,ib,ic,id,iab,icd,iac,ibd,i,tabref[4];
+  
+  pt = &mesh->tetra[iel];
+  for (i=0 ; i<4 ; i++) 
+    tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]]; 
+  if(pt->tabedg != 51) {
+    ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]];
+    ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]];
+    ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]];
+    id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]];
+  } else {
+    ia = pt->v[0];
+    ib = pt->v[1];
+    ic = pt->v[2];
+    id = pt->v[3];
+  } 
+  iab = MMG_edgePoint(hash,ia,ib); 
+  assert(iab>0);
+  icd = MMG_edgePoint(hash,ic,id); 
+  assert(icd>0);
+  iac = MMG_edgePoint(hash,ia,ic); 
+  assert(iac>0);
+  ibd = MMG_edgePoint(hash,ib,id); 
+  assert(ibd>0);
+  
+  if ( ( ib > ic ) && ( ia > id ) ) { /*tetrap43.mesh*/
+    pt->v[0] = id;
+    pt->v[1] = iab;
+    pt->v[2] = iac;
+    pt->v[3] = ibd;
+    pt->qual = MMG_caltet(mesh,sol,iel); 
+    pt->tabedg = 0;
+    pt->flag = mesh->flag; 
+    pt->bdryref[0] = -1;
+    pt->bdryref[1] = -1;
+    pt->bdryref[2] = tabref[2];
+    pt->bdryref[3] = -1;
+    
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = id;
+    pt1->v[1] = ia;
+    pt1->v[2] = iac;
+    pt1->v[3] = iab;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[3];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = tabref[1];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iac;
+    pt1->v[1] = ic;
+    pt1->v[2] = ibd;
+    pt1->v[3] = iab;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[3];
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = icd;
+    pt1->v[2] = iac;
+    pt1->v[3] = id;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[1];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = ib;
+    pt1->v[2] = iab;
+    pt1->v[3] = ic;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[3];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = tabref[2];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = ic;
+    pt1->v[2] = iac;
+    pt1->v[3] = icd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[1];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = -1;
+  }
+  else if ( ( ib > ic ) && ( id > ia ) ) { /*tetra45.mesh*/ 
+    pt->v[0] = ia;
+    pt->v[1] = id;
+    pt->v[2] = ibd;
+    pt->v[3] = icd;
+    pt->qual = MMG_caltet(mesh,sol,iel); 
+    pt->tabedg = 0;
+    pt->flag = mesh->flag; 
+    pt->bdryref[0] = tabref[0];
+    pt->bdryref[1] = -1;
+    pt->bdryref[2] = tabref[1];
+    pt->bdryref[3] = tabref[2];
+    
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = icd;
+    pt1->v[1] = iac;
+    pt1->v[2] = ibd;
+    pt1->v[3] = ia;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[1];
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iac;
+    pt1->v[1] = ic;
+    pt1->v[2] = ibd;
+    pt1->v[3] = iab;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[3];
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ia;
+    pt1->v[1] = iab;
+    pt1->v[2] = iac;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = tabref[3];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = ib;
+    pt1->v[2] = iab;
+    pt1->v[3] = ic;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[3];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = tabref[2];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = ic;
+    pt1->v[2] = iac;
+    pt1->v[3] = icd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[1];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = -1;
+  }
+  else if ( ( ic > ib ) && ( ia > id ) ) { /*tetrap52.mesh*/ 
+    pt->v[0] = ib;
+    pt->v[1] = icd;
+    pt->v[2] = iab;
+    pt->v[3] = ibd;
+    pt->qual = MMG_caltet(mesh,sol,iel); 
+    pt->tabedg = 0;
+    pt->flag = mesh->flag; 
+    pt->bdryref[0] = -1;
+    pt->bdryref[1] = tabref[2];
+    pt->bdryref[2] = tabref[0];
+    pt->bdryref[3] = -1;
+    
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iac;
+    pt1->v[1] = iab;
+    pt1->v[2] = icd;
+    pt1->v[3] = id;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[1];
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = id;
+    pt1->v[1] = iab;
+    pt1->v[2] = icd;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[0];
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iac;
+    pt1->v[1] = ia;
+    pt1->v[2] = iab;
+    pt1->v[3] = id;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[2];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[1];
+    pt1->bdryref[3] = tabref[3];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iac;
+    pt1->v[1] = icd;
+    pt1->v[2] = iab;
+    pt1->v[3] = ib;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[3];
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ic;
+    pt1->v[1] = ib;
+    pt1->v[2] = icd;
+    pt1->v[3] = iac;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[1];
+    pt1->bdryref[2] = tabref[3];
+    pt1->bdryref[3] = tabref[0];
+  }
+  else { /*tetrap54.mesh*/ 
+    assert(( ic > ib ) && ( id > ia ) );
+    pt->v[0] = ib;
+    pt->v[1] = icd;
+    pt->v[2] = iab;
+    pt->v[3] = ibd;
+    pt->qual = MMG_caltet(mesh,sol,iel); 
+    pt->tabedg = 0;
+    pt->flag = mesh->flag; 
+    pt->bdryref[0] = -1;
+    pt->bdryref[1] = tabref[2];
+    pt->bdryref[2] = tabref[0];
+    pt->bdryref[3] = -1;
+    
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = icd;
+    pt1->v[1] = ia;
+    pt1->v[2] = iac;
+    pt1->v[3] = iab;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[3];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[1];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = icd;
+    pt1->v[2] = iab;
+    pt1->v[3] = ia;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[2];
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = -1;
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = id;
+    pt1->v[1] = ia;
+    pt1->v[2] = icd;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[0];
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = tabref[1];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iac;
+    pt1->v[1] = iab;
+    pt1->v[2] = ib;
+    pt1->v[3] = icd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = tabref[3];
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ic;
+    pt1->v[1] = ib;
+    pt1->v[2] = icd;
+    pt1->v[3] = iac;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[1];
+    pt1->bdryref[2] = tabref[3];
+    pt1->bdryref[3] = tabref[0];
+  }
+   
+  return(1); 
+}
+
+int MMG_pattern5(pMesh mesh,pSol sol,pHedge hash, int iel) { 
+  pTetra     pt,pt1;
+  int        jel,ia,ib,ic,id,iac,icd,ibd,ibc,iad,i,tabref[4];
+  
+  pt = &mesh->tetra[iel];
+  for (i=0 ; i<4 ; i++) 
+    tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]];   
+
+  if(pt->tabedg != 62) {
+    ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]];
+    ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]];
+    ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]];
+    id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]];
+  } else {
+    ia = pt->v[0];
+    ib = pt->v[1];
+    ic = pt->v[2];
+    id = pt->v[3];
+  } 
+  iac = MMG_edgePoint(hash,ia,ic); 
+  assert(iac>0);
+  ibc = MMG_edgePoint(hash,ib,ic); 
+  assert(ibc>0);
+  ibd = MMG_edgePoint(hash,ib,id); 
+  assert(ibd>0);
+  icd = MMG_edgePoint(hash,ic,id); 
+  assert(icd>0);
+  iad = MMG_edgePoint(hash,ia,id); 
+  assert(iad>0); 
+	if(0 && (iel==8778 || iel==6508 )) ddebug = 1;   
+	if(iel==6512) ddebug=1;
+  if(ddebug) printf("tet %d : %d %d %d %d\n",iel,ia,ib,ic,id);    
+	if(ddebug) printf("cas %d : %d %d %d %d\n",pt->tabedg,pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
+  if(ddebug) printf("bdyref      %d %d %d %d\n",pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]);
+  if(ddebug) printf("tabref      %d %d %d %d\n",tabref[0],tabref[1],tabref[2],tabref[3]);
+  if ( ( ia > ib ) ) { /*tetra_p51.mesh*/
+    pt->v[0] = ibc;
+    pt->v[1] = ic;
+    pt->v[2] = iac;
+    pt->v[3] = icd;
+    pt->qual = MMG_caltet(mesh,sol,iel); 
+    pt->tabedg = 0;
+    pt->flag = mesh->flag; 
+    pt->bdryref[0] = tabref[1];
+    pt->bdryref[1] = -1;
+    pt->bdryref[2] = tabref[0];
+    pt->bdryref[3] = tabref[3];
+		if(ddebug) printf("1 : on change %d : %d %d %d %d\n",iel,pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]);
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibc;
+    pt1->v[1] = icd;
+    pt1->v[2] = iad;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = -1;
+		if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]);
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = icd;
+    pt1->v[2] = iad;
+    pt1->v[3] = id;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[1];
+    pt1->bdryref[1] = tabref[2];
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = -1;
+		if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]);
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibc;
+    pt1->v[1] = icd;
+    pt1->v[2] = iac;
+    pt1->v[3] = iad;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[1];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = -1;
+		if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]);
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ib;
+    pt1->v[1] = ibc;
+    pt1->v[2] = iad;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = tabref[2];
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = -1;
+		if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]);
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ib;
+    pt1->v[1] = ia;
+    pt1->v[2] = iad;
+    pt1->v[3] = iac;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+		pt1->bdryref[0] = tabref[1];
+		pt1->bdryref[1] = -1;//tabref[2];
+    pt1->bdryref[2] = tabref[3];//tabref[3];
+    pt1->bdryref[3] = tabref[2];//-1;
+		if(ddebug) printf("--on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]);
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibc;
+    pt1->v[1] = ib;
+    pt1->v[2] = iad;
+    pt1->v[3] = iac;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[3];
+    pt1->bdryref[3] = -1;
+		if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]);
+  }
+  else { /*tetra_p54.mesh*/  
+    pt->v[0] = ibc;
+    pt->v[1] = ic;
+    pt->v[2] = iac;
+    pt->v[3] = icd;
+    pt->qual = MMG_caltet(mesh,sol,iel); 
+    pt->tabedg = 0;
+    pt->flag = mesh->flag; 
+    pt->bdryref[0] = tabref[1];
+    pt->bdryref[1] = -1;
+    pt->bdryref[2] = tabref[0];
+    pt->bdryref[3] = tabref[3];
+		if(ddebug) printf("2 : on change %d : %d %d %d %d\n",iel,pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]);
+    
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = icd;
+    pt1->v[2] = iad;
+    pt1->v[3] = id;    
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[1];
+    pt1->bdryref[1] = tabref[2];
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = -1;
+		if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]);
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iac;
+    pt1->v[1] = ibd;
+    pt1->v[2] = iad;
+    pt1->v[3] = ia;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[2];
+    pt1->bdryref[1] = tabref[1];
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = -1;
+		if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]);
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = iac;
+    pt1->v[1] = ia;
+    pt1->v[2] = ibc;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;//tabref[3];
+    pt1->bdryref[3] = tabref[3];//-1;
+		if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]);
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ia;
+    pt1->v[1] = ib;
+    pt1->v[2] = ibc;
+    pt1->v[3] = ibd;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[0];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[2];
+    pt1->bdryref[3] = tabref[3];
+		if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]);
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = ibd;
+    pt1->v[1] = iad;
+    pt1->v[2] = icd;
+    pt1->v[3] = iac;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;
+    pt1->bdryref[0] = tabref[1];
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = -1;
+    pt1->bdryref[3] = -1;
+		if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]);
+
+    jel = MMG_newElt(mesh);
+    pt1 = &mesh->tetra[jel];
+    pt1->v[0] = icd;
+    pt1->v[1] = ibd;
+    pt1->v[2] = iac;
+    pt1->v[3] = ibc;
+    pt1->qual = MMG_caltet(mesh,sol,jel);
+    pt1->ref  = pt->ref;
+    pt1->flag = mesh->flag;  
+    pt1->bdryref[0] = -1;
+    pt1->bdryref[1] = -1;
+    pt1->bdryref[2] = tabref[0];
+    pt1->bdryref[3] = -1;
+		if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]);
+  }
+	ddebug = 0; 
+  return(1); 
+}
+
+//insert ip02 on ip0ip2 etc...
+
+/*create 8 tets
+ip02 ip0 ip01 ip03
+ip01 ip1 ip12 ip13
+ip12 ip2 ip02 ip23
+ip23 ip3 ip03 ip13
+ip02 i12 ip03 ip01
+ip01 ip03 ip13 ip12
+ip12 ip03 ip23 ip02
+ip23 ip12 ip13 ip03
+*/
+int MMG_pattern6(pMesh mesh,pSol sol,int jel,int *ipa) {
+  pTetra     pt,pt1;
+  int        iel,ip0,ip1,ip2,ip3,i,tabref[4]; 
+
+  pt1 = &mesh->tetra[jel];
+  for (i=0 ; i<4 ; i++) 
+    tabref[i] = pt1->bdryref[i]; 
+
+
+  ip0 = pt1->v[0];
+  ip1 = pt1->v[1];
+  ip2 = pt1->v[2];
+  ip3 = pt1->v[3];
+	ddebug = 0;
+  if(ddebug) printf("tet %d : %d %d %d %d\n",jel,ip0,ip1,ip2,ip3);
+  if(ddebug) printf("bdyref      %d %d %d %d\n",pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]);
+  if(ddebug) printf("tabref      %d %d %d %d\n",tabref[0],tabref[1],tabref[2],tabref[3]);
+	ddebug = 0;
+  
+  pt1->v[0] = ipa[1];
+  pt1->v[1] = ip0;
+  pt1->v[2] = ipa[0];
+  pt1->v[3] = ipa[2];
+  pt1->qual = MMG_caltet(mesh,sol,jel);
+  pt1->tabedg = 0;
+  pt1->flag = mesh->flag;
+  pt1->bdryref[0] = tabref[2];
+  pt1->bdryref[1] = -1;
+  pt1->bdryref[2] = tabref[1];
+  pt1->bdryref[3] = tabref[3];
+
+  iel = MMG_newElt(mesh);
+  pt = &mesh->tetra[iel];
+  pt->v[0] = ipa[0];
+  pt->v[1] = ip1;
+  pt->v[2] = ipa[3];
+  pt->v[3] = ipa[4];
+  pt->qual = MMG_caltet(mesh,sol,iel);
+  pt->ref  = pt1->ref;
+  pt->flag = mesh->flag;
+  pt->bdryref[0] = tabref[0];
+  pt->bdryref[1] = -1;
+  pt->bdryref[2] = tabref[2];
+  pt->bdryref[3] = tabref[3];
+	// printf("on cree %d : %d %d %d %d\n",iel,pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]);
+  iel = MMG_newElt(mesh);
+  pt = &mesh->tetra[iel];
+  pt->v[0] = ipa[3];
+  pt->v[1] = ip2;
+  pt->v[2] = ipa[1];
+  pt->v[3] = ipa[5];
+  pt->qual = MMG_caltet(mesh,sol,iel);
+  pt->ref  = pt1->ref;
+  pt->flag = mesh->flag;
+  pt->bdryref[0] = tabref[1];
+  pt->bdryref[1] = -1;
+  pt->bdryref[2] = tabref[0];
+  pt->bdryref[3] = tabref[3];
+	// printf("on cree %d : %d %d %d %d\n",iel,pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]);
+
+  iel = MMG_newElt(mesh);
+  pt = &mesh->tetra[iel];
+  pt->v[0] = ipa[5];
+  pt->v[1] = ip3;
+  pt->v[2] = ipa[2];
+  pt->v[3] = ipa[4];
+  pt->qual = MMG_caltet(mesh,sol,iel);
+  pt->ref  = pt1->ref;
+  pt->flag = mesh->flag;
+  pt->bdryref[0] = tabref[2];
+  pt->bdryref[1] = -1;
+  pt->bdryref[2] = tabref[0];
+  pt->bdryref[3] = tabref[1];
+	// printf("on cree %d : %d %d %d %d\n",iel,pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]);
+ 
+  iel = MMG_newElt(mesh);
+  pt = &mesh->tetra[iel];
+  pt->v[0] = ipa[1];
+  pt->v[1] = ipa[3];
+  pt->v[2] = ipa[2];
+  pt->v[3] = ipa[0];
+  pt->qual = MMG_caltet(mesh,sol,iel);
+  pt->ref  = pt1->ref;
+  pt->flag = mesh->flag;
+  pt->bdryref[0] = -1;
+  pt->bdryref[1] = -1;
+  pt->bdryref[2] = tabref[3];
+  pt->bdryref[3] = -1;
+	// printf("on cree %d : %d %d %d %d\n",iel,pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]);
+
+  iel = MMG_newElt(mesh);
+  pt = &mesh->tetra[iel];
+  pt->v[0] = ipa[0];
+  pt->v[1] = ipa[2];
+  pt->v[2] = ipa[4];
+  pt->v[3] = ipa[3];
+  pt->qual = MMG_caltet(mesh,sol,iel);
+  pt->ref  = pt1->ref;
+  pt->flag = mesh->flag;
+  pt->bdryref[0] = -1;
+  pt->bdryref[1] = -1;
+  pt->bdryref[2] = -1;
+  pt->bdryref[3] = tabref[2];
+	// printf("on cree %d : %d %d %d %d\n",iel,pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]);
+
+  iel = MMG_newElt(mesh);
+  pt = &mesh->tetra[iel];
+  pt->v[0] = ipa[3];
+  pt->v[1] = ipa[2];
+  pt->v[2] = ipa[5];
+  pt->v[3] = ipa[1];
+  pt->qual = MMG_caltet(mesh,sol,iel);
+  pt->ref  = pt1->ref;
+  pt->flag = mesh->flag;
+  pt->bdryref[0] = tabref[1];
+  pt->bdryref[1] = -1;
+  pt->bdryref[2] = -1;
+  pt->bdryref[3] = -1;
+	// printf("on cree %d : %d %d %d %d\n",iel,pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]);
+
+  iel = MMG_newElt(mesh);
+  pt = &mesh->tetra[iel];
+  pt->v[0] = ipa[5];
+  pt->v[1] = ipa[3];
+  pt->v[2] = ipa[4];
+  pt->v[3] = ipa[2];
+  pt->qual = MMG_caltet(mesh,sol,iel);
+  pt->ref  = pt1->ref;
+  pt->flag = mesh->flag;
+  pt->bdryref[0] = -1;
+  pt->bdryref[1] = -1;
+  pt->bdryref[2] = -1;
+  pt->bdryref[3] = tabref[0];
+	// printf("on cree %d : %d %d %d %d\n",iel,pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]);
+  //printf("on cut 6\n");
+  //exit(1);              
+  return(1);
+}
+
diff --git a/contrib/mmg3d/build/sources/quality.c b/contrib/mmg3d/build/sources/quality.c
new file mode 100644
index 0000000000000000000000000000000000000000..7a78991ac0f4f6ec3c5c6c4788653ea05ed761a2
--- /dev/null
+++ b/contrib/mmg3d/build/sources/quality.c
@@ -0,0 +1,1745 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"  
+
+
+double MMG_rao(pMesh mesh,int k,int inm);
+double MMG_caltetrao(pMesh mesh,pSol sol,int iel) {
+	return(MMG_rao(mesh,iel,0));
+}
+
+/* compute tetra volume */
+double MMG_voltet(pMesh mesh,int iel) {
+  pTetra   pt;
+  pPoint   p1,p2,p3,p4;
+  double   ax,ay,az,bx,by,bz,vol,len;
+  int      s1,s2,s3,s4;
+
+  pt = &mesh->tetra[iel];
+  s1 = pt->v[0];
+  s2 = pt->v[1];
+  s3 = pt->v[2];
+  s4 = pt->v[3];
+
+  /* sort tetra vertices */
+  if ( pt->v[0] < pt->v[1] ) {
+    if ( pt->v[0] < pt->v[2] ) {
+      s3 = pt->v[2];
+      if ( pt->v[0] < pt->v[3] ) {
+        s1 = pt->v[0];
+	      s2 = pt->v[1];
+	      s4 = pt->v[3];
+      }
+      else {
+        s1 = pt->v[3];
+	      s2 = pt->v[0];
+	      s4 = pt->v[1];
+      }
+    }
+    else {
+      s2 = pt->v[0];
+      if ( pt->v[2] < pt->v[3] ) {
+        s1 = pt->v[2];
+	      s3 = pt->v[1];
+	      s4 = pt->v[3];
+      }
+      else {
+        s1 = pt->v[3];
+	      s3 = pt->v[2];
+	      s4 = pt->v[1];
+      }
+    }
+  }
+  else {
+    if ( pt->v[1] < pt->v[2] ) {
+      if ( pt->v[1] < pt->v[3] ) {
+        s1 = pt->v[1];
+	      s2 = pt->v[2];
+        s3 = pt->v[0];
+	      s4 = pt->v[3];
+      }
+      else {
+        s1 = pt->v[3];
+	      s2 = pt->v[0];
+        s3 = pt->v[2];
+	      s4 = pt->v[1];
+      }
+    }
+    else {
+      s2 = pt->v[0];
+      if ( pt->v[2] < pt->v[3] ) {
+        s1 = pt->v[2];
+        s3 = pt->v[1];
+        s4 = pt->v[3];
+      }
+      else {
+        s1 = pt->v[3];
+        s3 = pt->v[2];
+        s4 = pt->v[1];
+      }
+    }
+  }
+
+  p1 = &mesh->point[s1];
+  p2 = &mesh->point[s4];
+  p3 = &mesh->point[s2];
+  p4 = &mesh->point[s3];
+  if ( s2 < s3 ) {
+    if ( s2 < s4 ) {
+      p2 = &mesh->point[s2];
+      p3 = &mesh->point[s3];
+      p4 = &mesh->point[s4];
+    }
+  }
+  else if ( s3 < s4 ) {
+    p2 = &mesh->point[s3];
+    p3 = &mesh->point[s4];
+    p4 = &mesh->point[s2];
+  }
+
+  /* compute volume */
+  ax = p3->c[0] - p1->c[0];
+  ay = p3->c[1] - p1->c[1];
+  az = p3->c[2] - p1->c[2];
+
+  bx = p4->c[0] - p1->c[0];
+  by = p4->c[1] - p1->c[1];
+  bz = p4->c[2] - p1->c[2];
+  //printf("a %e %e %e \n",(ay*bz - az*by),(az*bx - ax*bz),(ax*by - ay*bx));
+  vol = (p2->c[0]-p1->c[0]) * (ay*bz - az*by) \
+      + (p2->c[1]-p1->c[1]) * (az*bx - ax*bz) \
+      + (p2->c[2]-p1->c[2]) * (ax*by - ay*bx);
+  //printf("%e %e %e\n",(p2->c[0]-p1->c[0]),(p2->c[1]-p1->c[1]),(p2->c[2]-p1->c[2]));
+  //printf("vol1 %e %e %e\n",(p2->c[0]-p1->c[0]) * (ay*bz - az*by),(p2->c[1]-p1->c[1]) * (az*bx - ax*bz),
+  //  (p2->c[2]-p1->c[2]) * (ax*by - ay*bx));
+  len = ax*ax+ay*ay+az*az;
+  len += bx*bx+by*by+bz*bz;
+  len += (p2->c[0]-p1->c[0])*(p2->c[0]-p1->c[0])+(p2->c[1]-p1->c[1])*(p2->c[1]-p1->c[1])
+       + (p2->c[2]-p1->c[2])*(p2->c[2]-p1->c[2]);
+  len += (p2->c[0]-p3->c[0])*(p2->c[0]-p3->c[0])+(p2->c[1]-p3->c[1])*(p2->c[1]-p3->c[1])
+       + (p2->c[2]-p3->c[2])*(p2->c[2]-p3->c[2]);
+  len += (p2->c[0]-p4->c[0])*(p2->c[0]-p4->c[0])+(p2->c[1]-p4->c[1])*(p2->c[1]-p4->c[1])
+       + (p2->c[2]-p4->c[2])*(p2->c[2]-p4->c[2]);
+  len += (p3->c[0]-p4->c[0])*(p3->c[0]-p4->c[0])+(p3->c[1]-p4->c[1])*(p3->c[1]-p4->c[1])
+       + (p3->c[2]-p4->c[2])*(p3->c[2]-p4->c[2]);    
+  len /= 6.;
+  len = sqrt(len);
+  len = len*len*len; 
+  //printf("vol %e %e\n",vol,len);       
+  vol /= len;
+  return(vol);
+}
+
+
+/* quick volume check */
+double MMG_quickvol(double *c1,double *c2,double *c3,double *c4) {
+  double   ax,ay,az,bx,by,bz,vol;
+
+  ax = c3[0] - c1[0];
+  ay = c3[1] - c1[1];
+  az = c3[2] - c1[2];
+  
+  bx = c4[0] - c1[0];
+  by = c4[1] - c1[1];
+  bz = c4[2] - c1[2];
+  
+  vol = (c2[0]-c1[0]) * (ay*bz - az*by) \
+      + (c2[1]-c1[1]) * (az*bx - ax*bz) \
+      + (c2[2]-c1[2]) * (ax*by - ay*bx);
+
+  return(vol);
+}
+
+
+/* compute tetra quality aniso */
+double MMG_caltet_ani(pMesh mesh,pSol sol,int iel) {
+  pTetra     pt;
+  double     cal,abx,aby,abz,acx,acy,acz,adx,ady,adz;
+  double     bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz;
+  double     h1,h2,h3,h4,h5,h6,det,vol,rap,v1,v2,v3,num;
+  double    *a,*b,*c,*d;
+  double     *ma,*mb,*mc,*md,mm[6];
+  int        j,ia,ib,ic,id,iadr;
+
+  cal = CALLIM;
+  pt  = &mesh->tetra[iel];
+  if ( !pt->v[0] )  return(cal);
+
+  ia = pt->v[0];
+  ib = pt->v[1];
+  ic = pt->v[2];
+  id = pt->v[3];
+
+  /* average metric */
+  memset(mm,0,6*sizeof(double));
+  iadr = (ia-1)*sol->offset + 1;
+  ma   = &sol->met[iadr];
+  iadr = (ib-1)*sol->offset + 1;
+  mb   = &sol->met[iadr];
+  iadr = (ic-1)*sol->offset + 1;
+  mc   = &sol->met[iadr];
+  iadr = (id-1)*sol->offset + 1;
+  md   = &sol->met[iadr];
+  for (j=0; j<6; j++)
+    mm[j] = 0.25 * (ma[j]+mb[j]+mc[j]+md[j]);
+  a = mesh->point[ia].c;
+  b = mesh->point[ib].c;
+  c = mesh->point[ic].c;
+  d = mesh->point[id].c;
+
+  /* volume */
+  abx = b[0] - a[0];
+  aby = b[1] - a[1];
+  abz = b[2] - a[2];
+
+  acx = c[0] - a[0];
+  acy = c[1] - a[1];
+  acz = c[2] - a[2];
+  
+  adx = d[0] - a[0];
+  ady = d[1] - a[1];
+  adz = d[2] - a[2];
+
+  v1  = acy*adz - acz*ady;
+  v2  = acz*adx - acx*adz;
+  v3  = acx*ady - acy*adx;
+  vol = abx * v1 + aby * v2 + abz * v3;            
+  if ( vol <= 0. )  return(cal);
+  det = mm[0] * ( mm[3]*mm[5] - mm[4]*mm[4]) \
+      - mm[1] * ( mm[1]*mm[5] - mm[2]*mm[4]) \
+      + mm[2] * ( mm[1]*mm[4] - mm[2]*mm[3]);   
+  if ( det < EPSOK )   {
+    //printf("--- INVALID METRIC : DET (%d) %e\n",iel,det);
+    return(cal);
+  }
+  det = sqrt(det) * vol;
+  /* edge lengths */
+  h1 =      mm[0]*abx*abx + mm[3]*aby*aby + mm[5]*abz*abz \
+     + 2.0*(mm[1]*abx*aby + mm[2]*abx*abz + mm[4]*aby*abz);
+  h2 =      mm[0]*acx*acx + mm[3]*acy*acy + mm[5]*acz*acz \
+     + 2.0*(mm[1]*acx*acy + mm[2]*acx*acz + mm[4]*acy*acz);
+  h3 =      mm[0]*adx*adx + mm[3]*ady*ady + mm[5]*adz*adz \
+     + 2.0*(mm[1]*adx*ady + mm[2]*adx*adz + mm[4]*ady*adz);
+
+  bcx = c[0] - b[0];
+  bcy = c[1] - b[1];
+  bcz = c[2] - b[2];
+
+  bdx = d[0] - b[0];
+  bdy = d[1] - b[1];
+  bdz = d[2] - b[2];
+
+  cdx = d[0] - c[0];
+  cdy = d[1] - c[1];
+  cdz = d[2] - c[2];
+
+  h4 =      mm[0]*bdx*bdx + mm[3]*bdy*bdy + mm[5]*bdz*bdz \
+     + 2.0*(mm[1]*bdx*bdy + mm[2]*bdx*bdz + mm[4]*bdy*bdz);
+  h5 =      mm[0]*cdx*cdx + mm[3]*cdy*cdy + mm[5]*cdz*cdz \
+     + 2.0*(mm[1]*cdx*cdy + mm[2]*cdx*cdz + mm[4]*cdy*cdz);
+  h6 =      mm[0]*bcx*bcx + mm[3]*bcy*bcy + mm[5]*bcz*bcz \
+     + 2.0*(mm[1]*bcx*bcy + mm[2]*bcx*bcz + mm[4]*bcy*bcz);
+
+  /* quality */
+  rap = h1 + h2 + h3 + h4 + h5 + h6;
+  num = sqrt(rap) * rap;  
+  //if ( det > EPS1 * num )  completement arbitraire comme seuil!!!!
+  cal = num / det;  
+  if(cal >= CALLIM) printf(" %d %e %e %e %e\n",iel,cal,num,det,vol);  
+  
+  assert(cal < CALLIM);
+  return(cal);
+}
+
+/* compute tetra quality iso */
+double MMG_caltet5_iso(pMesh mesh,pSol sol,int iel) {
+  pTetra     pt;
+  double     cal,abx,aby,abz,acx,acy,acz,adx,ady,adz;
+  double     bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz;
+  double     h1,h2,h3,h4,h5,h6,vol,v1,v2,v3,rap,num;
+  double    *a,*b,*c,*d;
+  int        ia,ib,ic,id;
+double h;
+
+  cal = CALLIM;
+  pt = &mesh->tetra[iel];
+  if ( !pt->v[0] )  return(cal);
+
+  ia = pt->v[0];
+  ib = pt->v[1];
+  ic = pt->v[2];
+  id = pt->v[3];
+  a  = mesh->point[ia].c;
+  b  = mesh->point[ib].c;
+  c  = mesh->point[ic].c;
+  d  = mesh->point[id].c;
+  
+  h1 = sol->met[ia];
+  h2 = sol->met[ib];
+  h3 = sol->met[ic];
+  h4 = sol->met[id];
+  h  = 0.25*(h1 + h2 + h3 + h4);
+
+  /* volume */
+  abx = b[0] - a[0];
+  aby = b[1] - a[1];
+  abz = b[2] - a[2];
+
+  acx = c[0] - a[0];
+  acy = c[1] - a[1];
+  acz = c[2] - a[2];
+  
+  adx = d[0] - a[0];
+  ady = d[1] - a[1];
+  adz = d[2] - a[2];
+
+  v1  = acy*adz - acz*ady;
+  v2  = acz*adx - acx*adz;
+  v3  = acx*ady - acy*adx;
+  vol = abx * v1 + aby * v2 + abz * v3;
+  if ( vol <= 0. )  return(cal);
+
+  /* max edge */
+  h1 = abx*abx + aby*aby + abz*abz;
+  h2 = acx*acx + acy*acy + acz*acz;
+  h3 = adx*adx + ady*ady + adz*adz;
+
+  bcx = c[0] - b[0];
+  bcy = c[1] - b[1];
+  bcz = c[2] - b[2];
+
+  bdx = d[0] - b[0];
+  bdy = d[1] - b[1];
+  bdz = d[2] - b[2];
+
+  cdx = d[0] - c[0];
+  cdy = d[1] - c[1];
+  cdz = d[2] - c[2];
+
+  h4 = bdx*bdx + bdy*bdy + bdz*bdz;
+  h5 = cdx*cdx + cdy*cdy + cdz*cdz;
+  h6 = bcx*bcx + bcy*bcy + bcz*bcz;
+
+  /* quality */
+  rap = h1*h1 + h2*h2 + h3*h3 + h4*h4 + h5*h5 + h6*h6;
+  num = sqrt(rap) * rap;
+  cal = num / vol;
+  assert( cal < CALLIM );
+
+  return(cal);
+}          
+
+
+/* compute tetra quality iso */
+double MMG_caltet_iso(pMesh mesh,pSol sol,int iel) {
+  pTetra     pt;
+  double     cal,abx,aby,abz,acx,acy,acz,adx,ady,adz;
+  double     bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz;
+  double     h1,h2,h3,h4,h5,h6,vol,v1,v2,v3,rap,num;
+  double    *a,*b,*c,*d;
+  int        ia,ib,ic,id;
+
+  cal = CALLIM;
+  pt = &mesh->tetra[iel];  
+  if ( !pt->v[0] )  return(cal);
+
+  ia = pt->v[0];
+  ib = pt->v[1];
+  ic = pt->v[2];
+  id = pt->v[3];
+  a  = mesh->point[ia].c;
+  b  = mesh->point[ib].c;
+  c  = mesh->point[ic].c;
+  d  = mesh->point[id].c;
+  
+  /* volume */
+  abx = b[0] - a[0];
+  aby = b[1] - a[1];
+  abz = b[2] - a[2];
+
+  acx = c[0] - a[0];
+  acy = c[1] - a[1];
+  acz = c[2] - a[2];
+  
+  adx = d[0] - a[0];
+  ady = d[1] - a[1];
+  adz = d[2] - a[2];
+
+  v1  = acy*adz - acz*ady;
+  v2  = acz*adx - acx*adz;
+  v3  = acx*ady - acy*adx;
+  vol = abx * v1 + aby * v2 + abz * v3;   
+  if ( vol <= 0. )  {
+      /*tmp = pt->v[2];
+      pt->v[2] =pt->v[1];
+      pt->v[1] = tmp;*/  
+        //printf("arg on a un vol nul!!%8e \n ",vol);
+      return(cal);}
+
+  /* max edge */
+  h1 = abx*abx + aby*aby + abz*abz;
+  h2 = acx*acx + acy*acy + acz*acz;
+  h3 = adx*adx + ady*ady + adz*adz;
+
+  bcx = c[0] - b[0];
+  bcy = c[1] - b[1];
+  bcz = c[2] - b[2];
+
+  bdx = d[0] - b[0];
+  bdy = d[1] - b[1];
+  bdz = d[2] - b[2];
+
+  cdx = d[0] - c[0];
+  cdy = d[1] - c[1];
+  cdz = d[2] - c[2];
+
+  h4 = bdx*bdx + bdy*bdy + bdz*bdz;
+  h5 = cdx*cdx + cdy*cdy + cdz*cdz;
+  h6 = bcx*bcx + bcy*bcy + bcz*bcz;
+
+  /* quality */
+  rap = h1 + h2 + h3 + h4 + h5 + h6;
+  num = sqrt(rap) * rap;
+  //if ( vol > EPS1 * num ) completement arbitraire comme seuil!!!!    
+  cal = num / vol;
+  assert( cal < CALLIM );
+
+  return(cal);
+}
+
+
+static double determ(double ab[3],double ac[3],double *mm) {
+  double    a1,a2,a3,a4,a5,a6,m0,m1,m2,m3;
+
+  a1 = mm[0]*ab[0] + mm[1]*ab[1] + mm[2]*ab[2];
+  a2 = mm[1]*ab[0] + mm[3]*ab[1] + mm[4]*ab[2];
+  a3 = mm[2]*ab[0] + mm[4]*ab[1] + mm[5]*ab[2];
+
+  a4 = mm[0]*ac[0] + mm[1]*ac[1] + mm[2]*ac[2];
+  a5 = mm[1]*ac[0] + mm[3]*ac[1] + mm[4]*ac[2];
+  a6 = mm[2]*ac[0] + mm[4]*ac[1] + mm[5]*ac[2];
+
+  m0 = a1*ab[0] + a2*ab[1] + a3*ab[2];
+  m1 = a4*ab[0] + a5*ab[1] + a6*ab[2];
+  m2 = a1*ac[0] + a2*ac[1] + a3*ac[2];
+  m3 = a4*ac[0] + a5*ac[1] + a6*ac[2];
+
+  return(m0*m3 - m1*m2);
+}
+
+
+/* compute tetra quality for output (same as GHS3D)
+   note: must be normalized by ALPHAC  */
+double MMG_calte1_ani(pMesh mesh,pSol sol,int iel) {
+  pTetra     pt;
+  double     cal,ab[3],ac[3],ad[3],bc[3],bd[3],cd[3];
+  double     h1,h2,h3,h4,h5,h6,rapmax,vol,det,v1,v2,v3;
+  double     air,dd,num;
+  double    *a,*b,*c,*d;
+  double     *ma,*mb,*mc,*md,mm[6];;
+  int        j,ia,ib,ic,id,iadr;
+
+  pt = &mesh->tetra[iel];
+  if ( !pt->v[0] )  return(0.0);
+  cal = CALLIM;
+
+  ia = pt->v[0];
+  ib = pt->v[1];
+  ic = pt->v[2];
+  id = pt->v[3];
+
+  /* average metric */
+  memset(mm,0,6*sizeof(double));
+  iadr = (ia-1)*sol->offset + 1;
+  ma   = &sol->met[iadr];
+  iadr = (ib-1)*sol->offset + 1;
+  mb   = &sol->met[iadr];
+  iadr = (ic-1)*sol->offset + 1;
+  mc   = &sol->met[iadr];
+  iadr = (id-1)*sol->offset + 1;
+  md   = &sol->met[iadr];
+  for (j=0; j<6; j++)
+    mm[j] = 0.25 * (ma[j]+mb[j]+mc[j]+md[j]);
+
+  a  = mesh->point[ia].c;
+  b  = mesh->point[ib].c;
+  c  = mesh->point[ic].c;
+  d  = mesh->point[id].c;
+
+  /* volume */
+  ab[0] = b[0] - a[0];
+  ab[1] = b[1] - a[1];
+  ab[2] = b[2] - a[2];
+
+  ac[0] = c[0] - a[0];
+  ac[1] = c[1] - a[1];
+  ac[2] = c[2] - a[2];
+  
+  ad[0] = d[0] - a[0];
+  ad[1] = d[1] - a[1];
+  ad[2] = d[2] - a[2];
+
+  v1  = ac[1]*ad[2] - ac[2]*ad[1];
+  v2  = ac[2]*ad[0] - ac[0]*ad[2];
+  v3  = ac[0]*ad[1] - ac[1]*ad[0];
+  vol = ab[0] * v1 + ab[1] * v2 + ab[2] * v3;
+  if ( vol <= 0. )  return(cal);
+
+  det = mm[0] * ( mm[3]*mm[5] - mm[4]*mm[4]) \
+      - mm[1] * ( mm[1]*mm[5] - mm[2]*mm[4]) \
+      + mm[2] * ( mm[1]*mm[4] - mm[2]*mm[3]);
+  if ( det < EPSOK )  {
+    if(iel) printf("INVALID METRIC : DET (%d) %e\n",iel,det);
+    return(cal);
+  }
+  det = sqrt(det) * vol;
+
+  /* edge lengths */
+  rapmax = 0.0;
+  h1 =      mm[0]*ab[0]*ab[0] + mm[3]*ab[1]*ab[1] + mm[5]*ab[2]*ab[2] \
+     + 2.0*(mm[1]*ab[0]*ab[1] + mm[2]*ab[0]*ab[2] + mm[4]*ab[1]*ab[2]);
+  rapmax = M_MAX(rapmax,h1); 
+  h2 =      mm[0]*ac[0]*ac[0] + mm[3]*ac[1]*ac[1] + mm[5]*ac[2]*ac[2] \
+     + 2.0*(mm[1]*ac[0]*ac[1] + mm[2]*ac[0]*ac[2] + mm[4]*ac[1]*ac[2]);
+  rapmax = M_MAX(rapmax,h2); 
+  h3 =      mm[0]*ad[0]*ad[0] + mm[3]*ad[1]*ad[1] + mm[5]*ad[2]*ad[2] \
+     + 2.0*(mm[1]*ad[0]*ad[1] + mm[2]*ad[0]*ad[2] + mm[4]*ad[1]*ad[2]);
+  rapmax = M_MAX(rapmax,h3); 
+
+  bc[0] = c[0] - b[0];
+  bc[1] = c[1] - b[1];
+  bc[2] = c[2] - b[2];
+
+  bd[0] = d[0] - b[0];
+  bd[1] = d[1] - b[1];
+  bd[2] = d[2] - b[2];
+
+  cd[0] = d[0] - c[0];
+  cd[1] = d[1] - c[1];
+  cd[2] = d[2] - c[2];
+
+  h4 =      mm[0]*bd[0]*bd[0] + mm[3]*bd[1]*bd[1] + mm[5]*bd[2]*bd[2] \
+     + 2.0*(mm[1]*bd[0]*bd[1] + mm[2]*bd[0]*bd[2] + mm[4]*bd[1]*bd[2]);
+  rapmax = M_MAX(rapmax,h4); 
+  h5 =      mm[0]*cd[0]*cd[0] + mm[3]*cd[1]*cd[1] + mm[5]*cd[2]*cd[2] \
+     + 2.0*(mm[1]*cd[0]*cd[1] + mm[2]*cd[0]*cd[2] + mm[4]*cd[1]*cd[2]);
+  rapmax = M_MAX(rapmax,h5); 
+  h6 =      mm[0]*bc[0]*bc[0] + mm[3]*bc[1]*bc[1] + mm[5]*bc[2]*bc[2] \
+     + 2.0*(mm[1]*bc[0]*bc[1] + mm[2]*bc[0]*bc[2] + mm[4]*bc[1]*bc[2]);
+  rapmax = M_MAX(rapmax,h6); 
+
+  /* surfaces */
+  dd  = determ(bd,bc,mm);
+  air = sqrt(dd);
+
+  dd   = determ(ac,ad,mm);
+  air += sqrt(dd);
+
+  dd   = determ(ad,ab,mm);
+  air += sqrt(dd);
+
+  dd   = determ(ab,ac,mm);
+  air += sqrt(dd);
+  
+  /* quality */
+  num = sqrt(rapmax) * air;
+  cal = num / det;
+  assert( cal < CALLIM );
+
+  return(cal);
+}
+
+
+double MMG_calte1_iso(pMesh mesh,pSol sol,int iel) {
+  pTetra     pt;
+  double     cal,abx,aby,abz,acx,acy,acz,adx,ady,adz;
+  double     bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz;
+  double     h1,h2,h3,h4,h5,h6,rapmax,vol,v1,v2,v3;
+  double     s1,s2,s3,s4,dd,d2,num;
+  double    *a,*b,*c,*d;
+  int        ia,ib,ic,id;
+
+  cal = CALLIM;
+  pt = &mesh->tetra[iel];
+  if ( !pt->v[0] )  return(cal);
+
+  ia = pt->v[0];
+  ib = pt->v[1];
+  ic = pt->v[2];
+  id = pt->v[3];
+  a  = mesh->point[ia].c;
+  b  = mesh->point[ib].c;
+  c  = mesh->point[ic].c;
+  d  = mesh->point[id].c;
+
+  /* volume */
+  abx = b[0] - a[0];
+  aby = b[1] - a[1];
+  abz = b[2] - a[2];
+
+  acx = c[0] - a[0];
+  acy = c[1] - a[1];
+  acz = c[2] - a[2];
+ 
+  adx = d[0] - a[0];
+  ady = d[1] - a[1];
+  adz = d[2] - a[2];
+
+  v1  = acy*adz - acz*ady;
+  v2  = acz*adx - acx*adz;
+  v3  = acx*ady - acy*adx;
+  vol = abx * v1 + aby * v2 + abz * v3;
+  if ( vol <= 0. )  return(cal);
+
+  /* max edge */
+  rapmax = 0.0;
+  h1 = abx*abx + aby*aby + abz*abz;
+  rapmax = M_MAX(rapmax,h1);
+  h2 = acx*acx + acy*acy + acz*acz;
+  rapmax = M_MAX(rapmax,h2);
+  h3 = adx*adx + ady*ady + adz*adz;
+  rapmax = M_MAX(rapmax,h3);
+
+  bcx = c[0] - b[0];
+  bcy = c[1] - b[1];
+  bcz = c[2] - b[2];
+
+  bdx = d[0] - b[0];
+  bdy = d[1] - b[1];
+  bdz = d[2] - b[2];
+
+  cdx = d[0] - c[0];
+  cdy = d[1] - c[1];
+  cdz = d[2] - c[2];
+
+  h4 = bdx*bdx + bdy*bdy + bdz*bdz;
+  rapmax = M_MAX(rapmax,h4);
+  h5 = cdx*cdx + cdy*cdy + cdz*cdz;
+  rapmax = M_MAX(rapmax,h5);
+  h6 = bcx*bcx + bcy*bcy + bcz*bcz;
+  rapmax = M_MAX(rapmax,h6);
+
+  /* surface */
+  dd = cdy*bdz - cdz*bdy;
+  d2 = dd * dd;
+  dd = cdz*bdx - cdx*bdz;
+  d2 = d2 + dd * dd;
+  dd = cdx*bdy - cdy*bdx;
+  d2 = d2 + dd * dd;
+  s1 = sqrt(d2);
+  
+  s2 = sqrt(v1*v1 + v2*v2 + v3*v3);
+  
+  dd = bdy*adz - bdz*ady;
+  d2 = dd * dd;
+  dd = bdz*adx - bdx*adz;
+  d2 = d2 + dd * dd;
+  dd = bdx*ady - bdy*adx;
+  d2 = d2 + dd * dd;
+  s3 = sqrt(d2);
+
+  dd = aby*acz - abz*acy;
+  d2 = dd * dd;
+  dd = abz*acx - abx*acz;
+  d2 = d2 + dd * dd;
+  dd = abx*acy - aby*acx;
+  d2 = d2 + dd * dd;
+  s4 = sqrt(d2);
+
+  /* quality */
+  num = sqrt(rapmax) * (s1+s2+s3+s4);
+  cal = num / vol;
+  assert( cal < CALLIM );
+
+  return(cal);
+}
+
+/* compute tetra quality aniso : (ia ib ic id) and (ie ib id ic) */
+int MMG_caltet2_ani(pMesh mesh,pSol sol,int iel,int ie,double crit, double * caltab) {
+  pTetra     pt;
+  double     cal,acx,acy,acz,adx,ady,adz;
+  double     bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz,bax,bay,baz;
+  double     bex,bey,bez,ecx,ecy,ecz,edx,edy,edz;
+  double     h1,h2,h3,h4,h5,h6,det,dete,vol,vole,rap,v1,v2,v3;
+  double     h1e,h2e,h3e,h4e,h5e,h6e,num;
+  double    *a,*b,*c,*d,*e;
+  double     *ma,*mb,*mc,*md,mm[6],mme[6],*me;
+  int        j,ia,ib,ic,id,iadr;
+
+  cal       = CALLIM;
+  caltab[0] = cal;
+  caltab[1] = cal;
+  pt  = &mesh->tetra[iel];
+
+  ia = pt->v[0];
+  ib = pt->v[1];
+  ic = pt->v[2];
+  id = pt->v[3];
+
+  /* average metric */
+  memset(mm,0,6*sizeof(double));
+  iadr = (ia-1)*sol->offset + 1;
+  ma   = &sol->met[iadr];
+  
+  iadr = (ie-1)*sol->offset + 1;
+  me   = &sol->met[iadr];
+  
+  iadr = (ib-1)*sol->offset + 1;
+  mb   = &sol->met[iadr];
+  
+  iadr = (ic-1)*sol->offset + 1;
+  mc   = &sol->met[iadr];
+  
+  iadr = (id-1)*sol->offset + 1;
+  md   = &sol->met[iadr];
+  for (j=0; j<6; j++) {
+    mm[j]  = 0.25 * (ma[j]+mb[j]+mc[j]+md[j]);
+    mme[j] = 0.25 * (me[j]+mb[j]+mc[j]+md[j]);
+  }
+
+  a = mesh->point[ia].c;
+  b = mesh->point[ib].c;
+  c = mesh->point[ic].c;
+  d = mesh->point[id].c;
+  e = mesh->point[ie].c;
+  
+  /* volume */
+  bcx = c[0] - b[0];
+  bcy = c[1] - b[1];
+  bcz = c[2] - b[2];
+
+  bax = a[0] - b[0];
+  bay = a[1] - b[1];
+  baz = a[2] - b[2];
+  
+  bex = e[0] - b[0];
+  bey = e[1] - b[1];
+  bez = e[2] - b[2];
+  
+  bdx = d[0] - b[0];
+  bdy = d[1] - b[1];
+  bdz = d[2] - b[2];
+
+
+  v1  = bdy*bcz - bdz*bcy;
+  v2  = bdz*bcx - bdx*bcz;
+  v3  = bdx*bcy - bdy*bcx;
+  
+  vol = bax * v1 + bay * v2 + baz * v3;
+  if ( vol <= 0. )  return(0);
+  
+  vole = -bex * v1 - bey * v2 - bez * v3;
+  if ( vole <= 0. ) return(0);
+  
+  det = mm[0] * ( mm[3]*mm[5] - mm[4]*mm[4]) \
+      - mm[1] * ( mm[1]*mm[5] - mm[2]*mm[4]) \
+      + mm[2] * ( mm[1]*mm[4] - mm[2]*mm[3]);
+  if ( det < EPSOK )  return(0);
+  
+  dete = mme[0] * ( mme[3]*mme[5] - mme[4]*mme[4]) \
+       - mme[1] * ( mme[1]*mme[5] - mme[2]*mme[4]) \
+       + mme[2] * ( mme[1]*mme[4] - mme[2]*mme[3]);  
+  if ( dete < EPSOK )  return(0);
+  
+  det = sqrt(det) * vol;
+
+  /* edge lengths */
+  acx = c[0] - a[0];
+  acy = c[1] - a[1];
+  acz = c[2] - a[2];
+ 
+  adx = d[0] - a[0];
+  ady = d[1] - a[1];
+  adz = d[2] - a[2];
+  
+  h1 =      mm[0]*bax*bax + mm[3]*bay*bay + mm[5]*baz*baz \
+     + 2.0*(mm[1]*bax*bay + mm[2]*bax*baz + mm[4]*bay*baz);
+  h2 =      mm[0]*acx*acx + mm[3]*acy*acy + mm[5]*acz*acz \
+     + 2.0*(mm[1]*acx*acy + mm[2]*acx*acz + mm[4]*acy*acz);
+  h3 =      mm[0]*adx*adx + mm[3]*ady*ady + mm[5]*adz*adz \
+     + 2.0*(mm[1]*adx*ady + mm[2]*adx*adz + mm[4]*ady*adz);
+     
+  cdx = d[0] - c[0];
+  cdy = d[1] - c[1];
+  cdz = d[2] - c[2];
+
+  h4 =      mm[0]*bdx*bdx + mm[3]*bdy*bdy + mm[5]*bdz*bdz \
+     + 2.0*(mm[1]*bdx*bdy + mm[2]*bdx*bdz + mm[4]*bdy*bdz);
+  h5 =      mm[0]*cdx*cdx + mm[3]*cdy*cdy + mm[5]*cdz*cdz \
+     + 2.0*(mm[1]*cdx*cdy + mm[2]*cdx*cdz + mm[4]*cdy*cdz);
+  h6 =      mm[0]*bcx*bcx + mm[3]*bcy*bcy + mm[5]*bcz*bcz \
+     + 2.0*(mm[1]*bcx*bcy + mm[2]*bcx*bcz + mm[4]*bcy*bcz);
+
+  /* quality */
+  rap = h1 + h2 + h3 + h4 + h5 + h6;
+  num = sqrt(rap) * rap;
+  caltab[0] = num / det;  
+  if ( caltab[0] > crit )  return(0);
+
+  dete = sqrt(dete) * vole;
+  ecx = c[0] - e[0];
+  ecy = c[1] - e[1];
+  ecz = c[2] - e[2];
+ 
+  edx = d[0] - e[0];
+  edy = d[1] - e[1];
+  edz = d[2] - e[2];
+ 
+  h1e =      mme[0]*bex*bex + mme[3]*bey*bey + mme[5]*bez*bez \
+      + 2.0*(mme[1]*bex*bey + mme[2]*bex*bez + mme[4]*bey*bez);
+  h2e =      mme[0]*ecx*ecx + mme[3]*ecy*ecy + mme[5]*ecz*ecz \
+      + 2.0*(mme[1]*ecx*ecy + mme[2]*ecx*ecz + mme[4]*ecy*ecz);
+  h3e =      mme[0]*edx*edx + mme[3]*edy*edy + mme[5]*edz*edz \
+      + 2.0*(mme[1]*edx*edy + mme[2]*edx*edz + mme[4]*edy*edz);   
+
+  h4e =      mme[0]*bdx*bdx + mme[3]*bdy*bdy + mme[5]*bdz*bdz \
+      + 2.0*(mme[1]*bdx*bdy + mme[2]*bdx*bdz + mme[4]*bdy*bdz);
+  h5e =      mme[0]*cdx*cdx + mme[3]*cdy*cdy + mme[5]*cdz*cdz \
+      + 2.0*(mme[1]*cdx*cdy + mme[2]*cdx*cdz + mme[4]*cdy*cdz);
+  h6e =      mme[0]*bcx*bcx + mme[3]*bcy*bcy + mme[5]*bcz*bcz \
+      + 2.0*(mme[1]*bcx*bcy + mme[2]*bcx*bcz + mme[4]*bcy*bcz);   
+
+  rap = h1e + h2e + h3e + h4e + h5e + h6e;
+  num = sqrt(rap) * rap;
+  caltab[1] = ( sqrt(rap) * rap ) / dete;
+  
+  if ( caltab[1] > crit )  return(0);
+  
+  return(1);
+}
+
+
+/* compute tetra quality iso : (ia ib ic id) and (ie ib id ic) */
+int MMG_caltet2_iso(pMesh mesh,pSol sol,int iel,int ie,double crit,double * caltab) {
+  pTetra     pt;
+  double     cal,acx,acy,acz,adx,ady,adz;
+  double     bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz,bax,bay,baz;
+  double     bex,bey,bez,ecx,ecy,ecz,edx,edy,edz;
+  double     h1,h2,h3,h4,h5,h6,vol,vole,rap,v1,v2,v3;
+  double     h1e,h2e,h3e,num;
+  double    *a,*b,*c,*d,*e;
+  int        ia,ib,ic,id;
+
+  cal       = CALLIM;
+  caltab[0] = cal;
+  caltab[1] = cal;
+  pt  = &mesh->tetra[iel];  
+  ia = pt->v[0];
+  ib = pt->v[1];
+  ic = pt->v[2];
+  id = pt->v[3];
+
+  a = mesh->point[ia].c;
+  b = mesh->point[ib].c;
+  c = mesh->point[ic].c;
+  d = mesh->point[id].c;
+  e = mesh->point[ie].c;
+  
+  /* volume */
+  bcx = c[0] - b[0];
+  bcy = c[1] - b[1];
+  bcz = c[2] - b[2];
+
+  bax = a[0] - b[0];
+  bay = a[1] - b[1];
+  baz = a[2] - b[2];
+  
+  bex = e[0] - b[0];
+  bey = e[1] - b[1];
+  bez = e[2] - b[2];
+  
+  bdx = d[0] - b[0];
+  bdy = d[1] - b[1];
+  bdz = d[2] - b[2];
+
+
+  v1  = bdy*bcz - bdz*bcy;
+  v2  = bdz*bcx - bdx*bcz;
+  v3  = bdx*bcy - bdy*bcx;
+  vol = bax * v1 + bay * v2 + baz * v3;
+  if ( vol <= 0. )  return(0);
+  
+  vole = -bex * v1 - bey * v2 - bez * v3;
+  if ( vole <= 0. ) return(0);
+/////////////////////    
+/*
+caltab[0] = MMG_caltetrao(mesh,sol,iel);   
+if ( caltab[0] > crit )  {
+	return(0);
+}
+pt = &mesh->tetra[0];
+pt->v[0] = ie;
+pt->v[1] = ib;
+pt->v[2] = id;
+pt->v[3] = ic;       
+caltab[1] = MMG_caltetrao(mesh,sol,0);   
+if ( caltab[1] > crit )  {
+	return(0);
+}
+return(1);      */
+////////////////////
+  
+  /* edge lengths */
+  acx = c[0] - a[0];
+  acy = c[1] - a[1];
+  acz = c[2] - a[2];
+ 
+  adx = d[0] - a[0];
+  ady = d[1] - a[1];
+  adz = d[2] - a[2];
+  
+  
+  h1 = bax*bax + bay*bay + baz*baz;
+  h2 = acx*acx + acy*acy + acz*acz;
+  h3 = adx*adx + ady*ady + adz*adz;
+     
+
+  cdx = d[0] - c[0];
+  cdy = d[1] - c[1];
+  cdz = d[2] - c[2];
+
+  h4 = bdx*bdx + bdy*bdy + bdz*bdz;
+  h5 = cdx*cdx + cdy*cdy + cdz*cdz;                                             
+  h6 = bcx*bcx + bcy*bcy + bcz*bcz;
+     
+  /* quality */
+  rap = h1 + h2 + h3 + h4 + h5 + h6;
+  num = sqrt(rap) * rap;
+  caltab[0] = num / vol;
+  
+  if ( caltab[0] > crit )  return(0);
+  
+  ecx = c[0] - e[0];
+  ecy = c[1] - e[1];
+  ecz = c[2] - e[2];
+ 
+  edx = d[0] - e[0];
+  edy = d[1] - e[1];
+  edz = d[2] - e[2];
+
+  h1e = bex*bex + bey*bey + bez*bez;
+  h2e = ecx*ecx + ecy*ecy + ecz*ecz;
+  h3e = edx*edx + edy*edy + edz*edz;   
+ 
+  rap = h1e + h2e + h3e + h4 + h5 + h6;
+  num = sqrt(rap) * rap;
+  caltab[1] = num / vole;
+  
+  if ( caltab[1] > crit )  return(0);
+
+  return(1);
+}
+
+/* compute tetra quality : 60*max(1/lmin,lmax) + iare : (ia ib ic id) and (ie ib id ic) */
+int MMG_caltet2long_ani(pMesh mesh,pSol sol,int iel,int ie,double crit, double * caltab) {
+  pTetra     pt;
+  double     cal,acx,acy,acz,adx,ady,adz;
+  double     bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz,bax,bay,baz;
+  double     bex,bey,bez,ecx,ecy,ecz,edx,edy,edz;
+  double     h1,h2,h3,h4,h5,h6,det,dete,vol,vole,v1,v2,v3;
+  double     h1e,h2e,h3e,h4e,h5e,h6e;
+  double    *a,*b,*c,*d,*e;
+  double     *ma,*mb,*mc,*md,mm[6],mme[6],*me; 
+  double     lmin,lmax;
+  int        j,ia,ib,ic,id,iadr,iarmin,iarmax;
+
+  cal       = CALLIM;
+  caltab[0] = cal;
+  caltab[1] = cal;
+  pt  = &mesh->tetra[iel];
+
+  ia = pt->v[0];
+  ib = pt->v[1];
+  ic = pt->v[2];
+  id = pt->v[3];
+
+  /* average metric */
+  memset(mm,0,6*sizeof(double));
+  iadr = (ia-1)*sol->offset + 1;
+  ma   = &sol->met[iadr];
+  
+  iadr = (ie-1)*sol->offset + 1;
+  me   = &sol->met[iadr];
+  
+  iadr = (ib-1)*sol->offset + 1;
+  mb   = &sol->met[iadr];
+  
+  iadr = (ic-1)*sol->offset + 1;
+  mc   = &sol->met[iadr];
+  
+  iadr = (id-1)*sol->offset + 1;
+  md   = &sol->met[iadr];
+  for (j=0; j<6; j++) {
+    mm[j]  = 0.25 * (ma[j]+mb[j]+mc[j]+md[j]);
+    mme[j] = 0.25 * (me[j]+mb[j]+mc[j]+md[j]);
+  }
+
+  a = mesh->point[ia].c;
+  b = mesh->point[ib].c;
+  c = mesh->point[ic].c;
+  d = mesh->point[id].c;
+  e = mesh->point[ie].c;
+  
+  /* volume */
+  bcx = c[0] - b[0];
+  bcy = c[1] - b[1];
+  bcz = c[2] - b[2];
+
+  bax = a[0] - b[0];
+  bay = a[1] - b[1];
+  baz = a[2] - b[2];
+  
+  bex = e[0] - b[0];
+  bey = e[1] - b[1];
+  bez = e[2] - b[2];
+  
+  bdx = d[0] - b[0];
+  bdy = d[1] - b[1];
+  bdz = d[2] - b[2];
+
+
+  v1  = bdy*bcz - bdz*bcy;
+  v2  = bdz*bcx - bdx*bcz;
+  v3  = bdx*bcy - bdy*bcx;
+  
+  vol = bax * v1 + bay * v2 + baz * v3;
+  if ( vol <= 0. )  return(0);
+  
+  vole = -bex * v1 - bey * v2 - bez * v3;
+  if ( vole <= 0. ) return(0);
+  
+  det = mm[0] * ( mm[3]*mm[5] - mm[4]*mm[4]) \
+      - mm[1] * ( mm[1]*mm[5] - mm[2]*mm[4]) \
+      + mm[2] * ( mm[1]*mm[4] - mm[2]*mm[3]);
+  if ( det < EPSOK )  return(0);
+  
+  dete = mme[0] * ( mme[3]*mme[5] - mme[4]*mme[4]) \
+       - mme[1] * ( mme[1]*mme[5] - mme[2]*mme[4]) \
+       + mme[2] * ( mme[1]*mme[4] - mme[2]*mme[3]);  
+  if ( dete < EPSOK )  return(0);
+  
+  det = sqrt(det) * vol;
+
+  /* edge lengths */
+  acx = c[0] - a[0];
+  acy = c[1] - a[1];
+  acz = c[2] - a[2];
+ 
+  adx = d[0] - a[0];
+  ady = d[1] - a[1];
+  adz = d[2] - a[2];
+  
+  h1 =      mm[0]*bax*bax + mm[3]*bay*bay + mm[5]*baz*baz \
+     + 2.0*(mm[1]*bax*bay + mm[2]*bax*baz + mm[4]*bay*baz);
+  h2 =      mm[0]*acx*acx + mm[3]*acy*acy + mm[5]*acz*acz \
+     + 2.0*(mm[1]*acx*acy + mm[2]*acx*acz + mm[4]*acy*acz);
+  h3 =      mm[0]*adx*adx + mm[3]*ady*ady + mm[5]*adz*adz \
+     + 2.0*(mm[1]*adx*ady + mm[2]*adx*adz + mm[4]*ady*adz);
+     
+  cdx = d[0] - c[0];
+  cdy = d[1] - c[1];
+  cdz = d[2] - c[2];
+
+  h4 =      mm[0]*bdx*bdx + mm[3]*bdy*bdy + mm[5]*bdz*bdz \
+     + 2.0*(mm[1]*bdx*bdy + mm[2]*bdx*bdz + mm[4]*bdy*bdz);
+  h5 =      mm[0]*cdx*cdx + mm[3]*cdy*cdy + mm[5]*cdz*cdz \
+     + 2.0*(mm[1]*cdx*cdy + mm[2]*cdx*cdz + mm[4]*cdy*cdz);
+  h6 =      mm[0]*bcx*bcx + mm[3]*bcy*bcy + mm[5]*bcz*bcz \
+     + 2.0*(mm[1]*bcx*bcy + mm[2]*bcx*bcz + mm[4]*bcy*bcz);
+
+  /* quality */ 
+  if( h1 < h2 ) {
+    lmin = h1;
+    iarmin = 0;
+    lmax = h2;
+    iarmax = 1;
+  } else {
+    lmin = h2;
+    iarmin = 1;    
+    lmax = h1;
+    iarmax = 0;
+  }
+  
+  if( h3 < lmin) {
+    lmin = h3;
+    iarmin = 2;
+  }
+  if( h3 > lmax) {
+    lmax = h3;
+    iarmax = 2;
+  }
+  if( h4 < lmin) {
+    lmin = h4;
+    iarmin = 3;
+  }
+  if( h4 > lmax) {
+    lmax = h4;
+    iarmax = 3;
+  }
+  if( h5 < lmin) {
+    lmin = h5;
+    iarmin = 4;
+  }
+  if( h5 > lmax) {
+    lmax = h5;
+    iarmax = 4;
+  }
+  if( h6 < lmin) {
+    lmin = h6;
+    iarmin = 5;
+  }
+  if( h6 > lmax) {
+    lmax = h6;
+    iarmax = 5;
+  }                 
+  
+  lmin = sqrt(lmin);
+  lmax = sqrt(lmax);     
+  lmin = (lmin > 1.) ? lmin : 1./lmin;
+  lmax = (lmax > 1.) ? lmax : 1./lmax;
+  if ( lmin > lmax) {
+     caltab[0] = 60*lmin + iarmin;
+  } else {
+     caltab[0] = 60*lmax + iarmax;
+  } 
+  
+  /*rap = h1 + h2 + h3 + h4 + h5 + h6;
+  num = sqrt(rap) * rap;
+  caltab[0] = num / det;  
+  */
+  if ( caltab[0] > crit )  return(0);
+
+  dete = sqrt(dete) * vole;
+  ecx = c[0] - e[0];
+  ecy = c[1] - e[1];
+  ecz = c[2] - e[2];
+ 
+  edx = d[0] - e[0];
+  edy = d[1] - e[1];
+  edz = d[2] - e[2];
+ 
+  h1e =      mme[0]*bex*bex + mme[3]*bey*bey + mme[5]*bez*bez \
+      + 2.0*(mme[1]*bex*bey + mme[2]*bex*bez + mme[4]*bey*bez);
+  h2e =      mme[0]*ecx*ecx + mme[3]*ecy*ecy + mme[5]*ecz*ecz \
+      + 2.0*(mme[1]*ecx*ecy + mme[2]*ecx*ecz + mme[4]*ecy*ecz);
+  h3e =      mme[0]*edx*edx + mme[3]*edy*edy + mme[5]*edz*edz \
+      + 2.0*(mme[1]*edx*edy + mme[2]*edx*edz + mme[4]*edy*edz);   
+
+  h4e =      mme[0]*bdx*bdx + mme[3]*bdy*bdy + mme[5]*bdz*bdz \
+      + 2.0*(mme[1]*bdx*bdy + mme[2]*bdx*bdz + mme[4]*bdy*bdz);
+  h5e =      mme[0]*cdx*cdx + mme[3]*cdy*cdy + mme[5]*cdz*cdz \
+      + 2.0*(mme[1]*cdx*cdy + mme[2]*cdx*cdz + mme[4]*cdy*cdz);
+  h6e =      mme[0]*bcx*bcx + mme[3]*bcy*bcy + mme[5]*bcz*bcz \
+      + 2.0*(mme[1]*bcx*bcy + mme[2]*bcx*bcz + mme[4]*bcy*bcz);   
+
+  if( h1e < h2e ) {
+    lmin = h1e;
+    iarmin = 0;
+    lmax = h2e;
+    iarmax = 1;
+  } else {
+    lmin = h2e;
+    iarmin = 1;    
+    lmax = h1e;
+    iarmax = 0;
+  }
+  
+  if( h3e < lmin) {
+    lmin = h3e;
+    iarmin = 2;
+  }
+  if( h3e > lmax) {
+    lmax = h3;
+    iarmax = 2;
+  }
+  if( h4 < lmin) {
+    lmin = h4;
+    iarmin = 3;
+  }
+  if( h4 > lmax) {
+    lmax = h4;
+    iarmax = 3;
+  }
+  if( h5 < lmin) {
+    lmin = h5;
+    iarmin = 4;
+  }
+  if( h5 > lmax) {
+    lmax = h5;
+    iarmax = 4;
+  }
+  if( h6 < lmin) {
+    lmin = h6;
+    iarmin = 5;
+  }
+  if( h6 > lmax) {
+    lmax = h6;
+    iarmax = 5;
+  }
+
+  
+  lmin = sqrt(lmin);
+  lmax = sqrt(lmax);
+  lmin = (lmin > 1.) ? lmin : 1./lmin;
+  lmax = (lmax > 1.) ? lmax : 1./lmax;
+  if ( lmin > lmax) {
+     caltab[1] = 60*lmin + iarmin;
+  } else {
+     caltab[1] = 60*lmax + iarmax;
+  } 
+  /*rap = h1e + h2e + h3e + h4e + h5e + h6e;
+  num = sqrt(rap) * rap;
+  caltab[1] = ( sqrt(rap) * rap ) / dete;
+  */
+  if ( caltab[1] > crit )  return(0);
+  
+  return(1);
+}
+
+
+/* compute tetra quality iso : (ia ib ic id) and (ie ib id ic) */
+int MMG_caltet2long_iso(pMesh mesh,pSol sol,int iel,int ie,double crit,double * caltab) {
+  pTetra     pt;
+  double     cal,acx,acy,acz,adx,ady,adz;
+  double     bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz,bax,bay,baz;
+  double     bex,bey,bez,ecx,ecy,ecz,edx,edy,edz;
+  double     h1,h2,h3,h4,h5,h6,vol,vole,rap,v1,v2,v3;
+  double     h1e,h2e,h3e,num;
+  double    *a,*b,*c,*d,*e; 
+  double     lmin,lmax;
+  int        ia,ib,ic,id,iarmin,iarmax;
+  cal       = CALLIM;
+  caltab[0] = cal;
+  caltab[1] = cal;
+  pt  = &mesh->tetra[iel];  
+  ia = pt->v[0];
+  ib = pt->v[1];
+  ic = pt->v[2];
+  id = pt->v[3];
+
+  a = mesh->point[ia].c;
+  b = mesh->point[ib].c;
+  c = mesh->point[ic].c;
+  d = mesh->point[id].c;
+  e = mesh->point[ie].c;
+  
+  /* volume */
+  bcx = c[0] - b[0];
+  bcy = c[1] - b[1];
+  bcz = c[2] - b[2];
+
+  bax = a[0] - b[0];
+  bay = a[1] - b[1];
+  baz = a[2] - b[2];
+  
+  bex = e[0] - b[0];
+  bey = e[1] - b[1];
+  bez = e[2] - b[2];
+  
+  bdx = d[0] - b[0];
+  bdy = d[1] - b[1];
+  bdz = d[2] - b[2];
+
+
+  v1  = bdy*bcz - bdz*bcy;
+  v2  = bdz*bcx - bdx*bcz;
+  v3  = bdx*bcy - bdy*bcx;
+  vol = bax * v1 + bay * v2 + baz * v3;
+  if ( vol <= 0. )  return(0);
+  
+  vole = -bex * v1 - bey * v2 - bez * v3;
+  if ( vole <= 0. ) return(0);
+/////////////////////    
+/*
+caltab[0] = MMG_caltetrao(mesh,sol,iel);   
+if ( caltab[0] > crit )  {
+	return(0);
+}
+pt = &mesh->tetra[0];
+pt->v[0] = ie;
+pt->v[1] = ib;
+pt->v[2] = id;
+pt->v[3] = ic;       
+caltab[1] = MMG_caltetrao(mesh,sol,0);   
+if ( caltab[1] > crit )  {
+	return(0);
+}
+return(1);      */
+////////////////////
+  
+  /* edge lengths */
+  acx = c[0] - a[0];
+  acy = c[1] - a[1];
+  acz = c[2] - a[2];
+ 
+  adx = d[0] - a[0];
+  ady = d[1] - a[1];
+  adz = d[2] - a[2];
+  
+  
+  h1 = bax*bax + bay*bay + baz*baz;
+  h2 = acx*acx + acy*acy + acz*acz;
+  h3 = adx*adx + ady*ady + adz*adz;
+     
+
+  cdx = d[0] - c[0];
+  cdy = d[1] - c[1];
+  cdz = d[2] - c[2];
+
+  h4 = bdx*bdx + bdy*bdy + bdz*bdz;
+  h5 = cdx*cdx + cdy*cdy + cdz*cdz;                                             
+  h6 = bcx*bcx + bcy*bcy + bcz*bcz;
+     
+  /* quality */
+  if( h1 < h2 ) {
+    lmin = h1;
+    iarmin = 0;
+    lmax = h2;
+    iarmax = 1;
+  } else {
+    lmin = h2;
+    iarmin = 1;    
+    lmax = h1;
+    iarmax = 0;
+  }
+  
+  if( h3 < lmin) {
+    lmin = h3;
+    iarmin = 2;
+  }
+  if( h3 > lmax) {
+    lmax = h3;
+    iarmax = 2;
+  }
+  if( h4 < lmin) {
+    lmin = h4;
+    iarmin = 3;
+  }
+  if( h4 > lmax) {
+    lmax = h4;
+    iarmax = 3;
+  }
+  if( h5 < lmin) {
+    lmin = h5;
+    iarmin = 4;
+  }
+  if( h5 > lmax) {
+    lmax = h5;
+    iarmax = 4;
+  }
+  if( h6 < lmin) {
+    lmin = h6;
+    iarmin = 5;
+  }
+  if( h6 > lmax) {
+    lmax = h6;
+    iarmax = 5;
+  }
+  lmin = sqrt(lmin);
+  lmax = sqrt(lmax);   
+  lmin = (lmin > 1.) ? lmin : 1./lmin;
+  lmax = (lmax > 1.) ? lmax : 1./lmax; 
+  //printf("long %e %e %e %e %e %e\n",sqrt(h1),sqrt(h2),sqrt(h3),sqrt(h4),sqrt(h5),sqrt(h6));
+  //printf("--lmin %e %e\n",lmin,lmax);
+  if ( lmin > lmax) {
+     caltab[0] = 60*lmin + iarmin;
+  } else {
+     caltab[0] = 60*lmax + iarmax;
+  }
+  rap = h1 + h2 + h3 + h4 + h5 + h6;
+  num = sqrt(rap) * rap;
+  cal = num / vol;
+              
+  //printf("cal %e ? %e\n",caltab[0],crit);
+  if ( cal > crit )  return(0);   
+  
+  ecx = c[0] - e[0];
+  ecy = c[1] - e[1];
+  ecz = c[2] - e[2];
+ 
+  edx = d[0] - e[0];
+  edy = d[1] - e[1];
+  edz = d[2] - e[2];
+
+  h1e = bex*bex + bey*bey + bez*bez;
+  h2e = ecx*ecx + ecy*ecy + ecz*ecz;
+  h3e = edx*edx + edy*edy + edz*edz;   
+ 
+  if( h1e < h2e ) {
+    lmin = h1e;
+    iarmin = 0;
+    lmax = h2e;
+    iarmax = 1;
+  } else {
+    lmin = h2e;
+    iarmin = 1;    
+    lmax = h1e;
+    iarmax = 0;
+  }
+  
+  if( h3e < lmin) {
+    lmin = h3e;
+    iarmin = 2;
+  }
+  if( h3e > lmax) {
+    lmax = h3;
+    iarmax = 2;
+  }
+  if( h4 < lmin) {
+    lmin = h4;
+    iarmin = 3;
+  }
+  if( h4 > lmax) {
+    lmax = h4;
+    iarmax = 3;
+  }
+  if( h5 < lmin) {
+    lmin = h5;
+    iarmin = 4;
+  }
+  if( h5 > lmax) {
+    lmax = h5;
+    iarmax = 4;
+  }
+  if( h6 < lmin) {
+    lmin = h6;
+    iarmin = 5;
+  }
+  if( h6 > lmax) {
+    lmax = h6;
+    iarmax = 5;
+  }
+  
+  lmin = sqrt(lmin);
+  lmax = sqrt(lmax);     
+  lmin = (lmin > 1.) ? lmin : 1./lmin;
+  lmax = (lmax > 1.) ? lmax : 1./lmax;   
+  //printf("lmin %e %e\n",lmin,lmax);
+  if ( lmin > lmax) {
+     caltab[1] = 60*lmin + iarmin;
+  } else {
+     caltab[1] = 60*lmax + iarmax;
+  }
+  rap = h1e + h2e + h3e + h4 + h5 + h6;
+  num = sqrt(rap) * rap;
+  cal = num / vole;
+  
+  //printf("cal %e ? %e\n",caltab[1],crit);
+  if ( cal > crit )  return(0);
+//  puts("je passe");exit(0);
+
+  return(1);
+}
+
+double MMG_calte3_ani(pMesh mesh,pSol sol,int iel) {
+  pTetra     pt;
+  double     cal,ab[3],ac[3],ad[3],bc[3],bd[3],cd[3];
+  double     vol,det,v1,v2,v3,air,dd;
+  double    *a,*b,*c,*d;
+  double     *ma,*mb,*mc,*md,mm[6];;
+  int        j,ia,ib,ic,id,iadr;
+  static double id3[6] ={1.0,0.,0.,1.,0.,1.};
+
+  pt = &mesh->tetra[iel];
+  if ( !pt->v[0] )  return(0.0);
+  cal = CALLIM;
+
+  ia = pt->v[0];
+  ib = pt->v[1];
+  ic = pt->v[2];
+  id = pt->v[3];
+
+  /* average metric */
+  memset(mm,0,6*sizeof(double));
+  iadr = (ia-1)*sol->offset + 1;
+  ma   = &sol->met[iadr];
+  iadr = (ib-1)*sol->offset + 1;
+  mb   = &sol->met[iadr];
+  iadr = (ic-1)*sol->offset + 1;
+  mc   = &sol->met[iadr];
+  iadr = (id-1)*sol->offset + 1;
+  md   = &sol->met[iadr];
+  for (j=0; j<6; j++)
+    mm[j] = 0.25 * (ma[j]+mb[j]+mc[j]+md[j]);
+
+  a  = mesh->point[ia].c;
+  b  = mesh->point[ib].c;
+  c  = mesh->point[ic].c;
+  d  = mesh->point[id].c;
+
+  /* volume */
+  ab[0] = b[0] - a[0];
+  ab[1] = b[1] - a[1];
+  ab[2] = b[2] - a[2];
+
+  ac[0] = c[0] - a[0];
+  ac[1] = c[1] - a[1];
+  ac[2] = c[2] - a[2];
+  
+  ad[0] = d[0] - a[0];
+  ad[1] = d[1] - a[1];
+  ad[2] = d[2] - a[2];
+
+  v1  = ac[1]*ad[2] - ac[2]*ad[1];
+  v2  = ac[2]*ad[0] - ac[0]*ad[2];
+  v3  = ac[0]*ad[1] - ac[1]*ad[0];
+  vol = ab[0] * v1 + ab[1] * v2 + ab[2] * v3;
+  if ( vol <= 0. )  return(cal);
+
+  det = mm[0] * ( mm[3]*mm[5] - mm[4]*mm[4]) \
+      - mm[1] * ( mm[1]*mm[5] - mm[2]*mm[4]) \
+      + mm[2] * ( mm[1]*mm[4] - mm[2]*mm[3]);
+  if ( det < EPSOK )  return(cal);
+  det = sqrt(det) * vol;
+
+  bc[0] = c[0] - b[0];
+  bc[1] = c[1] - b[1];
+  bc[2] = c[2] - b[2];
+
+  bd[0] = d[0] - b[0];
+  bd[1] = d[1] - b[1];
+  bd[2] = d[2] - b[2];
+
+  cd[0] = d[0] - c[0];
+  cd[1] = d[1] - c[1];
+  cd[2] = d[2] - c[2];
+
+  /* surfaces */
+  memcpy(mm,id3,6*sizeof(double));
+  dd  = determ(bd,bc,mm);
+  air = dd;
+if ( iel ==17460 )  printf("aire1 %E\n",sqrt(dd));
+
+  dd   = determ(ac,ad,mm);
+if ( iel ==17460 )  printf("aire2 %E\n",sqrt(dd));
+  air  = M_MAX(air,dd);
+
+  dd   = determ(ad,ab,mm);
+if ( iel ==17460 )  printf("aire3 %E\n",sqrt(dd));
+  air  = M_MAX(air,dd);
+
+  dd   = determ(ab,ac,mm);
+if ( iel ==17460 )  printf("aire4 %E\n",sqrt(dd));
+  air  = M_MAX(air,dd);
+  
+  /* quality */
+  if ( iel == 20496 ) {
+    printf("vol %E  \n",vol);
+    printf("a %d: %f %f %f\n",ia,a[0],a[1],a[2]);
+    printf("b %d: %f %f %f\n",ib,b[0],b[1],b[2]);
+    printf("c %d: %f %f %f\n",ic,c[0],c[1],c[2]);
+    printf("d %d: %f %f %f\n",id,d[0],d[1],d[2]);
+  }
+  cal = 3.0*vol / sqrt(air);
+
+  return(cal);
+}
+
+/* compute tetra quality to be the cubic mean ration : 15552 * V^2/(somme l^2)^3 */
+double MMG_caltetcubic(pMesh mesh,pSol sol,int iel) {
+  pTetra     pt;
+  double     cal,abx,aby,abz,acx,acy,acz,adx,ady,adz;
+  double     bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz;
+  double     h1,h2,h3,h4,h5,h6,vol,rap,v1,v2,v3;
+  double    *a,*b,*c,*d;
+  int        ia,ib,ic,id;
+
+  cal = 0.;
+  pt  = &mesh->tetra[iel];
+  if ( !pt->v[0] )  return(cal);
+
+  ia = pt->v[0];
+  ib = pt->v[1];
+  ic = pt->v[2];
+  id = pt->v[3];
+
+  a = mesh->point[ia].c;
+  b = mesh->point[ib].c;
+  c = mesh->point[ic].c;
+  d = mesh->point[id].c;
+
+  /* volume */
+  abx = b[0] - a[0];
+  aby = b[1] - a[1];
+  abz = b[2] - a[2];
+
+  acx = c[0] - a[0];
+  acy = c[1] - a[1];
+  acz = c[2] - a[2];
+  
+  adx = d[0] - a[0];
+  ady = d[1] - a[1];
+  adz = d[2] - a[2];
+
+  v1  = acy*adz - acz*ady;
+  v2  = acz*adx - acx*adz;
+  v3  = acx*ady - acy*adx;
+  vol = abx * v1 + aby * v2 + abz * v3;
+  if ( vol <= 0. )  return(cal); 
+  vol /= 6.;
+
+  /*  edge */
+  h1 = abx*abx + aby*aby + abz*abz;
+  h2 = acx*acx + acy*acy + acz*acz;
+  h3 = adx*adx + ady*ady + adz*adz;
+
+  bcx = c[0] - b[0];
+  bcy = c[1] - b[1];
+  bcz = c[2] - b[2];
+
+  bdx = d[0] - b[0];
+  bdy = d[1] - b[1];
+  bdz = d[2] - b[2];
+
+  cdx = d[0] - c[0];
+  cdy = d[1] - c[1];
+  cdz = d[2] - c[2];
+
+  h4 = bdx*bdx + bdy*bdy + bdz*bdz;
+  h5 = cdx*cdx + cdy*cdy + cdz*cdz;
+  h6 = bcx*bcx + bcy*bcy + bcz*bcz;
+
+  /* quality */
+  rap = h1 + h2 + h3 + h4 + h5 + h6;
+  cal = vol*vol;
+  cal *= 15552.; 
+  cal = exp(0.3333333333*log(cal));
+  //cal = pow(cal,0.33333333333);
+  cal = cal / rap; 
+
+  return(cal);
+}
+
+/* compute tetra quality : 60*max(1/lmin,lmax) + iare*/
+double MMG_callong(pMesh mesh,pSol sol,int iel) {
+  pTetra     pt;
+  double    *ca,*cb,len;
+  double     *ma,*mb,lmin,lmax,cal; 
+  double     ux,uy,uz,dd1,sa,dd2,sb,dd,rap;
+  int        i,ia,ib,iadr,iarmin,iarmax,ipa,ipb;
+
+  cal = CALLIM;
+  pt  = &mesh->tetra[iel];
+  if ( !pt->v[0] )  return(cal);
+  
+  lmax   = 0.;
+  lmin   = CALLIM;
+  iarmin = 0;
+  iarmax = 0;
+  for (i=0; i<6; i++) {
+  
+    /* edge length */
+    ia  = MMG_iare[i][0];
+    ib  = MMG_iare[i][1];
+    ipa = pt->v[ia];
+    ipb = pt->v[ib];
+
+    ca  = &mesh->point[ipa].c[0];
+    cb  = &mesh->point[ipb].c[0];
+     
+    iadr = (ipa-1)*sol->offset + 1;
+    ma  = &sol->met[iadr];
+
+    iadr = (ipb-1)*sol->offset + 1;
+    mb  = &sol->met[iadr];        
+    
+    if(sol->offset==6) {
+      ux = cb[0] - ca[0];
+      uy = cb[1] - ca[1];
+      uz = cb[2] - ca[2];
+
+      dd1 =      ma[0]*ux*ux + ma[3]*uy*uy + ma[5]*uz*uz \
+          + 2.0*(ma[1]*ux*uy + ma[2]*ux*uz + ma[4]*uy*uz);
+      if ( dd1 <= 0.0 )  dd1 = 0.0;
+
+      dd2 =     mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \
+          + 2.0*(mb[1]*ux*uy +mb[2]*ux*uz + mb[4]*uy*uz);
+      if ( dd2 <= 0.0 )  dd2 = 0.0;
+
+      /*longueur approchee*/   
+      /*precision a 3.5 10e-3 pres*/
+      if(fabs(dd1-dd2) < 0.05 ) {
+        //printf("bonne precision %e \n",sqrt(0.5*(dd1+dd2)) - (sqrt(dd1)+sqrt(dd2)+4.0*sqrt(0.5*(dd1+dd2))) / 6.0 );
+        len = sqrt(0.5*(dd1+dd2));
+      } else{
+        len = (sqrt(dd1)+sqrt(dd2)+4.0*sqrt(0.5*(dd1+dd2))) / 6.0;
+      }
+    } else {
+      sa   = *ma;
+      sb   = *mb;
+
+      ux = cb[0] - ca[0];
+      uy = cb[1] - ca[1];
+      uz = cb[2] - ca[2];
+      dd = sqrt(ux*ux + uy*uy + uz*uz);
+
+      rap = (sb - sa) / sa;
+      if ( fabs(rap) < EPS1 )
+        /*len = dd * (2.0-EPS1) / (2.0*sa);*/
+        len = dd / sa;
+      else
+        /*len = max(dd/sa,dd/sb);*/
+        len = dd * (1.0/sa + 1.0/sb + 8.0 / (sa+sb)) / 6.0;
+      
+    }    
+    if ( len < lmin ) {
+      lmin = len;
+      iarmin = i;
+    } 
+    if ( len > lmax ) {
+      lmax = len;
+      iarmax = i;
+    }
+  }  
+  lmin = (lmin > 1.) ? lmin : 1./lmin;
+  lmax = (lmax > 1.) ? lmax : 1./lmax;
+  if ( lmin > lmax) {
+    cal = 60*lmin + iarmin;
+  } else {
+    cal = 60*lmax + iarmax;
+  } 
+  return(cal);
+}
diff --git a/contrib/mmg3d/build/sources/queue.c b/contrib/mmg3d/build/sources/queue.c
new file mode 100644
index 0000000000000000000000000000000000000000..2756bf3bb8d744fca88a3822f5aada85f2edaa9c
--- /dev/null
+++ b/contrib/mmg3d/build/sources/queue.c
@@ -0,0 +1,167 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+ 
+pQueue MMG_kiuini(pMesh mesh,int nbel,double declic,int base) {
+  pQueue   q;
+  pTetra   pt;
+  int      k;
+
+  q = (Queue*)M_malloc(sizeof(Queue),"kiuini");
+  assert(q);
+  q->stack = (int*)M_calloc((1+nbel),sizeof(int),"kiuini.stack");
+  assert(q->stack);
+
+  q->cur = 0;
+  for (k=1; k<=mesh->ne; k++) {
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] || pt->qual < declic )    continue;
+    else if ( base > 0 && pt->flag < base )  continue;
+
+    q->stack[q->cur] = k;
+    q->cur = k;
+  }
+
+  return(q);
+}
+
+
+void MMG_kiufree(pQueue q) {
+  M_free(q->stack);
+  M_free(q);
+}
+
+
+int MMG_kiudel(pQueue q,int iel) {
+  int   k;
+
+  if ( !q->stack[0] )
+    return(0);
+
+  else if ( q->cur != iel && !q->stack[iel] )
+    return(0);
+
+  else if ( iel == q->stack[0] ) {
+    if ( iel == q->cur ) {
+      q->cur = 0;
+      q->stack[0] = 0;
+      return(1);
+    }
+    else {
+      q->stack[0]   = q->stack[iel];
+      q->stack[iel] = 0; 
+      return(1);
+    }
+  }
+
+  else {
+    for (k=iel-1; k>0; k--)
+      if ( q->stack[k] == iel )  break;
+assert(k>0);
+    if ( iel == q->cur ) {
+      q->cur        = k;
+      q->stack[k]   = 0;
+      q->stack[iel] = 0;
+      return(1);
+    }
+    else {
+      q->stack[k]   = q->stack[iel];
+      q->stack[iel] = 0;
+      return(1);
+    }
+  }
+
+  return(0);
+}
+
+
+int MMG_kiuput(pQueue q,int iel) {
+  int    k;
+
+  if ( !q->stack[0] )
+    return(0);
+
+  else if ( iel == q->cur || q->stack[iel] )
+    return(0);
+
+  else if ( iel > q->cur ) {
+    q->stack[q->cur] = iel;
+    q->stack[iel]    = 0;
+    q->cur = iel;
+    return(1);
+  }
+
+  else if ( iel < q->stack[0] ) {
+    q->stack[iel] = q->stack[0];
+    q->stack[0]   = iel;
+    return(1);
+  }
+
+  else {
+    for (k=iel-1; k>=0; k--)
+      if ( q->stack[k] )  break;
+assert(k>-1);
+    q->stack[iel] = q->stack[k];
+    q->stack[k]   = iel;
+    return(1);
+  }
+
+  return(0);
+}
+
+
+int MMG_kiupop(pQueue q) {
+  int  cur;
+
+  cur = q->stack[0];
+  q->stack[0]   = q->stack[cur];
+  q->stack[cur] = 0;
+  if ( q->cur == cur )  q->cur = 0;
+
+  return(cur);
+}
+
+
diff --git a/contrib/mmg3d/build/sources/ratio.c b/contrib/mmg3d/build/sources/ratio.c
new file mode 100644
index 0000000000000000000000000000000000000000..a975e6da84d78a86b18fe3f37c624cc149a170ef
--- /dev/null
+++ b/contrib/mmg3d/build/sources/ratio.c
@@ -0,0 +1,435 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+/*  
+ratio = 
+tet equi : 1. 
+tet rect (1 1 sqrt(2)) : 3.73 vs 1.93 (avec sqrt(lmax/lmin))
+tet rect (1 1/sqrt(2) 1/sqrt(2)) : 2.2413 vs 1.49
+*/
+
+#include "mesh.h"    
+
+int MMG_gauss(double mat[6][6],double rhs[6],double* met);
+
+
+/*compute the aniso ratio for an element k*/
+double MMG_rao(pMesh mesh,int k,FILE* inm) {     
+  pTetra		pt;
+  pPoint		ppa,ppb;
+  double		edg[6][3],mat[6][6],met[6],rhs[6];   
+  double		lambda[3],v[3][3],lmin,lmax,rao;
+//  double		bufd[GmfMaxTyp];
+  int			i,j;
+   
+  pt = &mesh->tetra[k];
+  
+   /*compute the ellipsoide*/	  
+  for (i=0 ; i<6 ; i++)
+    rhs[i] = 1;
+  
+  for (i=0 ; i<6 ; i++) {
+    ppa = &mesh->point[pt->v[MMG_iare[i][0]]];
+    ppb = &mesh->point[pt->v[MMG_iare[i][1]]];
+    for (j=0 ; j<3 ; j++) {
+  	  edg[i][j] = ppb->c[j] - ppa->c[j];  
+    }              
+    mat[i][0] = edg[i][0]*edg[i][0];
+    mat[i][1] = 2*edg[i][0]*edg[i][1];
+    mat[i][2] = 2*edg[i][0]*edg[i][2];
+    mat[i][3] = edg[i][1]*edg[i][1];
+    mat[i][4] = 2*edg[i][1]*edg[i][2];
+    mat[i][5] = edg[i][2]*edg[i][2];
+  }	   
+  MMG_gauss(mat,rhs,met);  
+  
+  /*find the eigenvalues of the metric*/	
+  if ( !eigenv(1,met,lambda,v) ) {
+    for (j=0 ; j<6 ; j++)
+  	  printf("%e %e %e %e %e %e\n",mat[j][0],mat[j][1],mat[j][2],mat[j][3],mat[j][4],mat[j][5]);
+  	  printf("\n met %e %e %e %e %e %e\n",met[0],met[1],met[2],met[3],met[4],met[5]);
+  puts("pbs eigen"); 
+     return(0);
+  }
+  /*calculate the aniso ratio obtained*/ 
+  lmin = M_MIN(lambda[0],lambda[1]);
+  lmin = M_MIN(lmin,lambda[2]);   
+  lmax = M_MAX(lambda[0],lambda[1]);
+  lmax = M_MAX(lmax,lambda[2]);
+  rao  = sqrt(lmax / lmin);    
+  if(inm) {
+	  /*for (i=0; i<6; i++)
+      bufd[i] = met[i];  
+
+      bufd[2] = met[3];  
+	    bufd[3] = met[2];*/  
+		  fprintf(inm,"%.15lg \n",rao);
+  }
+	
+  return(rao);	
+}
+
+
+int MMG_avgmet(pSol sol,pTetra pt,double* mm) {
+  double	*ma,*mb,*mc,*md,h1,h2,h3,h4,h;
+  int		ia,ib,ic,id,j,iadr;
+
+  ia = pt->v[0];
+  ib = pt->v[1];
+  ic = pt->v[2];
+  id = pt->v[3];
+  
+  if (sol->offset==1) {
+	h1 = sol->met[ia];
+	h2 = sol->met[ib];
+	h3 = sol->met[ic];
+	h4 = sol->met[id];
+	h  = 0.25*(h1 + h2 + h3 + h4);
+	mm[0] = h;	
+	mm[1] = 0;	
+	mm[2] = 0;	
+	mm[3] = h;	
+	mm[4] = 0;	
+	mm[5] = h;	
+  } else {
+    
+	/* average metric */
+	memset(mm,0,6*sizeof(double));
+	iadr = (ia-1)*sol->offset + 1;
+	ma   = &sol->met[iadr];
+	iadr = (ib-1)*sol->offset + 1;
+	mb   = &sol->met[iadr];
+	iadr = (ic-1)*sol->offset + 1;
+	mc   = &sol->met[iadr];
+	iadr = (id-1)*sol->offset + 1;
+	md   = &sol->met[iadr];
+	for (j=0; j<6; j++)
+	  mm[j] = 0.25 * (ma[j]+mb[j]+mc[j]+md[j]);
+	
+  }	
+	
+  return(1);	
+}
+
+/* compute the prescribed and obtained anisotropic ratio
+   print histo + save the ratio in a file
+*/
+int MMG_ratio(pMesh mesh, pSol sol,char* firaoame) {  
+  FILE     *inm;
+  pTetra		pt;
+  double		met[6];   
+  double		lambda[3],v[3][3],lmin,lmax,rao;
+  int			  k,ne,typ;
+  char			*ptr,data[128],chaine[128];  
+  double    rapmin,rapmax,rapavg;
+  int       his[10],rapnum;
+  int       iel,ir,nn,nex,ielreal;
+  static double bd[9] = {1.0, 2., 10.0, 50., 100., 200., 500., 1000., 5000. };
+
+  /*save ratio obtained ?*/
+  inm = 0;  
+  if(firaoame) {
+    strcpy(data,firaoame);
+    ptr = strstr(data,".meshb");
+    if ( ptr )  *ptr = '\0';
+    else {
+      ptr = strstr(data,".mesh");
+      if ( ptr ) {
+        *ptr = '\0';
+      }
+    }
+    strcat(data,".sol");
+    if( !(inm = fopen(data,"w")) ) {
+      fprintf(stderr,"  ** UNABLE TO OPEN %s.\n",data);
+      return(0);
+    }
+    else
+      fprintf(stdout,"  %%%% %s OPENED\n",data);
+  
+    /*entete fichier*/
+    strcpy(&chaine[0],"MeshVersionFormatted 2\n"); 
+    fprintf(inm,"%s",chaine);
+    strcpy(&chaine[0],"\n\nDimension 3\n"); 
+    fprintf(inm,"%s ",chaine);
+
+	  typ = 1;
+    
+	  ne = 0;    
+    for(k=1 ; k<=mesh->ne ; k++) {
+	    pt = &mesh->tetra[k];
+	    if(!pt->v[0]) continue;
+	    ne++;
+    }
+    strcpy(&chaine[0],"\n\nSolAtTetrahedra\n"); 
+    fprintf(inm,"%s",chaine);
+    fprintf(inm,"%d\n",ne);
+    fprintf(inm,"%d %d\n",1,typ);
+  
+  }
+
+  if ( abs(mesh->info.imprim) > 7 ) {
+
+    /*ratio prescribed*/
+
+    rapmin  =  1.e20;
+    rapmax  = -1.e20;
+    rapavg  = 0.0;
+    rapnum  = 0;
+    iel     = 0;
+    ielreal = 0;
+    nn      = 0;
+    nex     = 0;
+
+    for (k=0; k<10; k++)  his[k] = 0;
+
+    for(k=1 ; k<=mesh->ne ; k++) {
+	  pt = &mesh->tetra[k];
+	  if(!pt->v[0]) {
+        nex++;
+        continue;
+      }
+      nn++;
+	
+	  /*mean metric*/
+	  MMG_avgmet(sol,pt,met);
+	
+      /*find the eigenvalues of the prescribed metric*/	
+	  if ( !eigenv(1,met,lambda,v) ) {
+   	     puts("pbs eigen"); 
+	     return(0);
+      }
+
+      /*calculate the aniso ratio */ 
+	  lmin = M_MIN(lambda[0],lambda[1]);
+	  lmin = M_MIN(lmin,lambda[2]);   
+ 	  lmax = M_MAX(lambda[0],lambda[1]);
+	  lmax = M_MAX(lmax,lambda[2]);
+	  rao  = sqrt(lmax / lmin);
+
+	  /*histo prescribed*/  
+	  ir   = (int)rao;  
+	  if ( rao > rapmax ) {
+        rapmax = rao; 
+        iel     = k;
+        ielreal = k - nex;
+      }
+      rapavg += rao;
+      rapnum++;
+      if ( rao < 17e10 ) {
+        rapmin = M_MIN(rapmin,rao);
+        if (rao < bd[3]) {
+	      if (rao > bd[2])       his[3]++;
+	      else if (rao > bd[1])  his[2]++;
+	      else                   his[1]++;
+        }
+        else if (rao < bd[5]) {
+	      if (rao > bd[4])       his[5]++;
+	      else if (rao > bd[3])  his[4]++;
+        }
+        else if (rao < bd[6])    his[6]++;
+        else if (rao < bd[7])    his[7]++;
+        else if (rao < bd[8])    his[8]++;
+        else                     his[9]++;
+      }
+    
+    }  
+    /* print histo ratio obtained*/
+    fprintf(stdout,"\n  -- ANISOTROPIC RATIO PRESCRIBED   %d\n",rapnum);
+    fprintf(stdout,"      AVERAGE RATIO       %12.4f\n",rapavg / rapnum);
+    fprintf(stdout,"     SMALLEST RATIO       %12.4f\n",rapmin);  
+    if (rapmax < 1.e4) {
+      fprintf(stdout,"      LARGEST RATIO       %12.4f\n",rapmax);     
+    } else {
+	  fprintf(stdout,"      LARGEST RATIO       %12.4e\n",rapmax);     
+    }
+    pt = &mesh->tetra[iel];
+    fprintf(stdout,"           ELEMENT   %d (%d)   %d %d %d %d\n",
+        iel,ielreal,pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
+
+    fprintf(stdout,"\n     HISTOGRAMM\n");
+    for (k=1; k<9; k++) {
+      if ( his[k] > 0 )
+        fprintf(stdout,"   %8.2f < R <%8.2f  %8d   %5.2f %%  \n",
+            	bd[k-1],bd[k],his[k],100.*(his[k]/(float)rapnum));
+    }
+    if ( his[9] )
+      fprintf(stdout,"    5000.00 < R            %8d   %5.2f %%  \n",
+        his[9],100.*(his[9]/(float)rapnum));
+
+  }
+  
+  rapmin  =  1.e20;
+  rapmax  = -1.e20;
+  rapavg  = 0.0;
+  rapnum  = 0;
+  iel     = 0;
+  ielreal = 0;
+  nn      = 0;
+  nex     = 0;
+
+  for (k=0; k<10; k++)  his[k] = 0;
+
+  for(k=1 ; k<=mesh->ne ; k++) {
+	pt = &mesh->tetra[k];
+	if(!pt->v[0]) {
+      nex++;
+      continue;
+    }
+    nn++;
+	
+	rao = MMG_rao(mesh,k,inm);
+	  
+    /*histo obtained*/  
+	ir   = (int)rao;  
+	if ( rao > rapmax ) {
+      rapmax = rao; 
+      iel     = k;
+      ielreal = k - nex;
+    }
+    rapavg += rao;
+    rapnum++;
+
+    if ( rao < 17e10 ) {
+      rapmin = M_MIN(rapmin,rao);
+      if (rao < bd[3]) {
+	    if (rao > bd[2])       his[3]++;
+	    else if (rao > bd[1])  his[2]++;
+	    else                   his[1]++;
+      }
+      else if (rao < bd[5]) {
+	    if (rao > bd[4])       his[5]++;
+	    else if (rao > bd[3])  his[4]++;
+      }
+      else if (rao < bd[6])    his[6]++;
+      else if (rao < bd[7])    his[7]++;
+      else if (rao < bd[8])    his[8]++;
+      else                     his[9]++;
+    }
+    
+  }
+
+  if(inm) fclose(inm);
+  
+  /* print histo ratio obtained*/
+  fprintf(stdout,"\n  -- ANISOTROPIC RATIO OBTAINED   %d\n",rapnum);
+  fprintf(stdout,"      AVERAGE RATIO       %12.4f\n",rapavg / rapnum);
+  fprintf(stdout,"     SMALLEST RATIO       %12.4f\n",rapmin);  
+  if (rapmax < 1.e4) {
+    fprintf(stdout,"      LARGEST RATIO       %12.4f\n",rapmax);     
+  } else {
+	fprintf(stdout,"      LARGEST RATIO       %12.4e\n",rapmax);     
+  }
+  pt = &mesh->tetra[iel];
+  fprintf(stdout,"           ELEMENT   %d (%d)   %d %d %d %d\n",
+	  iel,ielreal,pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
+
+  if ( abs(mesh->info.imprim) < 5 )  return;
+
+  fprintf(stdout,"\n     HISTOGRAMM\n");
+  for (k=1; k<9; k++) {
+    if ( his[k] > 0 )
+      fprintf(stdout,"   %8.2f < R <%8.2f  %8d   %5.2f %%  \n",
+      		bd[k-1],bd[k],his[k],100.*(his[k]/(float)rapnum));
+  }
+  if ( his[9] )
+    fprintf(stdout,"    5000.00 < R            %8d   %5.2f %%  \n",
+        his[9],100.*(his[9]/(float)rapnum));
+  
+  return(1);	
+} 
+
+/* solve mat*met = rhs */
+int MMG_gauss(double mat[6][6],double rhs[6],double* met) {
+  int i,j,l;  
+  double tmp,piv; 
+  /*printf("begin : \n");
+  for (j=0 ; j<6 ; j++)
+	  printf("%e %e %e %e %e %e\n",mat[j][0],mat[j][1],mat[j][2],mat[j][3],mat[j][4],mat[j][5]);
+  */
+  /* triangularisation*/  
+  for (i=0 ; i<5 ; i++) {     
+	l = i+1;         
+    while ( (fabs(mat[i][i]) < 1e-8) && (l<6)){
+	  for (j=0 ; j<6 ; j++) {     
+		tmp = mat[i][j];
+		mat[i][j] = mat[l][j];
+		mat[l][j] = tmp;
+	  }
+	  tmp    = rhs[i];
+	  rhs[i] = rhs[l];
+	  rhs[l] = tmp;
+	       
+	  l++;
+    }
+	if ((fabs(mat[i][i]) < 1e-8)) {
+	   //puts("WARNING PIV");
+		met[0] = 1;
+		met[1] = 0;
+		met[2] = 0;
+		met[3] = 1e7;
+		met[4] = 10;
+		met[5] = 1e7; 
+		return(1);
+	}	  	                                
+    for (j=i+1 ; j<6 ; j++) { 
+	  piv = mat[j][i];
+	  for (l=0 ; l<6 ; l++) {     
+ 		mat[j][l] -= piv*mat[i][l] / mat[i][i];
+	  }                                        
+	  rhs[j] -= piv*rhs[i]/ mat[i][i];
+    }
+  }
+  /*remontee*/
+  met[5] = rhs[5] / mat[5][5];
+  for(j=4 ; j>=0 ; j--){
+	met[j] = rhs[j];
+	for(l=j+1 ; l<6 ; l++) {
+	  met[j] += -mat[j][l]*met[l];
+	}
+	met[j] /= mat[j][j];  
+  }  
+
+  return(1);
+}
diff --git a/contrib/mmg3d/build/sources/scalem.c b/contrib/mmg3d/build/sources/scalem.c
new file mode 100644
index 0000000000000000000000000000000000000000..91fc6136123a24842aacc11b713e9e20699ff056
--- /dev/null
+++ b/contrib/mmg3d/build/sources/scalem.c
@@ -0,0 +1,230 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+int MMG_scaleMesh(pMesh mesh,pSol sol) {
+  pTetra    pt;
+  pPoint    ppt;
+  pDispl    pd;
+  Info     *info;
+  double    dd,d1;
+  double    *m,*mold;
+  int       i,k,iadr,alloc,ii,jj,kk;
+  double	lambda[3],v[3][3];  
+
+  /* mark used vertices */
+  for (k=1; k<=mesh->ne; k++) {
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+    for (i=0; i<4; i++) {
+      ppt = &mesh->point[ pt->v[i] ];
+      ppt->tag &= ~M_UNUSED;
+    }
+  }
+  
+  if (abs(mesh->info.option)==10) {
+    return(1);
+  }           
+  
+  /* compute bounding box */
+  info = &mesh->info;
+  for (i=0; i<3; i++) {
+    info->min[i] =  DBL_MAX;
+    info->max[i] = -DBL_MAX;
+  }
+
+  for (k=1; k<=mesh->np; k++) {
+    ppt = &mesh->point[k];
+    if ( ppt->tag & M_UNUSED ) continue;
+    for (i=0; i<3; i++) {
+      if ( ppt->c[i] > info->max[i] )  info->max[i] = ppt->c[i];
+      if ( ppt->c[i] < info->min[i] )  info->min[i] = ppt->c[i];
+    }
+  }
+  info->delta = info->max[0]-info->min[0];
+  dd = info->max[1]-info->min[1];
+  if ( dd > info->delta )
+    info->delta = dd;
+  dd = info->max[2]-info->min[2];
+  if ( dd > info->delta )
+    info->delta = dd;
+  if ( info->delta < EPS30 ) {
+    fprintf(stdout,"  ## Unable to scale mesh.\n");
+    return(0);
+  }
+  /* normalize coordinates */
+  alloc = mesh->disp != NULL;
+  dd = (double)PRECI / info->delta;
+  if ( !alloc ) {
+    for (k=1; k<=mesh->np; k++) {
+      ppt = &mesh->point[k];
+      if ( ppt->tag & M_UNUSED )  continue;
+      ppt->c[0] = dd * (ppt->c[0] - info->min[0]);
+      ppt->c[1] = dd * (ppt->c[1] - info->min[1]);
+      ppt->c[2] = dd * (ppt->c[2] - info->min[2]);
+    }
+  }
+  else {
+    pd  = mesh->disp;
+    for (k=1; k<=mesh->np; k++) {
+      ppt = &mesh->point[k];
+      if ( ppt->tag & M_UNUSED )  continue;
+      ppt->c[0] = dd * (ppt->c[0] - info->min[0]);
+      ppt->c[1] = dd * (ppt->c[1] - info->min[1]);
+      ppt->c[2] = dd * (ppt->c[2] - info->min[2]);
+
+      pd->mv[3*(k-1) + 1 + 0] *= dd;
+      pd->mv[3*(k-1) + 1 + 1] *= dd;
+      pd->mv[3*(k-1) + 1 + 2] *= dd;
+
+      d1 = pd->mv[3*(k-1) + 1 + 0]*pd->mv[3*(k-1) + 1 + 0]
+ 		 + pd->mv[3*(k-1) + 1 + 1]*pd->mv[3*(k-1) + 1 + 1] \
+         + pd->mv[3*(k-1) + 1 + 2]*pd->mv[3*(k-1) + 1 + 2];
+      if ( d1 > EPS2 )  ppt->tag  |= M_MOVE;
+    }
+  }
+
+  /* normalize metric */
+  if ( !sol->np ) return(1);
+  
+  switch (sol->offset) {
+  case 1:
+    for (k=1; k<=sol->np; k++)  {
+      sol->met[k] *= dd;
+     }
+    break;
+
+  case 6:
+    dd = 1.0 / (dd*dd);
+    for (k=1; k<=mesh->np; k++) {
+      iadr = (k-1)*sol->offset + 1;
+      m    = &sol->met[iadr];
+      for (i=0; i<sol->offset; i++)  m[i]   *= dd; 
+      
+      /*calcul du log de M*/                 
+      if ( !eigenv(1,m,lambda,v) ) {
+         printf("WRONG METRIC AT POINT %d -- \n",k);
+	     return(0);
+      }
+      for (i=0; i<3; i++) { 
+        if(lambda[i]<=0) {    
+            printf("WRONG METRIC AT POINT %d -- eigenvalue : %e %e %e -- det %e\n",k,lambda[0],lambda[1],lambda[2],
+                                                        m[0]*(m[3]*m[5]-m[4]*m[4])-m[1]*(m[1]*m[5]-m[2]*m[4])+
+                                                        m[2]*(m[1]*m[4]-m[2]*m[3]));
+            printf("WRONG METRIC AT POINT %d -- metric %e %e %e %e %e %e\n",k,m[0],m[1],m[2],m[3],m[4],m[5]);
+            return(0);  
+        }  
+        lambda[i] = log(lambda[i]);
+      }
+      mold    = &sol->metold[iadr]; 
+      kk = 0;
+	  for (ii=0; ii<3; ii++) {
+         for (jj=ii; jj<3; jj++) {
+            mold[kk] = lambda[0]*v[0][ii]*v[0][jj] + 
+ 	                   lambda[1]*v[1][ii]*v[1][jj] +
+                       lambda[2]*v[2][ii]*v[2][jj]; 
+            kk = kk+1;
+         }                     
+       }
+    }
+    break;
+  default:
+    fprintf(stderr,"  ## SPECIFIC DATA NOT USED.\n");
+    exit(2);
+  }
+  
+  /* compute quality */       
+  for (k=1; k<=mesh->ne; k++) {
+    pt = &mesh->tetra[k]; 
+    if ( pt->v[0] ) {
+      pt->qual = MMG_caltet(mesh,sol,k);   
+    }
+    else
+      pt->qual = 0.0;
+  }
+
+  return(1);
+}
+
+
+int MMG_unscaleMesh(pMesh mesh,pSol sol) {
+  pPoint     ppt;
+  Info      *info;
+  double     dd;
+  double     *m;
+  int        i,k,iadr;
+
+  info = &mesh->info;
+
+  /* de-normalize coordinates */
+  dd = info->delta / (double)PRECI;
+  for (k=1; k<=mesh->np; k++) {
+    ppt = &mesh->point[k];
+    if ( ppt->tag & M_UNUSED )  continue;
+    ppt->c[0] = ppt->c[0] * dd + info->min[0];
+    ppt->c[1] = ppt->c[1] * dd + info->min[1];
+    ppt->c[2] = ppt->c[2] * dd + info->min[2];
+  }
+
+  /* de-normalize metric */
+  sol->np = mesh->np;
+  if ( sol->offset == 1 ) {
+    for (k=1; k<=sol->np; k++)  sol->met[k] *= dd;
+  }
+  else {
+    dd = 1.0 / (dd*dd);
+    for (k=1; k<=sol->np; k++) {
+      iadr = (k-1)*sol->offset + 1;
+      m    = &sol->met[iadr];
+      for (i=0; i<6; i++)  m[i] *= dd;
+    }
+  }
+
+  return(1);
+}
+
+
+
diff --git a/contrib/mmg3d/build/sources/simu23.c b/contrib/mmg3d/build/sources/simu23.c
new file mode 100644
index 0000000000000000000000000000000000000000..e9d91c9398bbb7e914f7a00399133b271c43c761
--- /dev/null
+++ b/contrib/mmg3d/build/sources/simu23.c
@@ -0,0 +1,144 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+int MMG_simu23(pMesh mesh,pSol sol,int iel,int i,double crit) {
+  pTetra     pt,pt1;
+  int       *adja,iadr,jel,j,ia,ib,s1,s2,s3;
+  if ( !MMG_getnElt(mesh,3) )  return(-1);
+
+  pt = &mesh->tetra[iel];
+  if ( !pt->v[0] )  return(0);
+
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  if ( !adja[i] || (pt->bdryref[i]!=-1))  return(0);
+  jel  = adja[i] / 4;
+  j    = adja[i] % 4;
+  pt1  = &mesh->tetra[jel];
+
+  ia = pt->v[i];
+  ib = pt1->v[j];
+  s1 = pt->v[ MMG_idir[i][0] ];
+  s2 = pt->v[ MMG_idir[i][1] ];
+  s3 = pt->v[ MMG_idir[i][2] ];
+
+  /* quality of new tetras */
+  pt1 = &mesh->tetra[0];
+  pt1->v[0] = ia;
+  pt1->v[1] = ib;
+  pt1->v[2] = s1;
+  pt1->v[3] = s2;
+  if ( MMG_caltet(mesh,sol,0) > crit ) {
+    memset(pt1,0,sizeof(Tetra));
+    return(0);
+  }
+
+  pt1->v[2] = s2;
+  pt1->v[3] = s3;
+  if ( MMG_caltet(mesh,sol,0) > crit ) {
+    memset(pt1,0,sizeof(Tetra));
+    return(0);
+  }
+
+  pt1->v[2] = s3;
+  pt1->v[3] = s1;
+  if ( MMG_caltet(mesh,sol,0) > crit ) {
+    memset(pt1,0,sizeof(Tetra));
+    return(0);
+  }
+
+  memset(pt1,0,sizeof(Tetra));
+  
+  /* set function ptr */
+//  MMG_swpptr = MMG_swap23;
+  return(1);
+}
+
+
+int MMG_simu32(pMesh mesh,pSol sol,pList list,double crit) {
+  pTetra    pt,pt1;
+  double    caltab[2];
+  int      *adja,k,adj,ia,ib,s1,s2,s3,iadr,iel,iar;
+  short     voy;
+
+  /* initial qual */
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  s1  = pt->v[ MMG_isar[iar][0] ];
+  s2  = pt->v[ MMG_isar[iar][1] ];
+
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s3   = pt1->v[voy];
+
+  /* qual 2 elts */
+  pt1 = &mesh->tetra[0];
+  pt1->v[0] = ia;
+  pt1->v[1] = s1;
+  pt1->v[2] = s2;
+  pt1->v[3] = s3;
+  if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+    memset(pt1,0,sizeof(Tetra));
+    return(0);
+  }
+  list->qual[1] = caltab[0];
+  list->qual[2] = caltab[1];
+
+  memset(pt1,0,sizeof(Tetra));
+
+  /* set function ptr */
+  MMG_swpptr = MMG_swap32;
+  return(1);
+}
diff --git a/contrib/mmg3d/build/sources/simu44.c b/contrib/mmg3d/build/sources/simu44.c
new file mode 100644
index 0000000000000000000000000000000000000000..c8a20c9e49e33756c4775e3bc33c597c61dc4aaf
--- /dev/null
+++ b/contrib/mmg3d/build/sources/simu44.c
@@ -0,0 +1,140 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+/* return 41-42 for config */
+int MMG_simu44(pMesh mesh,pSol sol,pList list,double crit) {
+  pTetra	pt,pt1;;
+  double	caltab[2];
+  int		ia,ib,s1,s2,s3,s4,iadr,*adja,k,adj,iel,iar;
+  short		voy;
+  
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  s1  = pt->v[ MMG_isar[iar][0] ];
+  s2  = pt->v[ MMG_isar[iar][1] ];
+
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s3   = pt1->v[voy];
+
+  k    = MMG_isar[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s4   = pt1->v[voy];
+
+  do {
+     /*config 1 tetra 1*/
+     pt1 = &mesh->tetra[0];
+     pt1->v[0] = ia;
+     pt1->v[1] = s1;
+     pt1->v[2] = s2;
+     pt1->v[3] = s3;
+     if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+       memset(pt1,0,sizeof(Tetra));
+       break;
+     }
+     list->qual[1] = caltab[0];
+     list->qual[2] = caltab[1];
+  
+     pt1 = &mesh->tetra[0];
+     pt1->v[0] = ia;
+     pt1->v[1] = s1;
+     pt1->v[2] = s3;
+     pt1->v[3] = s4;
+     if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+       memset(pt1,0,sizeof(Tetra));
+       break;
+     }
+     list->qual[3] = caltab[0];
+     list->qual[4] = caltab[1];
+ 
+  
+     /* set function ptr */
+     MMG_swpptr = MMG_swap44_1;
+     return(41);
+  
+  } while(0);
+    
+  /* alternate config */
+  pt1 = &mesh->tetra[0];
+  pt1->v[0] = ia;
+  pt1->v[1] = s1;
+  pt1->v[2] = s2;
+  pt1->v[3] = s4;
+  if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+    memset(pt1,0,sizeof(Tetra));
+    return(0);
+  }
+  list->qual[1] = caltab[0];
+  list->qual[2] = caltab[1];
+
+  pt1 = &mesh->tetra[0];
+  pt1->v[0] = ia;
+  pt1->v[1] = s2;
+  pt1->v[2] = s3;
+  pt1->v[3] = s4;
+  if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+    memset(pt1,0,sizeof(Tetra));
+    return(0);  
+  }
+  list->qual[3] = caltab[0];
+  list->qual[4] = caltab[1];
+
+  /* set function ptr */
+  MMG_swpptr = MMG_swap44_2;
+  return(42);
+}
+
diff --git a/contrib/mmg3d/build/sources/simu56.c b/contrib/mmg3d/build/sources/simu56.c
new file mode 100644
index 0000000000000000000000000000000000000000..06671c0b2f140cb653400b4771b196ec7beee424
--- /dev/null
+++ b/contrib/mmg3d/build/sources/simu56.c
@@ -0,0 +1,364 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+int MMG_simu56(pMesh mesh,pSol sol,pList list,double crit) {
+  pTetra	pt,pt1;
+  double	qual[21],caltab[2];
+  int		j,ia,ib,s1,s2,s3,s4,s5;
+  int		iadr,*adja,k,adj,iel,iar;
+  short		voy;
+  
+  for(j = 0 ; j<21 ; j++) {
+    qual[j] = -1;
+  }
+  
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  s1  = pt->v[ MMG_isar[iar][0] ];
+  s2  = pt->v[ MMG_isar[iar][1] ]; 
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s3   = pt1->v[voy];
+
+  iadr = (adj-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  if(pt1->v[MMG_idir[voy][0]]==s2) {
+     k = MMG_idir[voy][0];
+  } else if(pt1->v[MMG_idir[voy][1]]==s2) {
+     k = MMG_idir[voy][1];
+  } else if(pt1->v[MMG_idir[voy][2]]==s2) {
+     k = MMG_idir[voy][2];
+  } else {
+    puts("MMG_simu56_ani: point non existant");
+    exit(0);
+  }  
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s4   = pt1->v[voy];
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s5   = pt1->v[voy];
+  
+  do {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s3;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        memset(pt1,0,sizeof(Tetra));
+				qual[1] = 0;
+        break;
+      }
+      qual[1] = caltab[0];
+      qual[2] = caltab[1];
+      list->qual[1] = qual[1];
+      list->qual[2] = qual[2];
+      
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[3] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[3] = caltab[0];
+      qual[4] = caltab[1];
+      list->qual[3] = qual[3];
+      list->qual[4] = qual[4];
+ 
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[5] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[5] = caltab[0];
+      qual[6] = caltab[1];
+      list->qual[5] = qual[5];
+      list->qual[6] = qual[6];
+     
+     /* set function ptr */
+     memset(pt1,0,sizeof(Tetra));
+     MMG_swpptr = MMG_swap56_1;
+     return(51);
+  } while(0);
+  
+  do {
+      if(!qual[1]) break;      
+      list->qual[1] = qual[1];
+      list->qual[2] = qual[2];
+      
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s3;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[7] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[7] = caltab[0];
+      qual[8] = caltab[1];
+      list->qual[3] = qual[7];
+      list->qual[4] = qual[8];
+ 
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab))  {
+        qual[9] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[9] = caltab[0];
+      qual[10] = caltab[1];
+      list->qual[5] = qual[9];
+      list->qual[6] = qual[10];
+     
+     /* set function ptr */
+     memset(pt1,0,sizeof(Tetra));
+     MMG_swpptr = MMG_swap56_3;
+     return(53);
+  } while(0);
+  
+  do {
+    if(!qual[5]) break;
+    else if(qual[5] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[5] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[5] = caltab[0];
+      qual[6] = caltab[1];
+    }
+    list->qual[1] = qual[5];
+    list->qual[2] = qual[6];
+        
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s2;
+    pt1->v[2] = s3;
+    pt1->v[3] = s4;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[11] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[11] = caltab[0];
+    qual[12] = caltab[1];
+    list->qual[3] = qual[11];
+    list->qual[4] = qual[12];
+ 
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s2;
+    pt1->v[3] = s4;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[13] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[13] = caltab[0];
+    qual[14] = caltab[1];
+    list->qual[5] = qual[13];
+    list->qual[6] = qual[14];
+     
+     /* set function ptr */
+     memset(pt1,0,sizeof(Tetra));
+     MMG_swpptr = MMG_swap56_4;
+     return(54);
+  } while(0);
+  
+  do {
+    if(!qual[11]) break;
+    else if(qual[11] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[11] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[11] = caltab[0];
+      qual[12] = caltab[1];
+    }  
+    list->qual[3] = qual[11];
+    list->qual[4] = qual[12];
+
+
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s2;
+    pt1->v[3] = s5;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[15] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[15] = caltab[0];
+    qual[16] = caltab[1];
+    list->qual[1] = qual[15];
+    list->qual[2] = qual[16];
+      
+ 
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s2;
+    pt1->v[2] = s4;
+    pt1->v[3] = s5;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[17] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[17] = caltab[0];
+    qual[18] = caltab[1];
+    list->qual[5] = qual[17];
+    list->qual[6] = qual[18];
+     
+     /* set function ptr */
+     memset(pt1,0,sizeof(Tetra));
+     MMG_swpptr = MMG_swap56_2;
+     
+     return(52);
+  } while(0);
+  
+  if(!qual[15]) return(0);
+  else if(qual[15] == -1) {
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s2;
+    pt1->v[3] = s5;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[15] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      return(0);
+    }
+    qual[15] = caltab[0];
+    qual[16] = caltab[1];
+  }
+  list->qual[1] = qual[15];
+  list->qual[2] = qual[16];
+  
+  if(!qual[9]) return(0);
+  else if(qual[9] == -1) {
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s3;
+    pt1->v[2] = s4;
+    pt1->v[3] = s5;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[9] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      return(0);
+    }
+    qual[9] = caltab[0];
+    qual[10] = caltab[1];
+  }  
+  list->qual[5] = qual[9];
+  list->qual[6] = qual[10];
+  
+  pt1 = &mesh->tetra[0];
+  pt1->v[0] = ia;
+  pt1->v[1] = s2;
+  pt1->v[2] = s3;
+  pt1->v[3] = s5;
+  if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+    qual[19] = 0;
+    memset(pt1,0,sizeof(Tetra));
+    return(0);
+  }
+  qual[19] = caltab[0];
+  qual[20] = caltab[1];
+  list->qual[3] = qual[19];
+  list->qual[4] = qual[20];
+ 
+
+
+  /* set function ptr */
+  memset(pt1,0,sizeof(Tetra));
+  MMG_swpptr = MMG_swap56_5;
+  return(55);
+}
diff --git a/contrib/mmg3d/build/sources/simu68.c b/contrib/mmg3d/build/sources/simu68.c
new file mode 100644
index 0000000000000000000000000000000000000000..f1114219a1eafb576ed965cd65653301c95c3ef4
--- /dev/null
+++ b/contrib/mmg3d/build/sources/simu68.c
@@ -0,0 +1,1130 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+/* return 1-14 for config */
+int MMG_simu68(pMesh mesh,pSol sol,pList list,double crit) {
+  pTetra pt,pt1;
+  int ia,ib,s1,s2,s3,s4,s5,s6;
+  int iadr,*adja,k,adj,iel,iar;
+  short  voy;
+  double caltab[2],qual[41];
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+
+  for(k=0 ; k<41 ; k++)
+    qual[k] = -1;
+    
+  /*find points of polygone*/
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  s1  = pt->v[ MMG_isar[iar][0] ];
+  s2  = pt->v[ MMG_isar[iar][1] ]; 
+  /*printf("s1 %d s2 %d\n",s1,s2);
+  */iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+ /* printf("tetra %d : %d %d %d %d\n",adj,pt1->v[0],pt1->v[1],pt1->v[2],pt1->v[3]);
+  */s3  = pt1->v[voy];
+  /*printf("s3 %d \n",s3);
+  */iadr = (adj-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  if(pt1->v[MMG_idir[voy][0]]==s2) {
+     k = MMG_idir[voy][0];
+  } else if(pt1->v[MMG_idir[voy][1]]==s2) {
+     k = MMG_idir[voy][1];
+  } else if(pt1->v[MMG_idir[voy][2]]==s2) {
+     k = MMG_idir[voy][2];
+  } else {
+    puts("MMG_simu56: point s2 non existant");
+    exit(0);
+  }  
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  /*printf("tetra %d : %d %d %d %d\n",adj,pt1->v[0],pt1->v[1],pt1->v[2],pt1->v[3]);
+  */s4   = pt1->v[voy];
+  /*printf("s4 %d\n",s4);
+  */iadr = (adj-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  if(pt1->v[MMG_idir[voy][0]]==s3) {
+     k = MMG_idir[voy][0];
+  } else if(pt1->v[MMG_idir[voy][1]]==s3) {
+     k = MMG_idir[voy][1];
+  } else if(pt1->v[MMG_idir[voy][2]]==s3) {
+     k = MMG_idir[voy][2];
+  } else {
+    puts("MMG_simu56_ani: point s4 non existant");
+    exit(0);
+  }  
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s5   = pt1->v[voy]; 
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s6   = pt1->v[voy];
+  
+  /*cas 1*/
+  do {
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s2;
+    pt1->v[3] = s3;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[1] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[1] = caltab[0];
+    qual[2] = caltab[1];
+    list->qual[1] = qual[1];
+    list->qual[2] = qual[2];
+   
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s3;
+    pt1->v[3] = s4;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[3] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[3] = caltab[0];
+    qual[4] = caltab[1];
+    list->qual[3] = qual[3];
+    list->qual[4] = qual[4];
+ 
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s4;
+    pt1->v[3] = s5;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[5] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[5] = caltab[0];
+    qual[6] = caltab[1];
+    list->qual[5] = qual[5];
+    list->qual[6] = qual[6];
+     
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s5;
+    pt1->v[3] = s6;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[7] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[7] = caltab[0];
+    qual[8] = caltab[1];
+    list->qual[7] = qual[7];
+    list->qual[8] = qual[8];
+    
+    /* set function ptr */
+    memset(pt1,0,sizeof(Tetra));
+    MMG_swpptr = MMG_swap68_1;
+     
+    return(1);
+  } while(0);
+  
+  /*cas 2*/
+  do {
+    if(!qual[1]) break;
+    list->qual[1] = qual[1];
+    list->qual[2] = qual[2];
+
+    if(!qual[3]) break;
+    else if(qual[3] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[3] = caltab[0];
+      qual[4] = caltab[1];
+    }  
+    list->qual[3] = qual[3];
+    list->qual[4] = qual[4];
+ 
+    
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s4;
+    pt1->v[3] = s6;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[9] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[9]  = caltab[0];
+    qual[10] = caltab[1];
+    list->qual[5] = qual[9];
+    list->qual[6] = qual[10];
+   
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s4;
+    pt1->v[2] = s5;
+    pt1->v[3] = s6;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[11] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[11] = caltab[0];
+    qual[12] = caltab[1];
+    list->qual[7] = qual[11];
+    list->qual[8] = qual[12];
+
+   /* set function ptr */
+   memset(pt1,0,sizeof(Tetra));
+   MMG_swpptr = MMG_swap68_2;
+   return(2);
+  } while(0);
+  
+  /*cas 3*/
+  do {
+    if(!qual[1]) break;
+    list->qual[1] = qual[1];
+    list->qual[2] = qual[2];
+
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s3;
+    pt1->v[3] = s6;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[13] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[13] = caltab[0];
+    qual[14] = caltab[1];
+    list->qual[3] = qual[13];
+    list->qual[4] = qual[14];
+ 
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s3;
+    pt1->v[2] = s5;
+    pt1->v[3] = s6;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[15] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[15] = caltab[0];
+    qual[16] = caltab[1];
+    list->qual[5] = qual[15];
+    list->qual[6] = qual[16];
+   
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s3;
+    pt1->v[2] = s4;
+    pt1->v[3] = s5;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[17] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[17] = caltab[0];
+    qual[18] = caltab[1];
+    list->qual[7] = qual[17];
+    list->qual[8] = qual[18];
+   /* set function ptr */
+   memset(pt1,0,sizeof(Tetra));
+   MMG_swpptr = MMG_swap68_3;
+   return(3);
+  } while(0);
+  
+  /*cas 4*/
+  do {
+    if(!qual[1]) break;
+    list->qual[1] = qual[1];
+    list->qual[2] = qual[2];
+    
+    if(!qual[11]) break;
+    else if(qual[11] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[11] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[11] = caltab[0];
+      qual[12] = caltab[1];
+    }
+    list->qual[7] = qual[11];
+    list->qual[8] = qual[12];
+    
+    if(!qual[13]) break;
+    else if(qual[13] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s3;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[13] = 0;
+	memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[13] = caltab[0];
+      qual[14] = caltab[1];
+    }
+    list->qual[3] = qual[13];
+    list->qual[4] = qual[14];
+    
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s3;
+    pt1->v[2] = s4;
+    pt1->v[3] = s6;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[19] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[19] = caltab[0];
+    qual[20] = caltab[1];
+    list->qual[5] = qual[19];
+    list->qual[6] = qual[20];
+   
+    
+   /* set function ptr */
+   memset(pt1,0,sizeof(Tetra));
+   MMG_swpptr = MMG_swap68_4;
+   return(4);
+  } while(0);
+  
+  /*cas 5*/
+  do {
+    if(!qual[9]) break;
+    else if(qual[9] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s4;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[9] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[9]  = caltab[0];
+      qual[10] = caltab[1]; 
+    }
+    list->qual[5] = qual[9];
+    list->qual[6] = qual[10];
+
+    if(!qual[11]) break;
+    else if(qual[11] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[11] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[11] = caltab[0];
+      qual[12] = caltab[1]; 
+    }
+    list->qual[7] = qual[11];
+    list->qual[8] = qual[12];
+    
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s2;
+    pt1->v[2] = s3;
+    pt1->v[3] = s4;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[21] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[21] = caltab[0];
+    qual[22] = caltab[1];
+    list->qual[1] = qual[21];
+    list->qual[2] = qual[22];
+    
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s2;
+    pt1->v[3] = s4;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[23] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[23] = caltab[0];
+    qual[24] = caltab[1];
+    list->qual[3] = qual[23];
+    list->qual[4] = qual[24];
+ 
+   /* set function ptr */
+   memset(pt1,0,sizeof(Tetra));
+   MMG_swpptr = MMG_swap68_5;
+   return(5);
+  } while(0);
+  
+  
+  /*cas 6*/
+  do {
+    if(!qual[5]) break;
+    else if(qual[5] == -1) { 
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[5] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[5] = caltab[0];
+      qual[6] = caltab[1];
+    } 
+    list->qual[5] = qual[5];
+    list->qual[6] = qual[6];
+
+    if(!qual[7]) break;
+    else if(qual[7] == -1) {   
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[7] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[7] = caltab[0];
+      qual[8] = caltab[1];
+    }  
+    list->qual[7] = qual[7];
+    list->qual[8] = qual[8];
+    
+    if(!qual[21]) break;
+    else if(qual[21] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[21] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[21] = caltab[0];
+      qual[22] = caltab[1];
+    }  
+    list->qual[1] = qual[21];
+    list->qual[2] = qual[22];
+    
+    if(!qual[23]) break;
+    else if(qual[23] == -1) {    
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[23] = 0;  
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[23] = caltab[0];
+      qual[24] = caltab[1];
+    }  
+    list->qual[3] = qual[23];
+    list->qual[4] = qual[24];
+ 
+   /* set function ptr */
+   memset(pt1,0,sizeof(Tetra));
+   MMG_swpptr = MMG_swap68_6;
+   return(6);
+  } while(0);
+  
+  /*cas 7*/
+  do {
+    if(!qual[7]) break;
+    else if(qual[7] == -1) {   
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[7] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[7] = caltab[0];
+      qual[8] = caltab[1];
+    }  
+    list->qual[1] = qual[7];
+    list->qual[2] = qual[8];
+    
+    if(!qual[17]) break;
+    else if(qual[17] == -1) { 
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[17] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[17] = caltab[0];
+      qual[18] = caltab[1];
+    }  
+    list->qual[7] = qual[17];
+    list->qual[8] = qual[18];
+     
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s2;
+    pt1->v[3] = s5;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[25] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[25] = caltab[0];
+    qual[26] = caltab[1];
+    list->qual[3] = qual[25];
+    list->qual[4] = qual[26];
+ 
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s2;
+    pt1->v[2] = s3;
+    pt1->v[3] = s5;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[27] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[27] = caltab[0];
+    qual[28] = caltab[1];
+    list->qual[5] = qual[27];
+    list->qual[6] = qual[28];
+   
+   /* set function ptr */
+   memset(pt1,0,sizeof(Tetra));
+   MMG_swpptr = MMG_swap68_7;
+   return(7);
+  } while(0);
+  
+ /*cas 8*/
+ do {
+    if(!qual[11]) break;
+    else if(qual[11] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab))  {
+        qual[11] = 0;
+	memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[11] = caltab[0];
+      qual[12] = caltab[1];
+    }  
+    list->qual[7] = qual[11];
+    list->qual[8] = qual[12];
+    
+    if(!qual[19]) break;
+    else if(qual[19] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab))  {
+        qual[19] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[19] = caltab[0];
+      qual[20] = caltab[1];
+    }      
+    list->qual[5] = qual[19];
+    list->qual[6] = qual[20];
+    
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s2;
+    pt1->v[3] = s6;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab))  {
+      qual[29] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[29] = caltab[0];
+    qual[30] = caltab[1];
+    list->qual[1] = qual[29];
+    list->qual[2] = qual[30];
+    
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s2;
+    pt1->v[2] = s3;
+    pt1->v[3] = s6;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab))  {
+      qual[31] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[31] = caltab[0];
+    qual[32] = caltab[1];
+    list->qual[3] = qual[31];
+    list->qual[4] = qual[32];
+   
+   /* set function ptr */
+   memset(pt1,0,sizeof(Tetra));
+   MMG_swpptr = MMG_swap68_8;
+   return(8);
+  } while(0);
+  
+  /*cas 9*/
+  do {  
+    if(!qual[1]) break;
+    list->qual[1] = qual[1];
+    list->qual[2] = qual[2];
+
+    if(!qual[7]) break;
+    else if(qual[7] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[7] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[7] = caltab[0];
+      qual[8] = caltab[1];
+    } 
+    list->qual[5] = qual[7];
+    list->qual[6] = qual[8];
+    
+    if(!qual[17]) break;
+    else if(qual[17] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[17] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[17] = caltab[0];
+      qual[18] = caltab[1];
+    }  
+    list->qual[3] = qual[17];
+    list->qual[4] = qual[18];
+   
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s3;
+    pt1->v[3] = s5;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[33] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[33] = caltab[0];
+    qual[34] = caltab[1];
+    list->qual[7] = qual[33];
+    list->qual[8] = qual[34];
+   /* set function ptr */
+   memset(pt1,0,sizeof(Tetra));
+   MMG_swpptr = MMG_swap68_9;
+   return(9);
+  } while(0);
+  
+  /*cas 10*/
+  do {
+    if(!qual[7]) break;
+    else if(qual[7] == -1){
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[7] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[7] = caltab[0];
+      qual[8] = caltab[1];
+    }
+    list->qual[7] = qual[7];
+    list->qual[8] = qual[8];
+
+    if(!qual[21]) break;
+    else if(qual[21] == -1){
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[21] = 0;
+	memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[21] = caltab[0];
+      qual[22] = caltab[1];
+    }
+    list->qual[1] = qual[21];
+    list->qual[2] = qual[22];
+    
+    if(!qual[25]) break;
+    else if(qual[25] == -1){
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[25] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[25] = caltab[0];
+      qual[26] = caltab[1];
+    }
+    list->qual[5] = qual[25];
+    list->qual[6] = qual[26];
+ 
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s2;
+    pt1->v[2] = s4;
+    pt1->v[3] = s5;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[35] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[35] = caltab[0];
+    qual[36] = caltab[1];
+    list->qual[3] = qual[35];
+    list->qual[4] = qual[36];
+ 
+   /* set function ptr */
+   memset(pt1,0,sizeof(Tetra));
+   MMG_swpptr = MMG_swap68_10;
+   return(10);
+  } while(0);
+  
+  /*cas 11*/
+  do {
+    if(!qual[21]) break;
+    else if(qual[21] == -1){
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[21] = 0;
+	memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[21] = caltab[0];
+      qual[22] = caltab[1];
+    }
+    list->qual[1] = qual[21];
+    list->qual[2] = qual[22];
+    
+    if(!qual[29]) break;
+    else if(qual[29] == -1){
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[29] = 0;
+	memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[29] = caltab[0];
+      qual[30] = caltab[1];
+    }
+    list->qual[7] = qual[29];
+    list->qual[8] = qual[30];
+
+    if(!qual[35]) break;
+    else if(qual[35] == -1){
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        qual[35] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[35] = caltab[0];
+      qual[36] = caltab[1];
+    }
+    list->qual[3] = qual[35];
+    list->qual[4] = qual[36];
+ 
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s2;
+    pt1->v[2] = s5;
+    pt1->v[3] = s6;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[37] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[37] = caltab[0];
+    qual[38] = caltab[1];
+    list->qual[5] = qual[37];
+    list->qual[6] = qual[38];
+   
+   /* set function ptr */
+   memset(pt1,0,sizeof(Tetra));
+   MMG_swpptr = MMG_swap68_11;
+   return(11);
+  } while(0);
+  
+  /*cas 12*/
+  do {
+    if(!qual[17]) break;
+    else if(qual[17] == -1){
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[17] = 0;
+	memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[17] = caltab[0];
+      qual[18] = caltab[1];
+    }
+    list->qual[7] = qual[17];
+    list->qual[8] = qual[18];
+    
+    if(!qual[27]) break;
+    else if(qual[27] == -1){
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[27] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[27] = caltab[0];
+      qual[28] = caltab[1];
+    }
+    list->qual[5] = qual[27];
+    list->qual[6] = qual[28];
+
+   if(!qual[29]) break;
+    else if(qual[29] == -1){
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[29] = 0;
+	memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[29] = caltab[0];
+      qual[30] = caltab[1];
+    }
+
+    list->qual[1] = qual[29];
+    list->qual[2] = qual[30];
+    
+    if(!qual[37]) break;
+    else if(qual[37] == -1){
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[37] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[37] = caltab[0];
+      qual[38] = caltab[1];
+    }
+    list->qual[3] = qual[37];
+    list->qual[4] = qual[38];
+    
+   /* set function ptr */
+   memset(pt1,0,sizeof(Tetra));
+   MMG_swpptr = MMG_swap68_12;
+   return(12);
+  } while(0);
+  
+  
+  /*cas 13*/
+  do {
+    if(!qual[15]) break;
+    else if(qual[15] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[15] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[15] = caltab[0];
+      qual[16] = caltab[1];
+    }
+    list->qual[5] = qual[15];
+    list->qual[6] = qual[16];
+   
+    if(!qual[17]) break;
+    else if(qual[17] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[17] = 0;
+	memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[17] = caltab[0];
+      qual[18] = caltab[1];
+    }
+    list->qual[7] = qual[17];
+    list->qual[8] = qual[18];
+
+    if(!qual[29]) break;
+    else if(qual[29] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[29] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[29] = caltab[0];
+      qual[30] = caltab[1];
+    }
+    list->qual[1] = qual[29];
+    list->qual[2] = qual[30];
+    
+    if(!qual[31]) break;
+    else if(qual[31] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[31] = 0;
+	memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[31] = caltab[0];
+      qual[32] = caltab[1];
+    }
+    list->qual[3] = qual[31];
+    list->qual[4] = qual[32];
+ 
+ 
+   /* set function ptr */
+   memset(pt1,0,sizeof(Tetra));
+   MMG_swpptr = MMG_swap68_13;
+   return(13);
+  } while(0);
+  
+  /*cas 14*/
+  do {
+    if(!qual[11]) break;
+    else if(qual[11] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[11] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[11] = caltab[0];
+      qual[12] = caltab[1];
+    }
+    list->qual[5] = qual[11];
+    list->qual[6] = qual[12];
+    
+    if(!qual[21]) break;
+    else if(qual[21] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[21] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[21] = caltab[0];
+      qual[22] = caltab[1];
+    }
+    list->qual[3] = qual[21];
+    list->qual[4] = qual[22];
+    
+    if(!qual[29]) break;
+    else if(qual[29] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        qual[29] = 0;
+        memset(pt1,0,sizeof(Tetra));
+        break;
+      }
+      qual[29] = caltab[0];
+      qual[30] = caltab[1];
+    }
+    list->qual[1] = qual[29];
+    list->qual[2] = qual[30];
+        
+   
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s2;
+    pt1->v[2] = s4;
+    pt1->v[3] = s6;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      qual[39] = 0;
+      memset(pt1,0,sizeof(Tetra));
+      break;
+    }
+    qual[39] = caltab[0];
+    qual[40] = caltab[1];
+    list->qual[7] = qual[39];
+    list->qual[8] = qual[40];
+   /* set function ptr */
+   memset(pt1,0,sizeof(Tetra));
+   MMG_swpptr = MMG_swap68_14;
+   return(14);
+  } while(0);
+  
+   return(0);
+
+}
diff --git a/contrib/mmg3d/build/sources/simu710.c b/contrib/mmg3d/build/sources/simu710.c
new file mode 100644
index 0000000000000000000000000000000000000000..6fea0e70feb76f9e6f3225c6455f34a6596fc67f
--- /dev/null
+++ b/contrib/mmg3d/build/sources/simu710.c
@@ -0,0 +1,4021 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+/* return 1-49 for config */
+int MMG_simu710(pMesh mesh,pSol sol,pList list,double crit) {
+  pTetra	pt,pt1;
+  double	qual[71],caltab[2];
+  int		ia,ib,s1,s2,s3,s4,s5,s6,s7;
+  int		iadr,*adja,k,adj,iel,iar;
+  short  voy;
+
+  for(k=0 ; k<=71 ; k++) qual[k] = -1;
+  
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+
+  /*find points of polygone*/
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  s1  = pt->v[ MMG_isar[iar][0] ];
+  s2  = pt->v[ MMG_isar[iar][1] ]; 
+
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+
+  s3  = pt1->v[voy];
+
+  iadr = (adj-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  if(pt1->v[MMG_idir[voy][0]]==s2) {
+     k = MMG_idir[voy][0];
+  } else if(pt1->v[MMG_idir[voy][1]]==s2) {
+     k = MMG_idir[voy][1];
+  } else if(pt1->v[MMG_idir[voy][2]]==s2) {
+     k = MMG_idir[voy][2];
+  } else {
+    puts("MMG_simu710: point s2 non existant");
+    exit(0);
+  }  
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+
+  s4   = pt1->v[voy];
+  iadr = (adj-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  if(pt1->v[MMG_idir[voy][0]]==s3) {
+     k = MMG_idir[voy][0];
+  } else if(pt1->v[MMG_idir[voy][1]]==s3) {
+     k = MMG_idir[voy][1];
+  } else if(pt1->v[MMG_idir[voy][2]]==s3) {
+     k = MMG_idir[voy][2];
+  } else {
+    printf("MMG_simu710: point s3 non existant %d \n",s3);
+    exit(0);
+  } 
+   
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+
+  s5   = pt1->v[voy];
+  iadr = (adj-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  if(pt1->v[MMG_idir[voy][0]]==s4) {
+     k = MMG_idir[voy][0];
+  } else if(pt1->v[MMG_idir[voy][1]]==s4) {
+     k = MMG_idir[voy][1];
+  } else if(pt1->v[MMG_idir[voy][2]]==s4) {
+     k = MMG_idir[voy][2];
+  } else {
+    puts("MMG_simu710: point s4 non existant");
+    exit(0);
+  }   
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s6   = pt1->v[voy]; 
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s7   = pt1->v[voy];
+  
+ /* printf("polygone : %d %d %d %d %d %d %d\n",s1,s2,s3,s4,s5,s6,s7);
+  */
+  /*for(k=1 ; k<=7 ; k++) {
+    jel = list->tetra[k]/6;
+    pt1 =&mesh->tetra[jel];
+    printf("tetra %d : %d %d %d %d\n",jel,pt1->v[0],pt1->v[1],pt1->v[2],pt1->v[3]);
+  }*/
+  
+  /*cas 1*/
+  do {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s3;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("cal 0 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[1] = 0;
+        break;
+      }
+      qual[1] = caltab[0];
+      qual[2] = caltab[1];
+      list->qual[1] = qual[1];
+      list->qual[2] = qual[2];
+        
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("caltab[0] 2 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[3] = 0;
+        break;
+      }
+      qual[3] = caltab[0];
+      qual[4] = caltab[1];
+      list->qual[3] = qual[3];
+      list->qual[4] = qual[4];
+
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("cal 4 %e %e \n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[5] = 0;
+        break;
+      }
+      qual[5] = caltab[0];
+      qual[6] = caltab[1];
+      list->qual[5] = qual[5];
+      list->qual[6] = qual[6];
+     
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab))  {
+        //printf("cal 6 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[7] = 0;
+        break;
+      }
+      qual[7] = caltab[0];
+      qual[8] = caltab[1];
+      list->qual[7] = qual[7];
+      list->qual[8] = qual[8];
+           
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("cal 8 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[9] = 0;
+        break;
+      }
+      qual[9]  = caltab[0];
+      qual[10] = caltab[1];
+      list->qual[9]  = qual[9];
+      list->qual[10] = qual[10];
+
+     MMG_swpptr = MMG_swap710_1;
+  
+     return(71);
+  } while(0);
+
+  /*cas 2*/
+  do {
+    if(!qual[1]) break;
+    list->qual[1] = qual[1];
+    list->qual[2] = qual[2];
+    
+    if(!qual[3]) break;
+    else if(qual[3] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 3 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[3] = 0;
+        break;
+      }
+      qual[3] = caltab[0];
+      qual[4] = caltab[1];
+    } 
+    list->qual[3] = qual[3];
+    list->qual[4] = qual[4];
+     
+    if(!qual[5]) break;
+    else if(qual[5] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 5 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[5] = 0;
+        break;
+      }
+      qual[5] = caltab[0];
+      qual[6] = caltab[1];
+    } 
+    list->qual[5] = qual[5];
+    list->qual[6] = qual[6];
+    
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s5;
+    pt1->v[3] = s7;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab))  {
+      //printf("2:cal 11 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[11] = 0;
+      break;
+    }
+    qual[11] = caltab[0];
+    qual[12] = caltab[1];
+    list->qual[7] = qual[11];
+    list->qual[8] = qual[12];
+      
+      
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s5;
+    pt1->v[2] = s6;
+    pt1->v[3] = s7;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[13] = 0;
+      break;
+    }
+    qual[13] = caltab[0];
+    qual[14] = caltab[1];
+    list->qual[9] = qual[13];
+    list->qual[10] = qual[14];   
+    
+    MMG_swpptr = MMG_swap710_2;
+    return(72);
+  } while(0); 
+  
+  /*cas 3*/
+  do {
+    if(!qual[1]) break;
+    list->qual[1] = qual[1];
+    list->qual[2] = qual[2];
+    
+    if(!qual[3]) break;
+    else if(qual[3] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 3 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[3] = 0;
+        break;
+      }
+      qual[3] = caltab[0];
+      qual[4] = caltab[1];
+    } 
+    list->qual[3] = qual[3];
+    list->qual[4] = qual[4];
+   
+    if(!qual[13]) break;
+    else if(qual[13] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s5;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[13] = 0;
+        break;
+      }
+      qual[13] = caltab[0];
+      qual[14] = caltab[1];
+    } 
+    list->qual[5] = qual[13];
+    list->qual[6] = qual[14];
+
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s4;
+    pt1->v[2] = s5;
+    pt1->v[3] = s7;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+      //printf("2:cal 15 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[15] = 0;
+      break;
+    }  
+    qual[15] = caltab[0];
+    qual[16] = caltab[1];
+    list->qual[7] = qual[15];
+    list->qual[8] = qual[16];
+
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s4;
+    pt1->v[3] = s7;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+      //printf("2:cal 11 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[17] = 0;
+      break;
+    }
+    qual[17] = caltab[0];
+    qual[18] = caltab[1];
+    list->qual[9]  = qual[17];
+    list->qual[10] = qual[18];
+         
+    MMG_swpptr = MMG_swap710_3;
+    return(73);
+  } while(0);
+  
+  /*cas 4*/
+  do {
+    if(!qual[1]) break;
+    list->qual[1] = qual[1];
+    list->qual[2] = qual[2];
+    
+    if(!qual[3]) break;
+    else if(qual[3] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 3 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[3] = 0;
+        break;
+      }
+      qual[3] = caltab[0];
+      qual[4] = caltab[1];
+    } 
+    list->qual[3] = qual[3];
+    list->qual[4] = qual[4];
+   
+    if(!qual[17]) break;
+    else if(qual[17] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s4;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 17 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[17] = 0;
+        break;
+      }
+      qual[17] = caltab[0];
+      qual[18] = caltab[1];
+    } 
+    list->qual[5] = qual[17];
+    list->qual[6] = qual[18];
+
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s4;
+    pt1->v[2] = s6;
+    pt1->v[3] = s7;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+      //printf("2:cal 19 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[19] = 0;
+      break;
+    }  
+    qual[19] = caltab[0];
+    qual[20] = caltab[1];
+    list->qual[7] = qual[19];
+    list->qual[8] = qual[20];
+
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s4;
+    pt1->v[2] = s5;
+    pt1->v[3] = s6;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+      //printf("2:cal 11 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[21] = 0;
+      break;
+    }
+    qual[21] = caltab[0];
+    qual[22] = caltab[1];
+    list->qual[9]  = qual[21];
+    list->qual[10] = qual[22];
+         
+    MMG_swpptr = MMG_swap710_4;
+    return(74);
+  } while(0); 
+  
+  /*cas 5*/
+  do {
+    if(!qual[1]) break;
+    list->qual[1] = qual[1];
+    list->qual[2] = qual[2];
+    
+    if(!qual[3]) break;
+    else if(qual[3] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 3 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[3] = 0;
+        break;
+      }
+      qual[3] = caltab[0];
+      qual[4] = caltab[1];
+    } 
+    list->qual[3] = qual[3];
+    list->qual[4] = qual[4];
+   
+    if(!qual[9]) break;
+    else if(qual[9] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 9 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[9] = 0;
+        break;
+      }
+      qual[9]  = caltab[0];
+      qual[10] = caltab[1];
+    } 
+    list->qual[5] = qual[9];
+    list->qual[6] = qual[10];
+
+    if(!qual[21]) break;
+    else if(qual[21] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[21] = 0;
+        break;
+      }
+      qual[21] = caltab[0];
+      qual[22] = caltab[1];
+    }  
+    list->qual[7] = qual[21];
+    list->qual[8] = qual[22];
+
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s4;
+    pt1->v[3] = s6;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+      //printf("2:cal 11 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[23] = 0;
+      break;
+    }
+    qual[23] = caltab[0];
+    qual[24] = caltab[1];
+    list->qual[9]  = qual[23];
+    list->qual[10] = qual[24];
+         
+    MMG_swpptr = MMG_swap710_5;
+    return(75);
+  } while(0);
+  
+  /*cas 6*/
+  do {
+    if(!qual[5]) break;
+    else if(qual[5] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("cal 4 %e %e \n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[5] = 0;
+        break;
+      }
+      qual[5] = caltab[0];
+      qual[6] = caltab[1];
+    }
+    list->qual[1] = qual[5];
+    list->qual[2] = qual[6];
+
+    if(!qual[7]) break;
+    else if(qual[7] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab))  {
+        //printf("cal 6 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[7] = 0;
+        break;
+      }
+      qual[7] = caltab[0];
+      qual[8] = caltab[1];
+    } 
+    list->qual[3] = qual[7];
+    list->qual[4] = qual[8];
+   
+    if(!qual[9]) break;
+    else if(qual[9] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("cal 8 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[9] = 0;
+        break;
+      }
+      qual[9]  = caltab[0];
+      qual[10] = caltab[1];
+    } 
+    list->qual[5] = qual[9];
+    list->qual[6] = qual[10];
+
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s2;
+    pt1->v[2] = s3;
+    pt1->v[3] = s4;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[25] = 0;
+      break;
+    }    
+    qual[25] = caltab[0];
+    qual[26] = caltab[1];
+    list->qual[7] = qual[25];
+    list->qual[8] = qual[26];
+        
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s2;
+    pt1->v[3] = s4;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 12 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[27] = 0;
+      break;
+    }
+    qual[27] = caltab[0];
+    qual[28] = caltab[1];
+    list->qual[9]  = qual[27];
+    list->qual[10] = qual[28];
+    MMG_swpptr = MMG_swap710_6;
+    return(76);
+  } while(0);
+        
+ /*cas 7*/
+ do {
+   if(!qual[5]) break;
+   else if(qual[5] == -1) {
+     pt1 = &mesh->tetra[0];
+     pt1->v[0] = ia;
+     pt1->v[1] = s1;
+     pt1->v[2] = s4;
+     pt1->v[3] = s5;
+     if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+       //printf("2:cal 5 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+       memset(pt1,0,sizeof(Tetra));
+       qual[5] = 0;
+       break;
+     }
+     qual[5] = caltab[0];
+     qual[6] = caltab[1];
+    } 
+    list->qual[1] = qual[5];
+    list->qual[2] = qual[6];
+    
+    if(!qual[11]) break;
+    else if (qual[11] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s5;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab))  {
+        //printf("2:cal 11 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[11] = 0;
+        break;
+      }
+      qual[11] = caltab[0];
+      qual[12] = caltab[1];
+    }
+    list->qual[3] = qual[11];
+    list->qual[4] = qual[12];
+   
+    if(!qual[13]) break;
+    else if(qual[13] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s5;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[13] = 0;
+        break;
+      }
+      qual[13] = caltab[0];
+      qual[14] = caltab[1];
+    } 
+    list->qual[5] = qual[13];
+    list->qual[6] = qual[14];
+    
+    if(!qual[25]) break;
+    else if(qual[25] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[25] = 0;
+        break;
+      }    
+      qual[25] = caltab[0];
+      qual[26] = caltab[1];
+    }
+    list->qual[7] = qual[25];
+    list->qual[8] = qual[26];
+    
+    if(!qual[27]) break;
+    else if(qual[27] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 12 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[27] = 0;
+        break;
+      }
+      qual[27] = caltab[0];
+      qual[28] = caltab[1];
+    }
+    list->qual[9]  = qual[27];
+    list->qual[10] = qual[28];
+    MMG_swpptr = MMG_swap710_7;
+    return(77);    
+ } while(0); 
+ 
+ /*cas 8*/
+ do {
+   if(!qual[13]) break;
+   else if(qual[13] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s5;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[13] = 0;
+        break;
+      }
+      qual[13] = caltab[0];
+      qual[14] = caltab[1];
+    } 
+    list->qual[1] = qual[13];
+    list->qual[2] = qual[14];
+   
+    if(!qual[15]) break;
+    else if(qual[15] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 15 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[15] = 0;
+        break;
+      }  
+      qual[15] = caltab[0];
+      qual[16] = caltab[1];
+    }
+    list->qual[3] = qual[15];
+    list->qual[4] = qual[16];
+    
+    if(!qual[17]) break;
+    else if(qual[17] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s4;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 17 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[17] = 0;
+        break;
+      }
+      qual[17] = caltab[0];
+      qual[18] = caltab[1];
+    } 
+    list->qual[5] = qual[17];
+    list->qual[6] = qual[18];
+    
+    if(!qual[25]) break;
+    else if(qual[25] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[25] = 0;
+        break;
+      }    
+      qual[25] = caltab[0];
+      qual[26] = caltab[1];
+    }
+    list->qual[7] = qual[25];
+    list->qual[8] = qual[26];
+    
+    if(!qual[27]) break;
+    else if(qual[27] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 12 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[27] = 0;
+        break;
+      }
+      qual[27] = caltab[0];
+      qual[28] = caltab[1];
+    }
+    list->qual[9]  = qual[27];
+    list->qual[10] = qual[28];
+    MMG_swpptr = MMG_swap710_8;
+    return(78);  
+ } while(0);	
+ 
+ /*cas 9*/
+ do {
+    if(!qual[17]) break;
+    else if(qual[17] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s4;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 17 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[17] = 0;
+        break;
+      }
+      qual[17] = caltab[0];
+      qual[18] = caltab[1];
+    } 
+    list->qual[1] = qual[17];
+    list->qual[2] = qual[18];
+    
+    if(!qual[19]) break;
+    else if(qual[19] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 19 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[19] = 0;
+        break;
+      }  
+      qual[19] = caltab[0];
+      qual[20] = caltab[1];
+    }
+    list->qual[3] = qual[19];
+    list->qual[4] = qual[20];
+   
+    if(!qual[21]) break;
+    else if(qual[21] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[21] = 0;
+        break;
+      }
+      qual[21] = caltab[0];
+      qual[22] = caltab[1];
+    }  
+    list->qual[5] = qual[21];
+    list->qual[6] = qual[22];
+    
+    if(!qual[25]) break;
+    else if(qual[25] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[25] = 0;
+        break;
+      }    
+      qual[25] = caltab[0];
+      qual[26] = caltab[1];
+    }
+    list->qual[7] = qual[25];
+    list->qual[8] = qual[26];
+
+    if(!qual[27]) break;
+    else if(qual[27] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 12 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[27] = 0;
+        break;
+      }
+      qual[27] = caltab[0];
+      qual[28] = caltab[1];
+    }
+    list->qual[9]  = qual[27];
+    list->qual[10] = qual[28];
+    MMG_swpptr = MMG_swap710_9;
+    return(79);          
+ } while(0);
+ 
+ /*cas 10*/
+ do {
+    if(!qual[9]) break;
+    else if(qual[9] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 9 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[9] = 0;
+        break;
+      }
+      qual[9]  = caltab[0];
+      qual[10] = caltab[1];
+    } 
+    list->qual[1] = qual[9];
+    list->qual[2] = qual[10];
+    
+    if(!qual[21]) break;
+    else if(qual[21] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[21] = 0;
+        break;
+      }
+      qual[21] = caltab[0];
+      qual[22] = caltab[1];
+    }  
+    list->qual[3] = qual[21];
+    list->qual[4] = qual[22];
+    
+    if(!qual[23]) break;
+    else if(qual[23] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s4;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 11 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[23] = 0;
+        break;
+      }
+      qual[23] = caltab[0];
+      qual[24] = caltab[1];
+    }
+    list->qual[5]  = qual[23];
+    list->qual[6] = qual[24];
+    
+    if(!qual[25]) break;
+    else if(qual[25] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[25] = 0;
+        break;
+      }    
+      qual[25] = caltab[0];
+      qual[26] = caltab[1];
+    }
+    list->qual[7] = qual[25];
+    list->qual[8] = qual[26];
+    
+    if(!qual[27]) break;
+    else if(qual[27] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 12 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[27] = 0;
+        break;
+      }
+      qual[27] = caltab[0];
+      qual[28] = caltab[1];
+    }
+    list->qual[9]  = qual[27];
+    list->qual[10] = qual[28];
+    
+    MMG_swpptr = MMG_swap710_10;
+    memset(pt1,0,sizeof(Tetra));
+    return(80);        
+ } while(0);
+ 
+ /*cas 11*/
+ do {
+    if(!qual[25]) break;
+    else if(qual[25] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[25] = 0;
+        break;
+      }    
+      qual[25] = caltab[0];
+      qual[26] = caltab[1];
+    }
+    list->qual[1] = qual[25];
+    list->qual[2] = qual[26];
+    
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s2;
+    pt1->v[3] = s7;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[29] = 0;
+      break;
+    }	 
+    qual[29] = caltab[0];
+    qual[30] = caltab[1];
+    list->qual[3] = qual[29];
+    list->qual[4] = qual[30];
+    
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s2;
+    pt1->v[2] = s6;
+    pt1->v[3] = s7;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[31] = 0;
+      break;
+    }	 
+    qual[31] = caltab[0];
+    qual[32] = caltab[1];
+    list->qual[5] = qual[31];
+    list->qual[6] = qual[32];
+    
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s2;
+    pt1->v[2] = s5;
+    pt1->v[3] = s6;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[33] = 0;
+      break;
+    }	 
+    qual[33] = caltab[0];
+    qual[34] = caltab[1];
+    list->qual[7] = qual[33];
+    list->qual[8] = qual[34];
+    
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s2;
+    pt1->v[2] = s4;
+    pt1->v[3] = s5;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[35] = 0;
+      break;
+    }	 
+    qual[35] = caltab[0];
+    qual[36] = caltab[1];
+    list->qual[9]  = qual[35];
+    list->qual[10] = qual[36];       
+    
+    memset(pt1,0,sizeof(Tetra));
+    MMG_swpptr = MMG_swap710_11;
+    return(81);
+ } while(0);
+ 
+ /*cas 12*/
+ do {
+    if(!qual[29]) break;
+    else if(qual[29] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[29] = 0;
+        break;
+      }	 
+      qual[29] = caltab[0];
+      qual[30] = caltab[1];
+    }
+    list->qual[1] = qual[29];
+    list->qual[2] = qual[30];
+    
+    if(!qual[31]) break;
+    else if(qual[31] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[31] = 0;
+        break;
+      }	 
+      qual[31] = caltab[0];
+      qual[32] = caltab[1];
+    }
+    list->qual[3] = qual[31];
+    list->qual[4] = qual[32];
+    
+    if(!qual[33]) break;
+    else if(qual[33] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[33] = 0;
+        break;
+      }	 
+      qual[33] = caltab[0];
+      qual[34] = caltab[1];
+    }
+    list->qual[5] = qual[33];
+    list->qual[6] = qual[34];
+    
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s3;
+    pt1->v[2] = s4;
+    pt1->v[3] = s5;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[37] = 0;
+      break;
+    }	 
+    qual[37] = caltab[0];
+    qual[38] = caltab[1];
+    list->qual[7] = qual[37];
+    list->qual[8] = qual[38];
+    
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s2;
+    pt1->v[2] = s3;
+    pt1->v[3] = s5;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[39] = 0;
+      break;
+    }	 
+    qual[39] = caltab[0];
+    qual[40] = caltab[1];
+    list->qual[9] = qual[39];
+    list->qual[10] = qual[40];
+    
+    MMG_swpptr = MMG_swap710_12;
+    memset(pt1,0,sizeof(Tetra));
+    return(82); 
+    
+ } while(0);
+ 
+ /*cas 13*/
+ do {
+    if(!qual[29]) break;
+    else if(qual[29] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[29] = 0;
+        break;
+      }	 
+      qual[29] = caltab[0];
+      qual[30] = caltab[1];
+    }
+    list->qual[1] = qual[29];
+    list->qual[2] = qual[30];
+    
+    if(!qual[31]) break;
+    else if(qual[31] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[31] = 0;
+        break;
+      }	 
+      qual[31] = caltab[0];
+      qual[32] = caltab[1];
+    }
+    list->qual[3] = qual[31];
+    list->qual[4] = qual[32];
+
+    if(!qual[37]) break;
+    else if(qual[37] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[37] = 0;
+        break;
+      }	 
+      qual[37] = caltab[0];
+      qual[38] = caltab[1];
+    }
+    list->qual[5] = qual[37];
+    list->qual[6] = qual[38];    
+    
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s2;
+    pt1->v[2] = s3;
+    pt1->v[3] = s6;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[41] = 0;
+      break;
+    }	 
+    qual[41] = caltab[0];
+    qual[42] = caltab[1];
+    list->qual[7] = qual[41];
+    list->qual[8] = qual[42];
+    
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s3;
+    pt1->v[2] = s5;
+    pt1->v[3] = s6;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[43] = 0;
+      break;
+    }	 
+    qual[43] = caltab[0];
+    qual[44] = caltab[1];
+    list->qual[9]  = qual[43];
+    list->qual[10] = qual[44];
+    MMG_swpptr = MMG_swap710_13;
+    memset(pt1,0,sizeof(Tetra));
+    return(84); 
+ } while(0);
+ 
+ /*cas 15*/
+ do {
+    if(!qual[21]) break;
+    else if(qual[21] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[21] = 0;
+        break;
+      }
+      qual[21] = caltab[0];
+      qual[22] = caltab[1];
+    }  
+    list->qual[1] = qual[21];
+    list->qual[2] = qual[22];
+
+    if(!qual[25]) break;
+    else if(qual[25] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[25] = 0;
+        break;
+      }    
+      qual[25] = caltab[0];
+      qual[26] = caltab[1];
+    }
+    list->qual[3] = qual[25];
+    list->qual[4] = qual[26];
+    
+    if(!qual[29]) break;
+    else if(qual[29] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[29] = 0;
+        break;
+      }	 
+      qual[29] = caltab[0];
+      qual[30] = caltab[1];
+    }
+    list->qual[5] = qual[29];
+    list->qual[6] = qual[30];
+    
+    if(!qual[31]) break;
+    else if(qual[31] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[31] = 0;
+        break;
+      }	 
+      qual[31] = caltab[0];
+      qual[32] = caltab[1];
+    }
+    list->qual[7] = qual[31];
+    list->qual[8] = qual[32];
+ 
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s2;
+    pt1->v[2] = s4;
+    pt1->v[3] = s6;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[47] = 0;
+      break;
+    }	 
+    qual[47] = caltab[0];
+    qual[48] = caltab[1];
+    list->qual[9]  = qual[47];
+    list->qual[10] = qual[48];
+    
+    MMG_swpptr = MMG_swap710_15;
+    memset(pt1,0,sizeof(Tetra));
+    return(85); 
+ } while(0);
+ 
+ /*cas 16*/
+ do {
+    if(!qual[9]) break;
+    else if(qual[9] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 9 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[9] = 0;
+        break;
+      }
+      qual[9]  = caltab[0];
+      qual[10] = caltab[1];
+    } 
+    list->qual[1] = qual[9];
+    list->qual[2] = qual[10];
+    
+    if(!qual[25]) break;
+    else if(qual[25] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[25] = 0;
+        break;
+      }    
+      qual[25] = caltab[0];
+      qual[26] = caltab[1];
+    }
+    list->qual[3] = qual[25];
+    list->qual[4] = qual[26];
+	
+    if(!qual[33]) break;
+    else if(qual[33] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[33] = 0;
+        break;
+      }	 
+      qual[33] = caltab[0];
+      qual[34] = caltab[1];
+    }
+    list->qual[5] = qual[33];
+    list->qual[6] = qual[34];
+    
+    if(!qual[35]) break;
+    else if(qual[35] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[35] = 0;
+        break;
+      }	 
+      qual[35] = caltab[0];
+      qual[36] = caltab[1];
+    }
+    list->qual[7] = qual[35];
+    list->qual[8] = qual[36];
+    
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s2;
+    pt1->v[3] = s6;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[49] = 0;
+      break;
+    }  
+    qual[49] = caltab[0];
+    qual[50] = caltab[1];
+    list->qual[9]  = qual[49];
+    list->qual[10] = qual[50];
+          
+    MMG_swpptr = MMG_swap710_16;
+    memset(pt1,0,sizeof(Tetra));
+    return(86);  
+ } while(0);
+ 
+ /*cas 17*/
+ do {
+    if(!qual[9]) break;
+    else if(qual[9] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 9 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[9] = 0;
+        break;
+      }
+      qual[9]  = caltab[0];
+      qual[10] = caltab[1];
+    } 
+    list->qual[1] = qual[9];
+    list->qual[2] = qual[10];
+    
+    if(!qual[33]) break;
+    else if(qual[33] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        ////printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[33] = 0;
+        break;
+      }	 
+      qual[33] = caltab[0];
+      qual[34] = caltab[1];
+    }
+    list->qual[3] = qual[33];
+    list->qual[4] = qual[34];
+
+    if(!qual[37]) break;
+    else if(qual[37] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[37] = 0;
+        break;
+      }	 
+      qual[37] = caltab[0];
+      qual[38] = caltab[1];
+    }
+    list->qual[5] = qual[37];
+    list->qual[6] = qual[38];    
+    
+    if(!qual[39]) break;
+    else if(qual[39] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[39] = 0;
+        break;
+      }	 
+      qual[39] = caltab[0];
+      qual[40] = caltab[1];
+    }
+    list->qual[7] = qual[39];
+    list->qual[8] = qual[40];
+ 
+    if(!qual[49]) break;
+    else if(qual[49] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[49] = 0;
+        break;
+      }  
+      qual[49] = caltab[0];
+      qual[50] = caltab[1];
+    }
+    list->qual[9]  = qual[49];
+    list->qual[10] = qual[50];
+    
+    MMG_swpptr = MMG_swap710_17;
+    memset(pt1,0,sizeof(Tetra));
+    return(87);   
+ } while(0);
+ 
+ /*cas 18*/
+ do {
+    if(!qual[9]) break;
+    else if(qual[9] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 9 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[9] = 0;
+        break;
+      }
+      qual[9]  = caltab[0];
+      qual[10] = caltab[1];
+    } 
+    list->qual[1] = qual[9];
+    list->qual[2] = qual[10];
+
+    if(!qual[37]) break;
+    else if(qual[37] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[37] = 0;
+        break;
+      }	 
+      qual[37] = caltab[0];
+      qual[38] = caltab[1];
+    }
+    list->qual[3] = qual[37];
+    list->qual[4] = qual[38];    
+ 
+     if(!qual[41]) break;
+    else if(qual[41] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[41] = 0;
+        break;
+      }	 
+      qual[41] = caltab[0];
+      qual[42] = caltab[1];
+    }
+    list->qual[5] = qual[41];
+    list->qual[6] = qual[42];
+    
+    if(!qual[43]) break;
+    else if(qual[43] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[43] = 0;
+        break;
+      }	 
+      qual[43] = caltab[0];
+      qual[44] = caltab[1];
+    }
+    list->qual[7] = qual[43];
+    list->qual[8] = qual[44];    
+
+    if(!qual[49]) break;
+    else if(qual[49] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[49] = 0;
+        break;
+      }  
+      qual[49] = caltab[0];
+      qual[50] = caltab[1];
+    }
+    list->qual[9]  = qual[49];
+    list->qual[10] = qual[50];
+
+    MMG_swpptr = MMG_swap710_18;
+    memset(pt1,0,sizeof(Tetra));
+    return(88);   
+ } while(0);
+ 
+ /*cas 19*/
+ do {
+    if(!qual[9]) break;
+    else if(qual[9] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 9 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[9] = 0;
+        break;
+      }
+      qual[9]  = caltab[0];
+      qual[10] = caltab[1];
+    } 
+    list->qual[1] = qual[9];
+    list->qual[2] = qual[10];
+
+    if(!qual[21]) break;
+    else if(qual[21] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[21] = 0;
+        break;
+      }
+      qual[21] = caltab[0];
+      qual[22] = caltab[1];
+    }  
+    list->qual[3] = qual[21];
+    list->qual[4] = qual[22];
+
+    if(!qual[41]) break;
+    else if(qual[41] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[41] = 0;
+        break;
+      }	 
+      qual[41] = caltab[0];
+      qual[42] = caltab[1];
+    }
+    list->qual[5] = qual[41];
+    list->qual[6] = qual[42];
+
+    if(!qual[45]) break;
+    else if(qual[45] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[45] = 0;
+        break;
+      }	 
+      qual[45] = caltab[0];
+      qual[46] = caltab[1];
+    }
+    list->qual[7] = qual[45];
+    list->qual[8] = qual[46];
+    
+    if(!qual[49]) break;
+    else if(qual[49] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[49] = 0;
+        break;
+      }  
+      qual[49] = caltab[0];
+      qual[50] = caltab[1];
+    }
+    list->qual[9]  = qual[49];
+    list->qual[10] = qual[50];
+    
+  
+    MMG_swpptr = MMG_swap710_19;
+    memset(pt1,0,sizeof(Tetra));
+    return(89);  
+ } while(0);
+ 
+ /*cas 20*/
+ do {
+    if(!qual[9]) break;
+    else if(qual[9] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 9 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[9] = 0;
+        break;
+      }
+      qual[9]  = caltab[0];
+      qual[10] = caltab[1];
+    } 
+    list->qual[1] = qual[9];
+    list->qual[2] = qual[10];
+
+    if(!qual[21]) break;
+    else if(qual[21] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[21] = 0;
+        break;
+      }
+      qual[21] = caltab[0];
+      qual[22] = caltab[1];
+    }  
+    list->qual[3] = qual[21];
+    list->qual[4] = qual[22];
+
+    if(!qual[25]) break;
+    else if(qual[25] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[25] = 0;
+        break;
+      }    
+      qual[25] = caltab[0];
+      qual[26] = caltab[1];
+    }
+    list->qual[5] = qual[25];
+    list->qual[6] = qual[26];
+
+    if(!qual[47]) break;
+    else if(qual[47] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s4;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[47] = 0;
+        break;
+      }	 
+      qual[47] = caltab[0];
+      qual[48] = caltab[1];
+    }
+    list->qual[7] = qual[47];
+    list->qual[8] = qual[48];    
+    if(!qual[49]) break;
+    else if(qual[49] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[49] = 0;
+        break;
+      }  
+      qual[49] = caltab[0];
+      qual[50] = caltab[1];
+    }
+    list->qual[9]  = qual[49];
+    list->qual[10] = qual[50];
+    
+    MMG_swpptr = MMG_swap710_20;
+    memset(pt1,0,sizeof(Tetra));
+    return(90);   
+ } while(0);
+
+/*cas 21*/
+do {
+    if(!qual[1]) break;
+    list->qual[1] = qual[1];
+    list->qual[2] = qual[2];
+
+    if(!qual[37]) break;
+    else if(qual[37] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[37] = 0;
+        break;
+      }	 
+      qual[37] = caltab[0];
+      qual[38] = caltab[1];
+    }
+    list->qual[3] = qual[37];
+    list->qual[4] = qual[38]; 
+
+    if(!qual[43]) break;
+    else if(qual[43] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[43] = 0;
+        break;
+      }	 
+      qual[43] = caltab[0];
+      qual[44] = caltab[1];
+    }
+    list->qual[5] = qual[43];
+    list->qual[6] = qual[44];    
+
+    if(!qual[69]) break;
+    else if(qual[69] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[69] = 0;
+        break;
+      }   
+      qual[69] = caltab[0];
+      qual[70] = caltab[1];
+    }
+    list->qual[7] = qual[69];
+    list->qual[8] = qual[70];
+       
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s3;
+    pt1->v[3] = s7;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[51] = 0;
+      break;
+    }  
+    qual[51] = caltab[0];
+    qual[52] = caltab[1];
+    list->qual[9]  = qual[51];
+    list->qual[10] = qual[52];       
+
+    MMG_swpptr = MMG_swap710_21;
+    memset(pt1,0,sizeof(Tetra));
+    return(91);   
+} while(0);
+
+/*cas 22*/
+do {
+    if(!qual[1]) break;
+    list->qual[1] = qual[1];
+    list->qual[2] = qual[2];
+
+    if(!qual[21]) break;
+    else if(qual[21] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[21] = 0;
+        break;
+      }
+      qual[21] = caltab[0];
+      qual[22] = caltab[1];
+    }  
+    list->qual[3] = qual[21];
+    list->qual[4] = qual[22];
+   
+    if(!qual[45]) break;
+    else if(qual[45] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[45] = 0;
+        break;
+      }	 
+      qual[45] = caltab[0];
+      qual[46] = caltab[1];
+    }
+    list->qual[5] = qual[45];
+    list->qual[6] = qual[46];
+    
+    if(!qual[51]) break;
+    else if(qual[51] == -1) {    
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s3;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[51] = 0;
+        break;
+      }   
+      qual[51] = caltab[0];
+      qual[52] = caltab[1];
+    }
+    list->qual[7]  = qual[51];
+    list->qual[8] = qual[52];    
+
+    if(!qual[69]) break;
+    else if(qual[69] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[69] = 0;
+        break;
+      }   
+      qual[69] = caltab[0];
+      qual[70] = caltab[1];
+    }
+    list->qual[9] = qual[69];
+    list->qual[10] = qual[70];
+        
+    MMG_swpptr = MMG_swap710_22;
+    memset(pt1,0,sizeof(Tetra));
+    return(92);  
+} while(0);
+
+/*cas 23*/
+do {
+    if(!qual[1]) break;
+    list->qual[1] = qual[1];
+    list->qual[2] = qual[2];
+
+    if(!qual[19]) break;
+    else if(qual[19] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 19 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[19] = 0;
+        break;
+      }  
+      qual[19] = caltab[0];
+      qual[20] = caltab[1];
+    }
+    list->qual[3] = qual[19];
+    list->qual[4] = qual[20];
+    
+    if(!qual[21]) break;
+    else if(qual[21] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[21] = 0;
+        break;
+      }
+      qual[21] = caltab[0];
+      qual[22] = caltab[1];
+    }  
+    list->qual[5] = qual[21];
+    list->qual[6] = qual[22];
+
+    if(!qual[51]) break;
+    else if(qual[51] == -1) {    
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s3;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[51] = 0;
+        break;
+      }   
+      qual[51] = caltab[0];
+      qual[52] = caltab[1];
+    }
+    list->qual[7] = qual[51];
+    list->qual[8] = qual[52];   
+    
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s3;
+    pt1->v[2] = s4;
+    pt1->v[3] = s7;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[53] = 0;
+      break;
+    }	
+    qual[53] = caltab[0];
+    qual[54] = caltab[1];
+    
+    list->qual[9]  = qual[53];
+    list->qual[10] = qual[54];  
+           
+    MMG_swpptr = MMG_swap710_23;
+    memset(pt1,0,sizeof(Tetra));
+    return(93);  
+} while(0);
+
+/*cas 24*/
+do {
+    if(!qual[1]) break;
+    list->qual[1] = qual[1];
+    list->qual[2] = qual[2];
+    
+    if(!qual[13]) break;
+    else if(qual[13] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s5;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[13] = 0;
+        break;
+      }
+      qual[13] = caltab[0];
+      qual[14] = caltab[1];
+    } 
+    list->qual[3] = qual[13];
+    list->qual[4] = qual[14];
+
+    if(!qual[15]) break;
+    else if(qual[15] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 15 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[15] = 0;
+        break;
+      }  
+      qual[15] = caltab[0];
+      qual[16] = caltab[1];
+    }
+    list->qual[5] = qual[15];
+    list->qual[6] = qual[16];
+    
+    if(!qual[51]) break;
+    else if(qual[51] == -1) {    
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s3;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[51] = 0;
+        break;
+      }   
+      qual[51] = caltab[0];
+      qual[52] = caltab[1];
+    }
+    list->qual[7] = qual[51];
+    list->qual[8] = qual[52];   
+
+    if(!qual[53]) break;
+    else if(qual[53] == -1) {    
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[53] = 0;
+        break;
+      }	
+      qual[53] = caltab[0];
+      qual[54] = caltab[1];
+    }
+    list->qual[9]  = qual[53];
+    list->qual[10] = qual[54];  
+    
+    MMG_swpptr = MMG_swap710_24;
+    memset(pt1,0,sizeof(Tetra));
+    return(94);  
+} while(0);
+
+/*cas 25*/
+do {
+    if(!qual[1]) break;
+    list->qual[1] = qual[1];
+    list->qual[2] = qual[2];
+    
+    if(!qual[13]) break;
+    else if(qual[13] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s5;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[13] = 0;
+        break;
+      }
+      qual[13] = caltab[0];
+      qual[14] = caltab[1];
+    } 
+    list->qual[3] = qual[13];
+    list->qual[4] = qual[14];
+
+    if(!qual[37]) break;
+    else if(qual[37] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[37] = 0;
+        break;
+      }	 
+      qual[37] = caltab[0];
+      qual[38] = caltab[1];
+    }
+    list->qual[5] = qual[37];
+    list->qual[6] = qual[38];    
+
+    if(!qual[51]) break;
+    else if(qual[51] == -1) {    
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s3;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[51] = 0;
+        break;
+      }   
+      qual[51] = caltab[0];
+      qual[52] = caltab[1];
+    }
+    list->qual[7] = qual[51];
+    list->qual[8] = qual[52];    
+
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s3;
+    pt1->v[2] = s5;
+    pt1->v[3] = s7;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[55] = 0;
+      break;
+    }	
+    qual[55] = caltab[0];
+    qual[56] = caltab[1];
+    
+    list->qual[9]  = qual[55];
+    list->qual[10] = qual[56];    
+
+    MMG_swpptr = MMG_swap710_25;
+    memset(pt1,0,sizeof(Tetra));
+    return(95);  
+} while(0);
+
+/*cas 26*/
+do {
+    if(!qual[29]) break;
+    else if(qual[29] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[29] = 0;
+        break;
+      }	 
+      qual[29] = caltab[0];
+      qual[30] = caltab[1];
+    }
+    list->qual[1] = qual[29];
+    list->qual[2] = qual[30];
+    
+    if(!qual[37]) break;
+    else if(qual[37] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[37] = 0;
+        break;
+      }	 
+      qual[37] = caltab[0];
+      qual[38] = caltab[1];
+    }
+    list->qual[3] = qual[37];
+    list->qual[4] = qual[38];
+    
+    if(!qual[43]) break;
+    else if(qual[43] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[43] = 0;
+        break;
+      }	 
+      qual[43] = caltab[0];
+      qual[44] = caltab[1];
+    }
+    list->qual[5] = qual[43];
+    list->qual[6] = qual[44];    
+
+    if(!qual[69]) break;
+    else if(qual[69] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[69] = 0;
+        break;
+      }  
+      qual[69] = caltab[0];
+      qual[70] = caltab[1];
+    }
+    list->qual[7] = qual[69];
+    list->qual[8] = qual[70];
+    
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s2;
+    pt1->v[2] = s3;
+    pt1->v[3] = s7;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[57] = 0;
+      break;
+    }  
+    qual[57] = caltab[0];
+    qual[58] = caltab[1];
+    list->qual[9]  = qual[57];
+    list->qual[10] = qual[58];    
+            
+    MMG_swpptr = MMG_swap710_26;
+    memset(pt1,0,sizeof(Tetra));
+    return(96);  
+} while(0);
+
+/*cas 27*/
+do {
+    if(!qual[21]) break;
+    else if(qual[21] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[21] = 0;
+        break;
+      }
+      qual[21] = caltab[0];
+      qual[22] = caltab[1];
+    }  
+    list->qual[1] = qual[21];
+    list->qual[2] = qual[22];
+
+    if(!qual[29]) break;
+    else if(qual[29] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[29] = 0;
+        break;
+      }	 
+      qual[29] = caltab[0];
+      qual[30] = caltab[1];
+    }
+    list->qual[3] = qual[29];
+    list->qual[4] = qual[30];
+
+    if(!qual[45]) break;
+    else if(qual[45] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[45] = 0;
+        break;
+      }
+      qual[45] = caltab[0];
+      qual[46] = caltab[1];
+    }
+    list->qual[5] = qual[45];
+    list->qual[6] = qual[46];    
+
+    if(!qual[57]) break;
+    else if(qual[57] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[57] = 0;
+        break;
+      }  
+      qual[57] = caltab[0];
+      qual[58] = caltab[1];
+    }
+    list->qual[7] = qual[57];
+    list->qual[8] = qual[58];    
+            
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s3;
+    pt1->v[2] = s6;
+    pt1->v[3] = s7;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[69] = 0;
+      break;
+    }  
+    qual[69] = caltab[0];
+    qual[70] = caltab[1];
+    list->qual[9]  = qual[69];
+    list->qual[10] = qual[70];    
+    MMG_swpptr = MMG_swap710_27;
+    memset(pt1,0,sizeof(Tetra));
+    return(97);  
+} while(0);
+
+/*cas 28*/
+do {
+    if(!qual[19]) break;
+    else if(qual[19] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 19 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[19] = 0;
+        break;
+      }  
+      qual[19] = caltab[0];
+      qual[20] = caltab[1];
+    }
+    list->qual[1] = qual[19];
+    list->qual[2] = qual[20];
+   
+    if(!qual[21]) break;
+    else if(qual[21] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[21] = 0;
+        break;
+      }
+      qual[21] = caltab[0];
+      qual[22] = caltab[1];
+    }  
+    list->qual[3] = qual[21];
+    list->qual[4] = qual[22];
+
+    if(!qual[29]) break;
+    else if(qual[29] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[29] = 0;
+        break;
+      }	 
+      qual[29] = caltab[0];
+      qual[30] = caltab[1];
+    }
+    list->qual[5] = qual[29];
+    list->qual[6] = qual[30];
+
+    if(!qual[53]) break;
+    else if(qual[53] == -1) {    
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[53] = 0;
+        break;
+      }	
+      qual[53] = caltab[0];
+      qual[54] = caltab[1];
+    }
+    list->qual[7] = qual[53];
+    list->qual[8] = qual[54];  
+
+    if(!qual[57]) break;
+    else if(qual[57] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[57] = 0;
+        break;
+      }  
+      qual[57] = caltab[0];
+      qual[58] = caltab[1];
+    }
+    list->qual[9] = qual[57];
+    list->qual[10] = qual[58];    
+
+    MMG_swpptr = MMG_swap710_28;
+    memset(pt1,0,sizeof(Tetra));
+    return(98);  
+} while(0);
+
+/*cas 29*/
+do {
+   if(!qual[13]) break;
+   else if(qual[13] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s5;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[13] = 0;
+        break;
+      }
+      qual[13] = caltab[0];
+      qual[14] = caltab[1];
+    } 
+    list->qual[1] = qual[13];
+    list->qual[2] = qual[14];
+   
+    if(!qual[15]) break;
+    else if(qual[15] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 15 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[15] = 0;
+        break;
+      }  
+      qual[15] = caltab[0];
+      qual[16] = caltab[1];
+    }
+    list->qual[3] = qual[15];
+    list->qual[4] = qual[16];
+
+    if(!qual[29]) break;
+    else if(qual[29] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[29] = 0;
+        break;
+      }	 
+      qual[29] = caltab[0];
+      qual[30] = caltab[1];
+    }
+    list->qual[5] = qual[29];
+    list->qual[6] = qual[30];
+
+    if(!qual[53]) break;
+    else if(qual[53] == -1) {    
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[53] = 0;
+        break;
+      }	
+      qual[53] = caltab[0];
+      qual[54] = caltab[1];
+    }
+    list->qual[7] = qual[53];
+    list->qual[8] = qual[54];  
+
+    if(!qual[57]) break;
+    else if(qual[57] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[57] = 0;
+        break;
+      }  
+      qual[57] = caltab[0];
+      qual[58] = caltab[1];
+    }
+    list->qual[9] = qual[57];
+    list->qual[10] = qual[58];    
+
+    MMG_swpptr = MMG_swap710_29;
+    memset(pt1,0,sizeof(Tetra));
+    return(99); 
+} while(0);
+
+/*cas 30*/
+do {
+   if(!qual[13]) break;
+   else if(qual[13] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s5;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[13] = 0;
+        break;
+      }
+      qual[13] = caltab[0];
+      qual[14] = caltab[1];
+    } 
+    list->qual[1] = qual[13];
+    list->qual[2] = qual[14];
+
+    if(!qual[29]) break;
+    else if(qual[29] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[29] = 0;
+        break;
+      }	 
+      qual[29] = caltab[0];
+      qual[30] = caltab[1];
+    }
+    list->qual[3] = qual[29];
+    list->qual[4] = qual[30];
+
+    if(!qual[37]) break;
+    else if(qual[37] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[37] = 0;
+        break;
+      }	 
+      qual[37] = caltab[0];
+      qual[38] = caltab[1];
+    }
+    list->qual[5] = qual[37];
+    list->qual[6] = qual[38];    
+
+    if(!qual[55]) break;
+    else if(qual[55] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s5;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[55] = 0;
+        break;
+      }	
+      qual[55] = caltab[0];
+      qual[56] = caltab[1];
+    }
+    list->qual[8] = qual[55];
+    list->qual[9] = qual[56];    
+    
+    if(!qual[57]) break;
+    else if(qual[57] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[57] = 0;
+        break;
+      }  
+      qual[57] = caltab[0];
+      qual[58] = caltab[1];
+    }
+    list->qual[9] = qual[57];
+    list->qual[10] = qual[58];    
+    
+    MMG_swpptr = MMG_swap710_30;
+    memset(pt1,0,sizeof(Tetra));
+    return(100); 
+} while(0);
+
+/*cas 31*/
+do {
+    if(!qual[19]) break;
+    else if(qual[19] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 19 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[19] = 0;
+        break;
+      }  
+      qual[19] = caltab[0];
+      qual[20] = caltab[1];
+    }
+    list->qual[1] = qual[19];
+    list->qual[2] = qual[20];
+
+    if(!qual[21]) break;
+    else if(qual[21] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[21] = 0;
+        break;
+      }
+      qual[21] = caltab[0];
+      qual[22] = caltab[1];
+    }  
+    list->qual[3] = qual[21];
+    list->qual[4] = qual[22];
+
+    if(!qual[25]) break;
+    else if(qual[25] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[25] = 0;
+        break;
+      }    
+      qual[25] = caltab[0];
+      qual[26] = caltab[1];
+    }
+    list->qual[5] = qual[25];
+    list->qual[6] = qual[26];
+
+    if(!qual[29]) break;
+    else if(qual[29] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[29] = 0;
+        break;
+      }	 
+      qual[29] = caltab[0];
+      qual[30] = caltab[1];
+    }
+    list->qual[7] = qual[29];
+    list->qual[8] = qual[30];
+
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s2;
+    pt1->v[2] = s4;
+    pt1->v[3] = s7;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[59] = 0;
+      break;
+    }  
+    qual[59] = caltab[0];
+    qual[60] = caltab[1];
+    list->qual[9]  = qual[59];
+    list->qual[10] = qual[60];
+    
+    MMG_swpptr = MMG_swap710_31;
+    memset(pt1,0,sizeof(Tetra));
+    return(101); 
+} while(0);
+
+/*cas 32*/
+do {
+   if(!qual[13]) break;
+   else if(qual[13] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s5;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[13] = 0;
+        break;
+      }
+      qual[13] = caltab[0];
+      qual[14] = caltab[1];
+    } 
+    list->qual[1] = qual[13];
+    list->qual[2] = qual[14];
+   
+    if(!qual[15]) break;
+    else if(qual[15] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 15 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[15] = 0;
+        break;
+      }  
+      qual[15] = caltab[0];
+      qual[16] = caltab[1];
+    }
+    list->qual[3] = qual[15];
+    list->qual[4] = qual[16];
+
+    if(!qual[25]) break;
+    else if(qual[25] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[25] = 0;
+        break;
+      }    
+      qual[25] = caltab[0];
+      qual[26] = caltab[1];
+    }
+    list->qual[5] = qual[25];
+    list->qual[6] = qual[26];
+
+    if(!qual[29]) break;
+    else if(qual[29] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[29] = 0;
+        break;
+      }	 
+      qual[29] = caltab[0];
+      qual[30] = caltab[1];
+    }
+    list->qual[7] = qual[29];
+    list->qual[8] = qual[30];
+    
+    if(!qual[59]) break;
+    else if(qual[59] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s4;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[59] = 0;
+        break;
+      }  
+      qual[59] = caltab[0];
+      qual[60] = caltab[1];
+    }
+    list->qual[9]  = qual[59];
+    list->qual[10] = qual[60];
+    
+    MMG_swpptr = MMG_swap710_32;
+    memset(pt1,0,sizeof(Tetra));
+    return(102); 
+} while(0);
+
+/*cas 33*/
+do {
+    if(!qual[1]) break;
+    list->qual[1] = qual[1];
+    list->qual[2] = qual[2];
+
+    if(!qual[7]) break;
+    else if(qual[7] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab))  {
+        //printf("cal 6 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[7] = 0;
+        break;
+      }
+      qual[7] = caltab[0];
+      qual[8] = caltab[1];
+    } 
+    list->qual[3] = qual[7];
+    list->qual[4] = qual[8];
+   
+    if(!qual[9]) break;
+    else if(qual[9] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("cal 8 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[9] = 0;
+        break;
+      }
+      qual[9]  = caltab[0];
+      qual[10] = caltab[1];
+    } 
+    list->qual[5] = qual[9];
+    list->qual[6] = qual[10];
+
+    if(!qual[37]) break;
+    else if(qual[37] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[37] = 0;
+        break;
+      }	 
+      qual[37] = caltab[0];
+      qual[38] = caltab[1];
+    }
+    list->qual[7] = qual[37];
+    list->qual[8] = qual[38];    
+
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s3;
+    pt1->v[3] = s5;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[61] = 0;
+      break;
+    }  
+    qual[61] = caltab[0];
+    qual[62] = caltab[1];
+    list->qual[9]  = qual[61];
+    list->qual[10] = qual[62];
+
+    MMG_swpptr = MMG_swap710_33;
+    memset(pt1,0,sizeof(Tetra));
+    return(103); 
+} while(0);
+
+/*cas 34*/
+do {
+    if(!qual[7]) break;
+    else if(qual[7] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab))  {
+        //printf("cal 6 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[7] = 0;
+        break;
+      }
+      qual[7] = caltab[0];
+      qual[8] = caltab[1];
+    } 
+    list->qual[1] = qual[7];
+    list->qual[2] = qual[8];
+   
+    if(!qual[9]) break;
+    else if(qual[9] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("cal 8 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[9] = 0;
+        break;
+      }
+      qual[9]  = caltab[0];
+      qual[10] = caltab[1];
+    } 
+    list->qual[3] = qual[9];
+    list->qual[4] = qual[10];
+
+    if(!qual[37]) break;
+    else if(qual[37] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[37] = 0;
+        break;
+      }	 
+      qual[37] = caltab[0];
+      qual[38] = caltab[1];
+    }
+    list->qual[5] = qual[37];
+    list->qual[6] = qual[38];    
+
+    if(!qual[39]) break;
+    else if(qual[39] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[39] = 0;
+        break;
+      }	 
+      qual[39] = caltab[0];
+      qual[40] = caltab[1];
+    }
+    list->qual[7] = qual[39];
+    list->qual[8] = qual[40];
+
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s2;
+    pt1->v[3] = s5;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[63] = 0;
+      break;
+    }  
+    qual[63] = caltab[0];
+    qual[64] = caltab[1];
+    list->qual[9]  = qual[63];
+    list->qual[10] = qual[64];
+    
+    MMG_swpptr = MMG_swap710_34;
+    memset(pt1,0,sizeof(Tetra));
+    return(104); 
+} while(0);
+
+/*cas 35*/
+do {
+    if(!qual[7]) break;
+    else if(qual[7] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab))  {
+        //printf("cal 6 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[7] = 0;
+        break;
+      }
+      qual[7] = caltab[0];
+      qual[8] = caltab[1];
+    } 
+    list->qual[1] = qual[7];
+    list->qual[2] = qual[8];
+   
+    if(!qual[9]) break;
+    else if(qual[9] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("cal 8 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[9] = 0;
+        break;
+      }
+      qual[9]  = caltab[0];
+      qual[10] = caltab[1];
+    } 
+    list->qual[3] = qual[9];
+    list->qual[4] = qual[10];
+
+    if(!qual[25]) break;
+    else if(qual[25] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[25] = 0;
+        break;
+      }    
+      qual[25] = caltab[0];
+      qual[26] = caltab[1];
+    }
+    list->qual[5] = qual[25];
+    list->qual[6] = qual[26];
+
+    if(!qual[35]) break;
+    else if(qual[35] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[35] = 0;
+        break;
+      }	 
+      qual[35] = caltab[0];
+      qual[36] = caltab[1];
+    }
+    list->qual[7] = qual[35];
+    list->qual[8] = qual[36];
+
+    if(!qual[63]) break;
+    else if(qual[63] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[63] = 0;
+        break;
+      }  
+      qual[63] = caltab[0];
+      qual[64] = caltab[1];
+    }
+    list->qual[9]  = qual[63];
+    list->qual[10] = qual[64];
+    
+    MMG_swpptr = MMG_swap710_35;
+    memset(pt1,0,sizeof(Tetra));
+    return(105); 
+} while(0);
+
+/*cas 36*/
+do {
+    if(!qual[1]) break;
+    list->qual[1] = qual[1];
+    list->qual[2] = qual[2];
+
+    if(!qual[11]) break;
+    else if (qual[11] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s5;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab))  {
+        //printf("2:cal 11 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[11] = 0;
+        break;
+      }
+      qual[11] = caltab[0];
+      qual[12] = caltab[1];
+    }
+    list->qual[3] = qual[11];
+    list->qual[4] = qual[12];
+    
+    if(!qual[13]) break;
+    else if(qual[13] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s5;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[13] = 0;
+        break;
+      }
+      qual[13] = caltab[0];
+      qual[14] = caltab[1];
+    } 
+    list->qual[5] = qual[13];
+    list->qual[6] = qual[14];
+
+    if(!qual[37]) break;
+    else if(qual[37] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[37] = 0;
+        break;
+      }	 
+      qual[37] = caltab[0];
+      qual[38] = caltab[1];
+    }
+    list->qual[7] = qual[37];
+    list->qual[8] = qual[38];
+    
+    if(!qual[61]) break;
+    else if(qual[61] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s3;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[61] = 0;
+        break;
+      }  
+      qual[61] = caltab[0];
+      qual[62] = caltab[1];
+    }
+    list->qual[9]  = qual[61];
+    list->qual[10] = qual[62];         
+    
+    MMG_swpptr = MMG_swap710_36;
+    memset(pt1,0,sizeof(Tetra));
+    return(106); 
+} while(0);
+
+/*cas 37*/
+do {
+    if(!qual[11]) break;
+    else if (qual[11] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s5;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab))  {
+        //printf("2:cal 11 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[11] = 0;
+        break;
+      }
+      qual[11] = caltab[0];
+      qual[12] = caltab[1];
+    }
+    list->qual[1] = qual[11];
+    list->qual[2] = qual[12];
+    
+    if(!qual[13]) break;
+    else if(qual[13] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s5;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[13] = 0;
+        break;
+      }
+      qual[13] = caltab[0];
+      qual[14] = caltab[1];
+    } 
+    list->qual[3] = qual[13];
+    list->qual[4] = qual[14];
+    
+    if(!qual[37]) break;
+    else if(qual[37] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[37] = 0;
+        break;
+      }	 
+      qual[37] = caltab[0];
+      qual[38] = caltab[1];
+    }
+    list->qual[5] = qual[37];
+    list->qual[6] = qual[38];
+
+    if(!qual[39]) break;
+    else if(qual[39] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[39] = 0;
+        break;
+      }	 
+      qual[39] = caltab[0];
+      qual[40] = caltab[1];
+    }
+    list->qual[7] = qual[39];
+    list->qual[8] = qual[40];
+
+    if(!qual[63]) break;
+    else if(qual[63] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[63] = 0;
+        break;
+      }  
+      qual[63] = caltab[0];
+      qual[64] = caltab[1];
+    }
+    list->qual[9]  = qual[63];
+    list->qual[10] = qual[64];
+    
+    MMG_swpptr = MMG_swap710_37;
+    memset(pt1,0,sizeof(Tetra));
+    return(107); 
+} while(0);
+
+/*cas 38*/
+do {
+    if(!qual[11]) break;
+    else if (qual[11] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s5;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab))  {
+        //printf("2:cal 11 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[11] = 0;
+        break;
+      }
+      qual[11] = caltab[0];
+      qual[12] = caltab[1];
+    }
+    list->qual[1] = qual[11];
+    list->qual[2] = qual[12];
+    
+    if(!qual[13]) break;
+    else if(qual[13] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s5;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[13] = 0;
+        break;
+      }
+      qual[13] = caltab[0];
+      qual[14] = caltab[1];
+    } 
+    list->qual[3] = qual[13];
+    list->qual[4] = qual[14];
+
+    if(!qual[25]) break;
+    else if(qual[25] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[25] = 0;
+        break;
+      }    
+      qual[25] = caltab[0];
+      qual[26] = caltab[1];
+    }
+    list->qual[5] = qual[25];
+    list->qual[6] = qual[26];
+
+    if(!qual[35]) break;
+    else if(qual[35] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[35] = 0;
+        break;
+      }	 
+      qual[35] = caltab[0];
+      qual[36] = caltab[1];
+    }
+    list->qual[7] = qual[35];
+    list->qual[8] = qual[36];
+
+    if(!qual[63]) break;
+    else if(qual[63] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[63] = 0;
+        break;
+      }  
+      qual[63] = caltab[0];
+      qual[64] = caltab[1];
+    }
+    list->qual[9]  = qual[63];
+    list->qual[10] = qual[64];
+    
+    MMG_swpptr = MMG_swap710_38;
+    memset(pt1,0,sizeof(Tetra));
+    return(108); 
+} while(0);
+
+/*cas 39*/
+do {
+    if(!qual[13]) break;
+    else if(qual[13] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s5;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[13] = 0;
+        break;
+      }
+      qual[13] = caltab[0];
+      qual[14] = caltab[1];
+    } 
+    list->qual[1] = qual[13];
+    list->qual[2] = qual[14];
+
+    if(!qual[29]) break;
+    else if(qual[29] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[29] = 0;
+        break;
+      }	 
+      qual[29] = caltab[0];
+      qual[30] = caltab[1];
+    }
+    list->qual[3] = qual[29];
+    list->qual[4] = qual[30];
+    
+    if(!qual[37]) break;
+    else if(qual[37] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[37] = 0;
+        break;
+      }	 
+      qual[37] = caltab[0];
+      qual[38] = caltab[1];
+    }
+    list->qual[5] = qual[37];
+    list->qual[6] = qual[38];    
+
+    if(!qual[39]) break;
+    else if(qual[39] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[39] = 0;
+        break;
+      }	 
+      qual[39] = caltab[0];
+      qual[40] = caltab[1];
+    }
+    list->qual[7] = qual[39];
+    list->qual[8] = qual[40];
+
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s2;
+    pt1->v[2] = s5;
+    pt1->v[3] = s7;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[65] = 0;
+      break;
+    }  
+    qual[65] = caltab[0];
+    qual[66] = caltab[1];  
+    list->qual[9]  = qual[65];
+    list->qual[10] = qual[66];
+        
+    MMG_swpptr = MMG_swap710_39;
+    memset(pt1,0,sizeof(Tetra));
+    return(109); 
+} while(0);
+
+/*cas 40*/
+do {
+    if(!qual[13]) break;
+    else if(qual[13] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s5;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[13] = 0;
+        break;
+      }
+      qual[13] = caltab[0];
+      qual[14] = caltab[1];
+    } 
+    list->qual[1] = qual[13];
+    list->qual[2] = qual[14];
+
+    if(!qual[25]) break;
+    else if(qual[25] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s3;
+      pt1->v[3] = s4;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[25] = 0;
+        break;
+      }    
+      qual[25] = caltab[0];
+      qual[26] = caltab[1];
+    }
+    list->qual[3] = qual[25];
+    list->qual[4] = qual[26];
+
+    if(!qual[29]) break;
+    else if(qual[29] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s2;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[29] = 0;
+        break;
+      }	 
+      qual[29] = caltab[0];
+      qual[30] = caltab[1];
+    }
+    list->qual[5] = qual[29];
+    list->qual[6] = qual[30];
+
+    if(!qual[35]) break;
+    else if(qual[35] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[35] = 0;
+        break;
+      }	 
+      qual[35] = caltab[0];
+      qual[36] = caltab[1];
+    }
+    list->qual[7] = qual[35];
+    list->qual[8] = qual[36];
+
+    if(!qual[65]) break;
+    else if(qual[65] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s2;
+      pt1->v[2] = s5;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[65] = 0;
+        break;
+      }  
+      qual[65] = caltab[0];
+      qual[66] = caltab[1];  
+    }
+    list->qual[9]  = qual[65];
+    list->qual[10] = qual[66];
+
+    MMG_swpptr = MMG_swap710_40;
+    memset(pt1,0,sizeof(Tetra));
+    return(110); 
+} while(0);
+
+/*cas 41*/
+do {
+    if(!qual[1]) break;
+    list->qual[1] = qual[1];
+    list->qual[2] = qual[2];
+
+    if(!qual[9]) break;
+    else if(qual[9] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 9 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[9] = 0;
+        break;
+      }
+      qual[9]  = caltab[0];
+      qual[10] = caltab[1];
+    } 
+    list->qual[3] = qual[9];
+    list->qual[4] = qual[10];
+
+    if(!qual[21]) break;
+    else if(qual[21] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s4;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[21] = 0;
+        break;
+      }
+      qual[21] = caltab[0];
+      qual[22] = caltab[1];
+    }  
+    list->qual[5] = qual[21];
+    list->qual[6] = qual[22];
+
+    if(!qual[45]) break;
+    else if(qual[45] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[45] = 0;
+        break;
+      }	 
+      qual[45] = caltab[0];
+      qual[46] = caltab[1];
+    }
+    list->qual[7] = qual[45];
+    list->qual[8] = qual[46];
+
+    pt1 = &mesh->tetra[0];
+    pt1->v[0] = ia;
+    pt1->v[1] = s1;
+    pt1->v[2] = s3;
+    pt1->v[3] = s6;
+    if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+      //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+      memset(pt1,0,sizeof(Tetra));
+      qual[67] = 0;
+      break;
+    }  
+    qual[67] = caltab[0];
+    qual[68] = caltab[1];
+    list->qual[9]  = qual[67];
+    list->qual[10] = qual[68];
+    
+    MMG_swpptr = MMG_swap710_41;
+    memset(pt1,0,sizeof(Tetra));
+    return(111); 
+} while(0);
+
+/*cas 42*/
+do {
+    if(!qual[1]) break;
+    list->qual[1] = qual[1];
+    list->qual[2] = qual[2];
+
+    if(!qual[9]) break;
+    else if(qual[9] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s6;
+      pt1->v[3] = s7;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){
+        //printf("2:cal 9 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+	qual[9] = 0;
+        break;
+      }
+      qual[9]  = caltab[0];
+      qual[10] = caltab[1];
+    } 
+    list->qual[3] = qual[9];
+    list->qual[4] = qual[10];
+
+    if(!qual[37]) break;
+    else if(qual[37] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s4;
+      pt1->v[3] = s5;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[37] = 0;
+        break;
+      }	 
+      qual[37] = caltab[0];
+      qual[38] = caltab[1];
+    }
+    list->qual[5] = qual[37];
+    list->qual[6] = qual[38]; 
+
+    if(!qual[43]) break;
+    else if(qual[43] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s3;
+      pt1->v[2] = s5;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[43] = 0;
+        break;
+      }	 
+      qual[43] = caltab[0];
+      qual[44] = caltab[1];
+    }
+    list->qual[7] = qual[43];
+    list->qual[8] = qual[44];    
+
+    if(!qual[67]) break;
+    else if(qual[67] == -1) {
+      pt1 = &mesh->tetra[0];
+      pt1->v[0] = ia;
+      pt1->v[1] = s1;
+      pt1->v[2] = s3;
+      pt1->v[3] = s6;
+      if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) {
+        //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0));
+        memset(pt1,0,sizeof(Tetra));
+        qual[67] = 0;
+        break;
+      }  
+      qual[67] = caltab[0];
+      qual[68] = caltab[1];
+    }
+    list->qual[9]  = qual[67];
+    list->qual[10] = qual[68];
+    
+    MMG_swpptr = MMG_swap710_42;
+    memset(pt1,0,sizeof(Tetra));
+    return(112);
+} while(0);
+ 
+ return(0);
+}
diff --git a/contrib/mmg3d/build/sources/solmap.c b/contrib/mmg3d/build/sources/solmap.c
new file mode 100644
index 0000000000000000000000000000000000000000..16e05cefc3b070eaa28b420f104d1824ffbd4a84
--- /dev/null
+++ b/contrib/mmg3d/build/sources/solmap.c
@@ -0,0 +1,208 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+static int MMG_inxtt[5] = {0,1,2,0,1};
+
+
+/* compute iso size map */
+int MMG_doSol(pMesh mesh,pSol sol) {
+  pTetra     pt;
+  pTria      ptt;
+  pPoint     p1,p2;
+  double     ux,uy,uz,dd;
+  int        i,k,ia,ib,ipa,ipb;
+
+  /* memory alloc */
+  sol->np     = mesh->np;
+  sol->npfixe = mesh->npfixe;
+  sol->npmax  = mesh->npmax;
+  sol->offset = 1;
+
+  if ( !MMG_zaldy3(sol) )  return(0);
+  /* boundary edges */
+  for (k=1; k<=mesh->nt; k++) {
+    ptt = &mesh->tria[k];
+    if ( !ptt->v[0] )  continue;
+
+    for (i=0; i<3; i++) {
+      ib  = MMG_inxtt[i+1];
+      ipa = ptt->v[i];
+      ipb = ptt->v[ib];
+      p1  = &mesh->point[ipa];
+      p2  = &mesh->point[ipb];
+
+      ux  = p1->c[0] - p2->c[0];
+      uy  = p1->c[1] - p2->c[1];
+      uz  = p1->c[2] - p2->c[2];
+      dd  = sqrt(ux*ux + uy*uy + uz*uz);
+
+      sol->met[ipa] += dd;
+      p1->mark++;
+      sol->met[ipb] += dd;
+      p2->mark++;
+    }
+  }
+
+  /* internal edges */
+  for (k=1; k<=mesh->ne; k++) {
+    pt = &mesh->tetra[k];
+    if ( !pt->v[0] )  continue;
+
+    /* internal edges */
+    for (i=0; i<6; i++) {
+      ia  = MMG_iare[i][0];
+      ib  = MMG_iare[i][1];
+      ipa = pt->v[ia];
+      ipb = pt->v[ib];
+      p1  = &mesh->point[ipa];
+      p2  = &mesh->point[ipb];
+
+      ux  = p1->c[0] - p2->c[0];
+      uy  = p1->c[1] - p2->c[1];
+      uz  = p1->c[2] - p2->c[2];
+      dd  = sqrt(ux*ux + uy*uy + uz*uz);
+
+      //if ( !(p1->tag & M_BDRY) ) {
+        sol->met[ipa] += dd;
+        p1->mark++;
+      //}
+      //if ( !(p2->tag & M_BDRY) ) {
+        sol->met[ipb] += dd;
+        p2->mark++;
+      //}
+    }
+  }
+
+  /* vertex size */
+  sol->hmin = 1.e20;
+  sol->hmax = 0.0;
+  for (k=1; k<=mesh->np; k++) {
+    p1 = &mesh->point[k];
+    if ( !p1->mark )  continue;
+
+    sol->met[k] = sol->met[k] / (double)p1->mark;
+ 
+    if ( sol->met[k] < sol->hmin )
+      sol->hmin = sol->met[k];
+    else if ( sol->met[k] > sol->hmax )
+      sol->hmax = sol->met[k];
+
+    p1->mark = 0;
+  }
+
+  if ( mesh->info.imprim < -4 )
+    fprintf(stdout,"     HMIN %f   HMAX %f\n",sol->hmin,sol->hmax);   
+    
+  /*compute quality*/
+  for (k=1; k<=mesh->ne; k++) {
+    pt = &mesh->tetra[k]; 
+    if ( pt->v[0] ) 
+      pt->qual = MMG_caltet(mesh,sol,k);
+    else
+      pt->qual = 0.0;
+  }
+    
+  return(1);
+}
+
+/* interpol iso/aniso size map */
+int MMG_computeMetric(pMesh mesh,pSol sol,int ip,double * coor) {
+  pTetra 	pt;
+  pPoint 	ppt;
+  double 	cb[4];
+  double 	dma[6],mai[6],mi[6];
+  double 	*mp,*ma;
+  int    	ktet,i,k,base,iadr,ia;
+  
+  ppt = &mesh->point[ip];
+  base = ++mesh->mark;
+  ktet = MMG_loctet(mesh,ppt->tmp,base,coor,cb);
+  if(!ktet) return(-1);
+  assert(ktet < mesh->ne + 1);
+  pt = &mesh->tetra[ktet];
+  
+  if ( sol->offset == 1 ) {
+    sol->met[ip] = cb[0] * sol->metold[pt->v[0]];
+  
+    for(k = 1 ; k < 4 ; k++) {
+      sol->met[ip] += cb[k] * sol->metold[pt->v[k]];
+    }
+  } else {
+    iadr = (ip-1)*sol->offset + 1;
+    mp   = &sol->met[iadr];
+      
+    for (i=0; i<6; i++) mi[i] = 0;
+    
+    for(k = 0 ; k < 4 ; k++) {
+      ia   = pt->v[k];
+      iadr = (ia-1)*sol->offset + 1;
+      ma   = &sol->met[iadr];
+      for (i=0; i<6; i++) {
+        dma[i] = ma[i];
+      }
+      
+      if ( !MMG_invmat(dma,mai) ) {
+        fprintf(stderr,"  ## INVALID METRIC.\n");
+        return(0);
+      }
+  
+      for (i=0; i<6; i++)
+        mi[i] += cb[k]*mai[i];
+    }
+    
+    if ( !MMG_invmat(mi,mai) ) {
+      fprintf(stderr,"  ## INVALID METRIC.\n");
+      return(0);
+    }
+  
+    for (i=0; i<6; i++)  mp[i] = mai[i];
+
+  }  
+  
+  return(1);
+}
+
diff --git a/contrib/mmg3d/build/sources/spledg.c b/contrib/mmg3d/build/sources/spledg.c
new file mode 100644
index 0000000000000000000000000000000000000000..de9965df9f9cced2525b7dcaedfee865ce13e804
--- /dev/null
+++ b/contrib/mmg3d/build/sources/spledg.c
@@ -0,0 +1,132 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+#define QCOEF   0.995
+
+
+int MMG_spledg(pMesh mesh,pSol sol,pQueue queue,pList list,int lon,double crit,double declic) {
+  pTetra    pt,pt0,pt1;
+  pPoint    pa,pb;
+  double     cal;
+  double    *ca,*cb,c[3],*ma,*mb,*mip,mp[6];
+  int       l,ipa,ipb,ip,jel,na,nbt,iel,iar,ret,iadr;
+  short     ia,ib;
+    
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  ia  = MMG_iare[iar][0];
+  ib  = MMG_iare[iar][1];
+
+  pt  = &mesh->tetra[iel];
+  ipa = pt->v[ia];
+  ipb = pt->v[ib];
+  pa  = &mesh->point[ipa];
+  pb  = &mesh->point[ipb];
+  
+  ca  = &mesh->point[ipa].c[0];
+  cb  = &mesh->point[ipb].c[0];
+       
+  iadr = (ipa-1)*sol->offset + 1;
+  ma  = &sol->met[iadr];
+
+  iadr = (ipb-1)*sol->offset + 1;
+  mb  = &sol->met[iadr];
+    
+  /* metric interpolation */
+  if ( !MMG_interp(ma,mb,mp,0.5) ) return(0);
+	
+  c[0] = 0.5*(ca[0] + cb[0]);
+  c[1] = 0.5*(ca[1] + cb[1]);
+  c[2] = 0.5*(ca[2] + cb[2]);
+  ip   = MMG_newPt(mesh,c);
+  if ( ip < 1 ) return(0);
+  iadr = (ip-1)*sol->offset + 1;
+  mip  = &sol->met[iadr];	  
+  memcpy(mip,mp,sol->offset*sizeof(double));
+    
+  /* eval coquille */
+  pt0  = &mesh->tetra[0];
+  nbt  = 0;
+  for (l=1; l<=lon; l++) {
+    jel = list->tetra[l] / 6;
+    na  = list->tetra[l] % 6;
+    pt1 = &mesh->tetra[jel];
+
+    memcpy(pt0->v,pt1->v,4*sizeof(int));
+    ipb = MMG_iare[na][0];
+    pt0->v[ipb] = ip;
+    cal = MMG_caltet(mesh,sol,0);
+    if ( cal > crit ) {
+      MMG_delPt(mesh,ip);
+      return(0);
+    }
+
+    memcpy(pt0->v,pt1->v,4*sizeof(int));
+    ipb = MMG_iare[na][1];
+    pt0->v[ipb] = ip;
+    cal = MMG_caltet(mesh,sol,0);
+    if ( cal > crit ) {
+      MMG_delPt(mesh,ip);
+      return(0);
+    }
+  }
+
+  /* update */
+  for (l=1; l<=lon; l++) {
+    list->tetra[l] = list->tetra[l] / 6;
+    mesh->tetra[list->tetra[l]].mark = mesh->mark;
+  }
+  ret = MMG_delons(mesh,sol,queue,ip,list,lon,declic);
+  if ( ret <= 0 ) {
+    MMG_delPt(mesh,ip);
+    return(0);
+  }
+  else {  
+    return(ip);  
+  }
+}
+
diff --git a/contrib/mmg3d/build/sources/sproto.h b/contrib/mmg3d/build/sources/sproto.h
new file mode 100644
index 0000000000000000000000000000000000000000..178623047f10fc79039824bed172d372282a1f0e
--- /dev/null
+++ b/contrib/mmg3d/build/sources/sproto.h
@@ -0,0 +1,240 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+
+int MMG_cassar(pMesh mesh,pSol sol,int ipa,int ipb,float t);
+int MMG_analar(pMesh ,pSol ,pBucket ,int *,int *,int *,int *);
+int MMG_boulep(pMesh ,int ,int ,pList );
+int MMG_bouleg(pMesh ,int ,int ,pList );
+int MMG_coquil(pMesh ,int ,int ,pList );
+int MMG_cendel(pMesh ,pSol ,float ,int );
+int MMG_spledg(pMesh ,pSol ,pQueue ,pList ,int ,float ,float );
+
+/* delaunay */
+int MMG_correction(pMesh ,int ,pList ,int ,int ,char );
+int MMG_delone(pMesh ,pSol ,int ,pList ,int );
+int MMG_delons(pMesh ,pSol ,pQueue ,int ,pList ,int ,float );
+int MMG_cenrad_ani(pMesh ,pSol ,int ,double *,double *,double *); 
+int MMG_cenrad_iso(pMesh ,pSol ,int ,double *,double *); 
+
+int MMG_colpoi(pMesh ,pSol ,int ,int ,int ,float );
+
+/* hash */
+int  MMG_hashTetra(pMesh );
+int  MMG_hashEdge(pMesh ,pHedge ,int ,int ,int *);
+int  MMG_inEdge(pHedge ,int *,int *,int *);
+int  MMG_markBdry(pMesh );
+
+/* inout */
+int  MMG_loadMesh(pMesh ,char *);
+int  MMG_loadSol(pSol ,char *,int );
+int  MMG_loadVect(pMesh ,char *,int );
+int  MMG_saveMesh(pMesh ,char *);
+int  MMG_saveSol(pMesh ,pSol ,char *);
+int  MMG_saveVect(pMesh ,char *);
+
+int  MMG_loctet(pMesh ,int ,int ,double *,double *);
+int  MMG_computeMetric(pMesh ,pSol ,int ,double * );
+
+/* scale */
+int  MMG_doSol(pMesh ,pSol );
+int  MMG_scaleMesh(pMesh ,pSol );
+int  MMG_unscaleMesh(pMesh ,pSol );
+
+int  MMG_mmg3d1(pMesh ,pSol ,int *);
+int  MMG_mmg3d9(pMesh ,pSol ,int *);
+
+
+/* zaldy */
+int  MMG_newPt(pMesh ,double *c);
+int  MMG_newElt(pMesh );
+int  MMG_getnElt(pMesh ,int );
+int  MMG_newTria(pMesh );
+void MMG_delPt(pMesh ,int );
+void MMG_delElt(pMesh ,int );
+void MMG_delTria(pMesh ,int );
+int  MMG_zaldy(pMesh );
+int  MMG_zaldy3(pSol );
+int  MMG_zaldy4(pHedge ,int );
+
+int  MMG_optra4(pMesh ,pSol );
+int  MMG_optcoq(pMesh ,pSol);
+int  MMG_opttet(pMesh ,pSol);
+int  MMG_opttyp(pMesh ,pSol ,float ,int *);
+int  MMG_optbdry(pMesh ,pSol ,int );
+int  MMG_opt2peau(pMesh ,pSol ,pQueue ,int ,float );
+int  MMG_optlap(pMesh ,pSol );
+
+/* swapar */
+typedef int (*MMG_Swap)(pMesh ,pSol ,pList );
+//MMG_Swap MMG_swpptr;
+
+int  MMG_swapar(pMesh ,pSol ,pQueue ,List *,int ,float ,float );
+
+int  MMG_simu23(pMesh ,pSol ,int ,int ,float );
+int  MMG_simu32(pMesh ,pSol ,pList ,float );
+int  MMG_swap32(pMesh ,pSol ,pList );
+int  MMG_swap23(pMesh ,pSol ,pQueue ,int ,int ,float );
+
+int  MMG_simu44(pMesh ,pSol ,pList ,float );
+int  MMG_swap44_1(pMesh ,pSol ,pList );
+int  MMG_swap44_2(pMesh ,pSol ,pList );
+
+int  MMG_simu56(pMesh ,pSol ,pList ,float );
+int  MMG_swap56_1(pMesh ,pSol ,pList );
+int  MMG_swap56_2(pMesh ,pSol ,pList );
+int  MMG_swap56_3(pMesh ,pSol ,pList );
+int  MMG_swap56_4(pMesh ,pSol ,pList );
+int  MMG_swap56_5(pMesh ,pSol ,pList );
+
+int MMG_simu68(pMesh ,pSol ,pList ,float );
+int MMG_swap68_1(pMesh ,pSol ,pList );
+int MMG_swap68_2(pMesh ,pSol ,pList );
+int MMG_swap68_3(pMesh ,pSol ,pList );
+int MMG_swap68_4(pMesh ,pSol ,pList );
+int MMG_swap68_5(pMesh ,pSol ,pList );
+int MMG_swap68_6(pMesh ,pSol ,pList );
+int MMG_swap68_7(pMesh ,pSol ,pList );
+int MMG_swap68_8(pMesh ,pSol ,pList );
+int MMG_swap68_9(pMesh ,pSol ,pList );
+int MMG_swap68_10(pMesh ,pSol ,pList );
+int MMG_swap68_11(pMesh ,pSol ,pList );
+int MMG_swap68_12(pMesh ,pSol ,pList );
+int MMG_swap68_13(pMesh ,pSol ,pList );
+int MMG_swap68_14(pMesh ,pSol ,pList );
+
+int MMG_simu710(pMesh ,pSol ,pList ,float );
+int MMG_swap710_1(pMesh ,pSol ,pList );
+int MMG_swap710_2(pMesh ,pSol ,pList );
+int MMG_swap710_3(pMesh ,pSol ,pList );
+int MMG_swap710_4(pMesh ,pSol ,pList );
+int MMG_swap710_5(pMesh ,pSol ,pList );
+int MMG_swap710_6(pMesh ,pSol ,pList );
+int MMG_swap710_7(pMesh ,pSol ,pList );
+int MMG_swap710_8(pMesh ,pSol ,pList );
+int MMG_swap710_9(pMesh ,pSol ,pList );
+int MMG_swap710_10(pMesh ,pSol sol,pList list);
+int MMG_swap710_11(pMesh ,pSol sol,pList list);
+int MMG_swap710_12(pMesh ,pSol sol,pList list);
+int MMG_swap710_13(pMesh ,pSol ,pList );
+int MMG_swap710_14(pMesh ,pSol ,pList );
+int MMG_swap710_15(pMesh ,pSol ,pList );
+int MMG_swap710_16(pMesh ,pSol ,pList );
+int MMG_swap710_17(pMesh ,pSol ,pList );
+int MMG_swap710_18(pMesh ,pSol ,pList );
+int MMG_swap710_19(pMesh ,pSol ,pList );
+int MMG_swap710_20(pMesh ,pSol ,pList );
+int MMG_swap710_21(pMesh ,pSol ,pList );
+int MMG_swap710_22(pMesh ,pSol ,pList );
+int MMG_swap710_23(pMesh ,pSol ,pList );
+int MMG_swap710_24(pMesh ,pSol ,pList );
+int MMG_swap710_25(pMesh ,pSol ,pList );
+int MMG_swap710_26(pMesh ,pSol ,pList );
+int MMG_swap710_27(pMesh ,pSol ,pList );
+int MMG_swap710_28(pMesh ,pSol ,pList );
+int MMG_swap710_29(pMesh ,pSol ,pList );
+int MMG_swap710_30(pMesh ,pSol ,pList );
+int MMG_swap710_31(pMesh ,pSol ,pList );
+int MMG_swap710_32(pMesh ,pSol ,pList );
+int MMG_swap710_33(pMesh ,pSol ,pList );
+int MMG_swap710_34(pMesh ,pSol ,pList );
+int MMG_swap710_35(pMesh ,pSol ,pList );
+int MMG_swap710_36(pMesh ,pSol ,pList );
+int MMG_swap710_37(pMesh ,pSol ,pList );
+int MMG_swap710_38(pMesh ,pSol ,pList );
+int MMG_swap710_39(pMesh ,pSol ,pList );
+int MMG_swap710_40(pMesh ,pSol ,pList );
+int MMG_swap710_41(pMesh ,pSol ,pList );
+int MMG_swap710_42(pMesh ,pSol ,pList );
+
+int  MMG_typelt(pMesh ,int ,int *);
+
+/* function pointers */
+extern double (*MMG_length)(pMesh ,pSol ,int ,int );
+extern double (*MMG_caltet)(pMesh ,pSol ,int );
+extern double (*MMG_calte1)(pMesh ,pSol ,int );
+extern int    (*MMG_caltet2)(pMesh ,pSol ,int ,int ,double ,double *);
+extern int    (*MMG_cavity)(pMesh ,pSol ,int ,int ,pList ,int );
+extern int    (*MMG_buckin)(pMesh ,pSol ,pBucket ,int );
+extern int    (*MMG_optlen)(pMesh ,pSol ,float ,int );
+extern int    (*MMG_interp)(double *,double *,double *,float );
+extern int    (*MMG_optlentet)(pMesh ,pSol ,pQueue ,float ,int ,int );
+extern int    (*MMG_movevertex)(pMesh ,pSol ,int ,int );
+
+/* quality */
+double MMG_voltet(pMesh ,int );
+double MMG_quickvol(double *,double *,double *,double *);
+int    MMG_prilen(pMesh ,pSol );
+void   MMG_outqua(pMesh ,pSol );
+double MMG_priworst(pMesh , pSol );
+
+int  MMG_chkmsh(pMesh ,int ,int );
+
+/* bucket */
+pBucket MMG_newBucket(pMesh ,int );
+int     MMG_addBucket(pMesh ,pBucket ,int );
+int     MMG_delBucket(pMesh ,pBucket ,int );
+void    MMG_freeBucket(pBucket );
+
+/* heap */
+Heap *MMG_hipini(pMesh ,int ,short ,float ,int );
+void  MMG_hipfree(Heap *);
+int   MMG_hipput(pMesh ,Heap *,int );
+int   MMG_hippop(pMesh ,Heap *);
+void  MMG_hiprep(pMesh ,Heap *,int );
+void  MMG_hipdel(pMesh ,Heap *,int );
+
+/* queue */
+pQueue MMG_kiuini(pMesh ,int ,float ,int );
+int    MMG_kiupop(pQueue );
+int    MMG_kiudel(pQueue ,int );
+int    MMG_kiuput(pQueue ,int );
+void   MMG_kiufree(pQueue );
+
+/* matrices */
+int MMG_invmat(double *,double *);
+
+double MMG_calte3_ani(pMesh mesh,pSol sol,int iel);
+
diff --git a/contrib/mmg3d/build/sources/swap23.c b/contrib/mmg3d/build/sources/swap23.c
new file mode 100644
index 0000000000000000000000000000000000000000..f51bfef10400b03f5a40e4fccf072720492f2fb8
--- /dev/null
+++ b/contrib/mmg3d/build/sources/swap23.c
@@ -0,0 +1,678 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+int MMG_swap23(pMesh mesh,pSol sol,pQueue q, int iel,int iar, double declic) {
+  pTetra pt,pt_a,pt1,pt2,pt3;
+  int jel,*adja,*adja_a,i_a,v,v_a,voy_a,a0,a1,a2;
+  int iadr,kel,lel,*adja1,adj0,adj1,adj2;
+  int s[3],n0,n1,n2,ref;
+
+  pt   = &mesh->tetra[iel];
+  ref  = pt->ref;
+  iadr = 4*(iel-1) + 1;
+  adja = &mesh->adja[iadr];
+  v    = pt->v[iar];
+  
+  i_a = adja[iar] >> 2;
+  assert(i_a);
+  voy_a = adja[iar] % 4;
+  pt_a = &mesh->tetra[i_a];
+  v_a = pt_a->v[voy_a];
+  iadr = 4*(i_a-1) + 1;
+  adja_a = &mesh->adja[iadr];
+  
+  /*check iel and i_a in the same SD*/
+	if(pt->ref != pt_a->ref) return(0);
+	
+  n0 = MMG_idir[iar][0];
+  n1 = MMG_idir[iar][1];
+  n2 = MMG_idir[iar][2];
+
+  s[0] = pt->v[n0];
+  s[1] = pt->v[n1];
+  s[2] = pt->v[n2];
+    
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[1] = v_a;
+  pt1->v[0] = v;
+  pt1->v[2] = s[0];
+  pt1->v[3] = s[1];
+  pt1->qual = MMG_caltet(mesh,sol,jel);
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  if ( pt1->qual >= declic )  MMG_kiuput(q,jel);
+  
+  kel = MMG_newElt(mesh);
+  pt2 = &mesh->tetra[kel];
+  pt2->v[1] = v_a;
+  pt2->v[0] = v;
+  pt2->v[2] = s[1];
+  pt2->v[3] = s[2]; 
+  pt2->qual = MMG_caltet(mesh,sol,kel);
+  pt2->flag = mesh->flag;
+  pt2->ref  = ref;
+  if ( pt2->qual >= declic )  MMG_kiuput(q,kel);
+
+  lel = MMG_newElt(mesh);
+  pt3 = &mesh->tetra[lel];
+  pt3->v[1] = v_a;
+  pt3->v[0] = v;
+  pt3->v[2] = s[2];
+  pt3->v[3] = s[0];   
+  pt3->qual = MMG_caltet(mesh,sol,lel);
+  pt3->flag = mesh->flag;
+  pt3->ref  = ref;
+  if ( pt3->qual >= declic )  MMG_kiuput(q,lel);
+
+//printf("qual %e %e %e\n",pt1->qual,pt2->qual,pt3->qual);
+  /*neighboors*/
+  a0 = n0;
+  a1 = n1;
+  a2 = n2;
+  
+  if(pt->v[MMG_idir[n0][0]] == v) {
+    if(pt->v[MMG_idir[n0][1]] == s[0]
+       || pt->v[MMG_idir[n0][2]] == s[0]) {
+       if(pt->v[MMG_idir[n0][1]] == s[1]
+       || pt->v[MMG_idir[n0][2]] == s[1])
+         a0 = n0;
+       else {
+         assert(pt->v[MMG_idir[n0][1]] == s[2]
+        	|| pt->v[MMG_idir[n0][2]] == s[2]);
+         a2 = n0;
+       }	   
+     } else {
+       a1 = n0;
+     }   
+  } else if(pt->v[MMG_idir[n0][1]] == v){
+    if(pt->v[MMG_idir[n0][0]] == s[0]
+       || pt->v[MMG_idir[n0][2]] == s[0]) {
+       if(pt->v[MMG_idir[n0][0]] == s[1]
+       || pt->v[MMG_idir[n0][2]] == s[1])
+         a0 = n0;
+       else {
+         assert(pt->v[MMG_idir[MMG_idir[iar][0]][0]] == s[2]
+        	|| pt->v[MMG_idir[MMG_idir[iar][0]][2]] == s[2]);
+         a2 = n0;
+       }	   
+     } else {
+       a1 = n0;
+     }   
+  } else {
+    assert(pt->v[MMG_idir[n0][2]] == v);
+    if(pt->v[MMG_idir[n0][1]] == s[0]
+       || pt->v[MMG_idir[n0][0]] == s[0]) {
+       if(pt->v[MMG_idir[n0][1]] == s[1]
+       || pt->v[MMG_idir[n0][0]] == s[1])
+         a0 = n0;
+       else {
+         assert(pt->v[MMG_idir[n0][1]] == s[2]
+        	|| pt->v[MMG_idir[n0][0]] == s[2]);
+         a2 = n0;
+       }	   
+     } else {
+       a1 = n0;
+     }     
+  }
+
+  if(pt->v[MMG_idir[MMG_idir[iar][1]][0]] == v) {
+    if(pt->v[MMG_idir[MMG_idir[iar][1]][1]] == s[0]
+       || pt->v[MMG_idir[MMG_idir[iar][1]][2]] == s[0]) {
+       if(pt->v[MMG_idir[MMG_idir[iar][1]][1]] == s[1]
+       || pt->v[MMG_idir[MMG_idir[iar][1]][2]] == s[1])
+         a0 = MMG_idir[iar][1];
+       else {
+         assert(pt->v[MMG_idir[MMG_idir[iar][1]][1]] == s[2]
+        	|| pt->v[MMG_idir[MMG_idir[iar][1]][2]] == s[2]);
+         a2 = MMG_idir[iar][1];
+       }	   
+     } else {
+       a1 = MMG_idir[iar][1];
+     }   
+  } else if(pt->v[MMG_idir[MMG_idir[iar][1]][1]] == v){
+    if(pt->v[MMG_idir[MMG_idir[iar][1]][0]] == s[0]
+       || pt->v[MMG_idir[MMG_idir[iar][1]][2]] == s[0]) {
+       if(pt->v[MMG_idir[MMG_idir[iar][1]][0]] == s[1]
+       || pt->v[MMG_idir[MMG_idir[iar][1]][2]] == s[1])
+         a0 = MMG_idir[iar][1];
+       else {
+         assert(pt->v[MMG_idir[MMG_idir[iar][1]][0]] == s[2]
+        	|| pt->v[MMG_idir[MMG_idir[iar][1]][2]] == s[2]);
+         a2 = MMG_idir[iar][1];
+       }	   
+     } else {
+       a1 = MMG_idir[iar][1];
+     }   
+  } else {
+    assert(pt->v[MMG_idir[MMG_idir[iar][1]][2]] == v);
+    if(pt->v[MMG_idir[MMG_idir[iar][1]][1]] == s[0]
+       || pt->v[MMG_idir[MMG_idir[iar][1]][0]] == s[0]) {
+       if(pt->v[MMG_idir[MMG_idir[iar][1]][1]] == s[1]
+       || pt->v[MMG_idir[MMG_idir[iar][1]][0]] == s[1])
+         a0 = MMG_idir[iar][1];
+       else {
+         assert(pt->v[MMG_idir[MMG_idir[iar][1]][1]] == s[2]
+        	|| pt->v[MMG_idir[MMG_idir[iar][1]][0]] == s[2]);
+         a2 = MMG_idir[iar][1];
+       }	   
+     } else {
+       a1 = MMG_idir[iar][1];
+     }     
+  }
+
+ if(pt->v[MMG_idir[n2][0]] == v) {
+    if(pt->v[MMG_idir[n2][1]] == s[0]
+       || pt->v[MMG_idir[n2][2]] == s[0]) {
+       if(pt->v[MMG_idir[n2][1]] == s[1]
+       || pt->v[MMG_idir[n2][2]] == s[1])
+         a0 = n2;
+       else {
+         assert(pt->v[MMG_idir[n2][1]] == s[2]
+        	|| pt->v[MMG_idir[n2][2]] == s[2]);
+         a2 = n2;
+       }	   
+     } else {
+       a1 = n2;
+     }   
+  } else if(pt->v[MMG_idir[n2][1]] == v){
+    if(pt->v[MMG_idir[n2][0]] == s[0]
+       || pt->v[MMG_idir[n2][2]] == s[0]) {
+       if(pt->v[MMG_idir[n2][0]] == s[1]
+       || pt->v[MMG_idir[n2][2]] == s[1])
+         a0 = n2;
+       else {
+         assert(pt->v[MMG_idir[n2][0]] == s[2]
+        	|| pt->v[MMG_idir[n2][2]] == s[2]);
+         a2 = n2;
+       }	   
+     } else {
+       a1 = n2;
+     }   
+  } else {
+    assert(pt->v[MMG_idir[n2][2]] == v);
+    if(pt->v[MMG_idir[MMG_idir[iar][2]][1]] == s[0]
+       || pt->v[MMG_idir[MMG_idir[iar][2]][0]] == s[0]) {
+       if(pt->v[MMG_idir[MMG_idir[iar][2]][1]] == s[1]
+       || pt->v[MMG_idir[MMG_idir[iar][2]][0]] == s[1])
+         a0 = MMG_idir[iar][2];
+       else {
+         assert(pt->v[MMG_idir[MMG_idir[iar][2]][1]] == s[2]
+        	|| pt->v[MMG_idir[MMG_idir[iar][2]][0]] == s[2]);
+         a2 = MMG_idir[iar][2];
+       }	   
+     } else {
+       a1 = MMG_idir[iar][2];
+     }     
+  }
+
+  adj0 = MMG_idir[voy_a][0];
+  adj1 = MMG_idir[voy_a][1];
+  adj2 = MMG_idir[voy_a][2];
+
+  if(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][0]] == v_a) {
+    if(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][1]] == s[0]
+       || pt_a->v[MMG_idir[MMG_idir[voy_a][0]][2]] == s[0]) {
+       if(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][1]] == s[1]
+       || pt_a->v[MMG_idir[MMG_idir[voy_a][0]][2]] == s[1])
+         adj0 = MMG_idir[voy_a][0];
+       else {
+         assert(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][1]] == s[2]
+        	|| pt_a->v[MMG_idir[MMG_idir[voy_a][0]][2]] == s[2]);
+         adj2 = MMG_idir[voy_a][0];
+       }	   
+     } else {
+       adj1 = MMG_idir[voy_a][0];
+     }   
+  } else if(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][1]] == v_a){
+    if(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][0]] == s[0]
+       || pt_a->v[MMG_idir[MMG_idir[voy_a][0]][2]] == s[0]) {
+       if(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][0]] == s[1]
+       || pt_a->v[MMG_idir[MMG_idir[voy_a][0]][2]] == s[1])
+         adj0 = MMG_idir[voy_a][0];
+       else {
+         assert(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][0]] == s[2]
+        	|| pt_a->v[MMG_idir[MMG_idir[voy_a][0]][2]] == s[2]);
+         adj2 = MMG_idir[voy_a][0];
+       }	   
+     } else {
+       adj1 = MMG_idir[voy_a][0];
+     }   
+  } else {
+    assert(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][2]] == v_a);
+    if(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][1]] == s[0]
+       || pt_a->v[MMG_idir[MMG_idir[voy_a][0]][0]] == s[0]) {
+       if(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][1]] == s[1]
+       || pt_a->v[MMG_idir[MMG_idir[voy_a][0]][0]] == s[1])
+         adj0 = MMG_idir[voy_a][0];
+       else {
+         assert(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][1]] == s[2]
+        	|| pt_a->v[MMG_idir[MMG_idir[voy_a][0]][0]] == s[2]);
+         adj2 = MMG_idir[voy_a][0];
+       }	   
+     } else {
+       adj1 = MMG_idir[voy_a][0];
+     }     
+  }
+
+  if(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][0]] == v_a) {
+    if(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][1]] == s[0]
+       || pt_a->v[MMG_idir[MMG_idir[voy_a][1]][2]] == s[0]) {
+       if(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][1]] == s[1]
+       || pt_a->v[MMG_idir[MMG_idir[voy_a][1]][2]] == s[1])
+         adj0 = MMG_idir[voy_a][1];
+       else {
+         assert(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][1]] == s[2]
+        	|| pt_a->v[MMG_idir[MMG_idir[voy_a][1]][2]] == s[2]);
+         adj2 = MMG_idir[voy_a][1];
+       }	   
+     } else {
+       adj1 = MMG_idir[voy_a][1];
+     }   
+  } else if(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][1]] == v_a){
+    if(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][0]] == s[0]
+       || pt_a->v[MMG_idir[MMG_idir[voy_a][1]][2]] == s[0]) {
+       if(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][0]] == s[1]
+       || pt_a->v[MMG_idir[MMG_idir[voy_a][1]][2]] == s[1])
+         adj0 = MMG_idir[voy_a][1];
+       else {
+         assert(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][0]] == s[2]
+        	|| pt_a->v[MMG_idir[MMG_idir[voy_a][1]][2]] == s[2]);
+         adj2 = MMG_idir[voy_a][1];
+       }	   
+     } else {
+       adj1 = MMG_idir[voy_a][1];
+     }   
+  } else {
+    assert(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][2]] == v_a);
+    if(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][1]] == s[0]
+       || pt_a->v[MMG_idir[MMG_idir[voy_a][1]][0]] == s[0]) {
+       if(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][1]] == s[1]
+       || pt_a->v[MMG_idir[MMG_idir[voy_a][1]][0]] == s[1])
+         adj0 = MMG_idir[voy_a][1];
+       else {
+         assert(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][1]] == s[2]
+        	|| pt_a->v[MMG_idir[MMG_idir[voy_a][1]][0]] == s[2]);
+         adj2 = MMG_idir[voy_a][1];
+       }	   
+     } else {
+       adj1 = MMG_idir[voy_a][1];
+     }     
+  }
+
+ if(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][0]] == v_a) {
+    if(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][1]] == s[0]
+       || pt_a->v[MMG_idir[MMG_idir[voy_a][2]][2]] == s[0]) {
+       if(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][1]] == s[1]
+       || pt_a->v[MMG_idir[MMG_idir[voy_a][2]][2]] == s[1])
+         adj0 = MMG_idir[voy_a][2];
+       else {
+         assert(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][1]] == s[2]
+        	|| pt_a->v[MMG_idir[MMG_idir[voy_a][2]][2]] == s[2]);
+         adj2 = MMG_idir[voy_a][2];
+       }	   
+     } else {
+       adj1 = MMG_idir[voy_a][2];
+     }   
+  } else if(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][1]] == v_a){
+    if(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][0]] == s[0]
+       || pt_a->v[MMG_idir[MMG_idir[voy_a][2]][2]] == s[0]) {
+       if(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][0]] == s[1]
+       || pt_a->v[MMG_idir[MMG_idir[voy_a][2]][2]] == s[1])
+         adj0 = MMG_idir[voy_a][2];
+       else {
+         assert(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][0]] == s[2]
+        	|| pt_a->v[MMG_idir[MMG_idir[voy_a][2]][2]] == s[2]);
+         adj2 = MMG_idir[voy_a][2];
+       }	   
+     } else {
+       adj1 = MMG_idir[voy_a][2];
+     }   
+  } else {
+    assert(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][2]] == v_a);
+    if(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][1]] == s[0]
+       || pt_a->v[MMG_idir[MMG_idir[voy_a][2]][0]] == s[0]) {
+       if(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][1]] == s[1]
+       || pt_a->v[MMG_idir[MMG_idir[voy_a][2]][0]] == s[1])
+         adj0 = MMG_idir[voy_a][2];
+       else {
+         assert(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][1]] == s[2]
+        	|| pt_a->v[MMG_idir[MMG_idir[voy_a][2]][0]] == s[2]);
+         adj2 = MMG_idir[voy_a][2];
+       }	   
+     } else {
+       adj1 = MMG_idir[voy_a][2];
+     }     
+  }
+  
+  iadr = 4*(jel-1) + 1;
+  adja1 = &mesh->adja[iadr];
+  adja1[1] = adja[a0];
+  adja1[0] = adja_a[adj0];
+  adja1[2] = 4*kel + 3;
+  adja1[3] = 4*lel + 2;   
+	pt1->bdryref[0] = pt_a->bdryref[adj0];
+	pt1->bdryref[1] = pt->bdryref[a0];
+	pt1->bdryref[2] = -1;
+	pt1->bdryref[3] = -1;
+	
+  
+  
+  if ((adja[a0]>>2)) {
+    iadr = 4*((adja[a0]>>2)-1) + 1;
+    adja1 = &mesh->adja[iadr];
+    adja1[adja[a0]%4] = 4*jel + 1;
+  }
+  
+  if (adja_a[adj0]>>2) {
+    iadr = 4*((adja_a[adj0]>>2)-1) + 1;
+    adja1 = &mesh->adja[iadr];
+    adja1[adja_a[adj0]%4] = 4*jel ;
+  }
+  
+  iadr = 4*(kel-1) + 1;
+  adja1 = &mesh->adja[iadr];
+  adja1[1] = adja[a1];
+  adja1[0] = adja_a[adj1];
+  adja1[2] = 4*lel + 3;
+  adja1[3] = 4*jel + 2;
+	pt2->bdryref[0] = pt_a->bdryref[adj1];
+	pt2->bdryref[1] = pt->bdryref[a1];
+	pt2->bdryref[2] = -1;
+	pt2->bdryref[3] = -1;
+  
+  if ((adja[a1]>>2)) {
+    iadr = 4*((adja[a1]>>2)-1) + 1;
+    adja1 = &mesh->adja[iadr];
+    adja1[adja[a1]%4] = 4*kel + 1; 
+  }
+    
+  if ((adja_a[adj1]>>2)) {
+    iadr = 4*((adja_a[adj1]>>2)-1) + 1;
+    adja1 = &mesh->adja[iadr];
+    adja1[adja_a[adj1]%4] = 4*kel ; 
+  }
+    
+  iadr = 4*(lel-1) + 1;
+  adja1 = &mesh->adja[iadr];
+  adja1[1] = adja[a2];
+  adja1[0] = adja_a[adj2];
+  adja1[2] = 4*jel + 3;
+  adja1[3] = 4*kel + 2;
+	pt3->bdryref[0] = pt_a->bdryref[adj2];
+	pt3->bdryref[1] = pt->bdryref[a2];
+	pt3->bdryref[2] = -1;
+	pt3->bdryref[3] = -1;
+  
+  if ((adja[a2]>>2)) {
+    iadr = 4*((adja[a2]>>2)-1) + 1;
+    adja1 = &mesh->adja[iadr];
+    adja1[adja[a2]%4] = 4*lel + 1; 
+  }
+   
+  if ((adja_a[adj2]>>2)) {
+    iadr = 4*((adja_a[adj2]>>2)-1) + 1;
+    adja1 = &mesh->adja[iadr];
+    adja1[adja_a[adj2]%4] = 4*lel; 
+  }
+    
+  /*del*/
+  MMG_delElt(mesh,iel);
+  MMG_delElt(mesh,i_a);
+  MMG_kiudel(q,iel);
+  MMG_kiudel(q,i_a);
+
+
+  return(1);
+}
+
+
+/* remove edge AB */
+int MMG_swap32(pMesh mesh,pSol sol,pList list) {
+  pTetra    pt,pt1,pt2,pt0;   
+	Hedge			hed;
+  int      *adja,k,i,jel,kel,adj,iadr,ia,ib,s1,s2,s3;
+  int       old,iarold,kk,adj_a,adj_b,iel,iar,ref,ref_a,ref_b;   
+  short     voy,voy_a,voy_b;
+  
+  if ( !MMG_zaldy4(&hed,10) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP32 IGNORED\n"); 
+  }   
+
+  /* face s1 s2 s3 */
+  iel  = list->tetra[1] / 6;
+  iar  = list->tetra[1] % 6;
+  pt   = &mesh->tetra[iel];
+  ref  = pt->ref;
+  
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  s1  = pt->v[ MMG_isar[iar][0] ];
+  s2  = pt->v[ MMG_isar[iar][1] ];
+	for(i=0 ; i<6 ; i++) {
+		//printf("1. insere %d %d -- %d\n",pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][0];
+  adj  = adja[k] >> 2;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s3   = pt1->v[voy];
+
+  /* create 2 new tetra */ 
+  /*edge : ias1 -- ias2 -- ias3 -- s1s2 -- s1s3 -- s2s3*/
+  jel = MMG_newElt(mesh);  
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s1;
+  pt1->v[2] = s2;
+  pt1->v[3] = s3;
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  /* 2nd elt */
+  /*edge : ibs2 -- ibs1 -- ibs3 -- s2s1 -- s2s3 -- s2s3*/
+  kel = MMG_newElt(mesh);
+  pt2 = &mesh->tetra[kel];
+  pt2->v[0] = ib;
+  pt2->v[1] = s2;
+  pt2->v[2] = s1;
+  pt2->v[3] = s3;
+  pt2->qual = list->qual[2];
+  pt2->flag = mesh->flag;
+  pt2->ref  = ref;
+
+  /* external faces */
+  for (k=2; k<=3; k++) {
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0    = &mesh->tetra[old]; 
+		for(i=0 ; i<6 ; i++) {    
+			//printf("2. insere %d %d -- %d\n",pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    iarold = list->tetra[k] % 6;
+    kk     = MMG_iare[iarold][1];
+    if( pt0->v[kk] == ib ) {
+      adj_a  = adja[kk] >> 2;
+      voy_a = adja[kk] % 4;
+      ref_a = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] >> 2;
+      voy_b  = adja[kk] % 4;
+      ref_b = pt0->bdryref[kk]; 
+    } 
+    else /*if ( pt0->v[MMG_iare[iarold][0]] == ib ) */{
+      adj_b  = adja[kk] >> 2;
+      voy_b  = adja[kk] % 4;   
+      ref_b  = pt0->bdryref[kk];  
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] >> 2;
+      voy_a  = adja[kk] % 4;  
+      ref_a  = pt0->bdryref[kk];  
+    }
+
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    if ( old == (adja[MMG_isar[iar][0]]>>2) ) {  
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_a*4 + voy_a;
+      pt1->bdryref[1] = ref_a;   
+			
+      if (adj_a) {        
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 1;
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_b*4 + voy_b;
+      pt2->bdryref[2] = ref_b;
+      if (adj_b) {        
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 2; 
+      }
+    } 
+    else if ( old == (adja[MMG_isar[iar][1]]>>2) ) {
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      pt1->bdryref[2] = ref_a;  
+        
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 2;
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_b*4 + voy_b;
+      pt2->bdryref[1] = ref_b; 
+      
+      if (adj_b) {        
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 1;
+      }
+    }
+ 
+  }
+
+  /* du tetra 1 de la liste pour ia */
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] >> 2;
+  voy  = adja[k] % 4;
+   
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  pt1->bdryref[3] = pt->bdryref[k];
+    
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;  
+  }
+
+  /* du tetra 1 de la liste pour ib */
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] >> 2;
+  voy  = adja[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  pt2->bdryref[3] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 3; 
+  }
+
+  /* internal face */
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  
+	for(i=0 ; i<6 ; i++) {
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); 
+		//printf("pas trouve %d %d\n",pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]]);
+		assert(pt1->bdryinfo[i]!=1);
+		pt2->bdryinfo[i] = MMG_edgePut(&hed,pt2->v[MMG_iare[i][0]],pt2->v[MMG_iare[i][1]],1);
+		assert(pt2->bdryinfo[i]!=1);
+	}
+
+  /* remove 3 old tetra */
+  for (k=1; k<=3; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = 0;
+  
+	M_free(hed.item);
+  return(2);
+}
+
diff --git a/contrib/mmg3d/build/sources/swap44.c b/contrib/mmg3d/build/sources/swap44.c
new file mode 100644
index 0000000000000000000000000000000000000000..b8d645576d6e15b0f007f976bd52fe1a8644304e
--- /dev/null
+++ b/contrib/mmg3d/build/sources/swap44.c
@@ -0,0 +1,608 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+/* remove edge iar of iel */
+int MMG_swap44_1(pMesh mesh,pSol sol,pList list) {
+  pTetra    pt,pt0,pt1;
+	Hedge			hed;
+  int      *adja,i,k,jel,kel,lel,mel,adj,base,iadr,ia,ib,s1,s2,s3,s4;
+  int       old,iarold,kk,adj_a,adj_b,iel,iar,ref,ref_a,ref_b;
+  short     voy,voy_a,voy_b;
+
+  if ( !MMG_zaldy4(&hed,13) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP441 IGNORED\n"); 
+  }   
+
+  /* face s1 s2 s3 */
+  iel  = list->tetra[1] / 6;
+  iar  = list->tetra[1] % 6;
+  base = mesh->mark;
+  pt   = &mesh->tetra[iel];
+  ref  = pt->ref;
+  
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  s1  = pt->v[ MMG_isar[iar][0] ];
+  s2  = pt->v[ MMG_isar[iar][1] ];
+  for(i=0 ; i<6 ; i++) {
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s3   = pt1->v[voy];
+
+  k    = MMG_isar[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s4   = pt1->v[voy];
+ 
+  /* create 4 new tetra */
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s1;
+  pt1->v[2] = s2;
+  pt1->v[3] = s3;
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  /* 2nd elt */
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s1;
+  pt1->v[2] = s3;
+  pt1->v[3] = s2;
+  pt1->qual = list->qual[2];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s1;
+  pt1->v[2] = s3;
+  pt1->v[3] = s4;
+  pt1->qual = list->qual[3];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  /* 2nd elt */
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s1;
+  pt1->v[2] = s4;
+  pt1->v[3] = s3;
+  pt1->qual = list->qual[4];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  /* external faces*/
+  /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k];
+
+  if (adj) {    
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k];
+    
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    if(iadr<0) {puts("aaaaaaaaaaaa");exit(0);}
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;  
+  }
+  
+  for(k=2 ; k<=4 ; k++) {
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0 = &mesh->tetra[old];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4; 
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk]; 
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+  
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    if(old==(adja[MMG_isar[iar][0]]/4)) { 
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_a*4 + voy_a;
+      mesh->tetra[jel].bdryref[1] = ref_a;
+        
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 1;
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[1] = ref_b;
+        
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 1; 
+      }
+      
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){ 
+      iadr = (lel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[lel].bdryref[2] = ref_a;
+        
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = lel*4 + 2; 
+      }
+      
+      iadr = (mel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[mel].bdryref[3] = ref_b;
+        
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = mel*4 + 3;
+      }
+    } else {
+      iadr = (lel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_a*4 + voy_a;
+      mesh->tetra[lel].bdryref[1] = ref_a;
+        
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = lel*4 + 1;
+      }
+      
+      iadr = (mel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_b*4 + voy_b;
+      mesh->tetra[mel].bdryref[1] = ref_b;
+        
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = mel*4 + 1; 
+      }
+    }
+  
+  }
+  
+	/*bdryinfo*/           
+	pt1 = &mesh->tetra[jel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); 
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[kel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[lel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[mel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	
+  /* internal face */
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[3] = jel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[2] = kel*4 + 3;
+  
+  /* remove 4 old tetra */
+  for (k=1; k<=4; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+    
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = 0;
+  
+	M_free(hed.item);
+  return(4);
+}
+
+
+/* remove edge iar of iel */
+int MMG_swap44_2(pMesh mesh,pSol sol,pList list) {
+  pTetra    pt,pt0,pt1;
+	Hedge			hed;
+  int      *adja,i,k,jel,kel,lel,mel,adj,base,iadr,ia,ib,s1,s2,s3,s4;
+  int       old,iarold,kk,adj_a,adj_b,iel,iar,ref,ref_a,ref_b;
+  short     voy,voy_a,voy_b;
+
+  if ( !MMG_zaldy4(&hed,13) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP442 IGNORED\n"); 
+  }   
+
+  /* face s1 s2 s3 */
+  iel  = list->tetra[1] / 6;
+  iar  = list->tetra[1] % 6;
+  base = mesh->mark;
+  pt   = &mesh->tetra[iel];
+  ref  = pt->ref;
+  
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  s1  = pt->v[ MMG_isar[iar][0] ];
+  s2  = pt->v[ MMG_isar[iar][1] ];
+	for(i=0 ; i<6 ; i++) { 
+		//printf("on insere %d %d -- %d\n",pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s3   = pt1->v[voy];
+
+  k    = MMG_isar[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s4   = pt1->v[voy];
+ 
+  /* create 4 new tetra */
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s1;
+  pt1->v[2] = s2;
+  pt1->v[3] = s4;
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  /* 2nd elt */
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s1;
+  pt1->v[2] = s4;
+  pt1->v[3] = s2;
+  pt1->qual = list->qual[2];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s2;
+  pt1->v[2] = s3;
+  pt1->v[3] = s4;
+  pt1->qual = list->qual[3];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  /* 2nd elt */
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s2;
+  pt1->v[2] = s4;
+  pt1->v[3] = s3;
+  pt1->qual = list->qual[4];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+ 
+  /* external faces*/
+  /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k];
+    
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;  
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k];
+    
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  
+  for(k=2 ; k<=4 ; k++) {
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0 = &mesh->tetra[old];
+		for(i=0 ; i<6 ; i++) {
+			//printf("2. on insere %d %d -- %d\n",pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4; 
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk]; 
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+  
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    if(old==(adja[MMG_isar[iar][0]]/4)) {  
+      iadr = (lel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_a*4 + voy_a;
+      mesh->tetra[lel].bdryref[3]  = ref_a;
+        
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = lel*4 + 3; 
+      }
+       
+      iadr = (mel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_b*4 + voy_b;
+      mesh->tetra[mel].bdryref[2]  = ref_b;
+        
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = mel*4 + 2; 
+      }
+      
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[jel].bdryref[2]  = ref_a;
+        
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 2; 
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[3]  = ref_b;
+        
+      if (adj_b){
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 3;
+      }
+    } else {
+      iadr = (lel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_a*4 + voy_a;
+      mesh->tetra[lel].bdryref[1]  = ref_a;
+        
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = lel*4 + 1; 
+      }
+      
+      iadr = (mel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_b*4 + voy_b;
+      mesh->tetra[mel].bdryref[1]  = ref_b;
+        
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = mel*4 + 1;
+      }
+    }
+  
+  }
+  /*bdryinfo*/           
+	pt1 = &mesh->tetra[jel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);   
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[kel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[lel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[mel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	
+  /* internal face */
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[1] = lel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[1] = mel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = jel*4 + 1;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = kel*4 + 1;
+  
+  /* remove 4 old tetra */
+  for (k=1; k<=4; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+    
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = 0;
+  
+	M_free(hed.item);
+	
+  return(4);
+}
diff --git a/contrib/mmg3d/build/sources/swap56.c b/contrib/mmg3d/build/sources/swap56.c
new file mode 100644
index 0000000000000000000000000000000000000000..a116080e05e1a1c597cfd9db7b44ba9ce5288be8
--- /dev/null
+++ b/contrib/mmg3d/build/sources/swap56.c
@@ -0,0 +1,1956 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+int MMG_swap56_1(pMesh mesh,pSol sol,pList list) {
+  pTetra  pt,pt1,pt0;
+	Hedge			hed;
+  int     i,ia,ib,s1,s2,s3,s4,s5;
+  int     jel,kel,lel,mel,nel,pel;
+  int     iadr,iarold,*adja,k,adj,old,kk,adj_a,adj_b,j,iel,iar,ref,ref_a,ref_b;
+  short   voy,voy_a,voy_b; 
+
+  if ( !MMG_zaldy4(&hed,17) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP442 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref;
+  
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  s1  = pt->v[ MMG_isar[iar][0] ];
+  s2  = pt->v[ MMG_isar[iar][1] ]; 
+	for(i=0 ; i<6 ; i++) { 
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s3   = pt1->v[voy];
+
+  iadr = (adj-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  if(pt1->v[MMG_idir[voy][0]]==s2) {
+     k = MMG_idir[voy][0];
+  } else if(pt1->v[MMG_idir[voy][1]]==s2) {
+     k = MMG_idir[voy][1];
+  } else if(pt1->v[MMG_idir[voy][2]]==s2) {
+     k = MMG_idir[voy][2];
+  } else {
+    puts("point non existant");
+    exit(0);
+  }   
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s4   = pt1->v[voy];
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s5   = pt1->v[voy];
+  
+  /* create 6 new tetra */
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s1;
+  pt1->v[2] = s2;
+  pt1->v[3] = s3;
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s1;
+  pt1->v[2] = s3;
+  pt1->v[3] = s2;
+  pt1->qual = list->qual[2];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+     
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s1;
+  pt1->v[2] = s3;
+  pt1->v[3] = s4;
+  pt1->qual = list->qual[3];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s1;
+  pt1->v[2] = s4;
+  pt1->v[3] = s3;
+  pt1->qual = list->qual[4];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+ 
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s1;
+  pt1->v[2] = s4;
+  pt1->v[3] = s5;
+  pt1->qual = list->qual[5];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+    
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s1;
+  pt1->v[2] = s5;
+  pt1->v[3] = s4;
+  pt1->qual = list->qual[6];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  /*external faces*/
+  /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3]  = pt->bdryref[k];
+  
+  if (adj)  {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3; 
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2]  = pt->bdryref[k];
+
+  if (adj)  {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  
+  for(k=2 ; k<=5 ; k++) {
+    
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0 = &mesh->tetra[old];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4; 
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk]; 
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+   
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    if(old==(adja[MMG_isar[iar][0]]/4)) {
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_a*4 + voy_a;
+      mesh->tetra[jel].bdryref[1] = ref_a;
+      
+      if (adj_a) { 
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 1; 
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[1] = ref_b;
+      
+      if (adj_b){
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 1; 
+      }
+      
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){
+      iadr = (nel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[nel].bdryref[2] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = nel*4 + 2;
+      }
+      
+      iadr = (pel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[pel].bdryref[3] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = pel*4 + 3;
+      }
+    } else {
+       /*old n'est pas un voisin de iel*/
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      j    = MMG_isar[iar][0];
+      adj  = adja[j] / 4;
+      voy  = adja[j] % 4;
+      pt1  = &mesh->tetra[adj];
+    
+     if(pt1->v[MMG_idir[voy][0]]==s2) {
+         j = MMG_idir[voy][0];
+      } else if(pt1->v[MMG_idir[voy][1]]==s2) {
+         j = MMG_idir[voy][1];
+      } else if(pt1->v[MMG_idir[voy][2]]==s2) {
+         j = MMG_idir[voy][2];
+      }
+
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      if(old==adja[j] / 4) {
+         
+         iadr = (lel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[lel].bdryref[1] = ref_a;
+         
+         if (adj_a){
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = lel*4 + 1;
+         }
+      
+         iadr = (mel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[mel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = mel*4 + 1;
+         }
+      } else {
+         iadr = (nel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[nel].bdryref[1] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = nel*4 + 1;
+         }
+      
+         iadr = (pel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[pel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = pel*4 + 1;
+         }
+      }
+    }
+  
+  }
+  
+   /*internal faces*/
+   iadr = (jel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = kel*4 + 0;
+   adja[2] = lel*4 + 3;
+   iadr = (kel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = jel*4 + 0;
+   adja[3] = mel*4 + 2;
+  
+   iadr = (lel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = mel*4 + 0;
+   adja[3] = jel*4 + 2;
+   adja[2] = nel*4 + 3;
+  
+   iadr = (mel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = lel*4 + 0;
+   adja[2] = kel*4 + 3;
+   adja[3] = pel*4 + 2;
+  
+   iadr = (nel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = pel*4 + 0;
+   adja[3] = lel*4 + 2;
+   
+   iadr = (pel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = nel*4 + 0;
+   adja[2] = mel*4 + 3;
+  
+  /*bdryinfo*/           
+	pt1 = &mesh->tetra[jel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);   
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[kel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[lel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[mel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[nel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[pel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+
+
+  /* remove 5 old tetra */
+  for (k=1; k<=5; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = pel;
+  list->tetra[7] = 0;
+	M_free(hed.item);
+  return(6);
+}
+
+
+int MMG_swap56_2(pMesh mesh,pSol sol,pList list) {
+   pTetra pt,pt1,pt0;
+	 Hedge			hed;
+   int i,ia,ib,s1,s2,s3,s4,s5;
+   int jel,kel,lel,mel,nel,pel;
+   int iadr,iarold,*adja,k,adj,old,kk,adj_a,adj_b,j,iel,iar,ref,ref_a,ref_b;
+   short voy,voy_a,voy_b;
+
+  if ( !MMG_zaldy4(&hed,17) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP442 IGNORED\n"); 
+  }   
+   
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref;
+  
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  s1  = pt->v[ MMG_isar[iar][0] ];
+  s2  = pt->v[ MMG_isar[iar][1] ]; 
+	for(i=0 ; i<6 ; i++) { 
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+  
+   iadr = (iel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   k    = MMG_isar[iar][0];
+   adj  = adja[k] / 4;
+   voy  = adja[k] % 4;
+   pt1  = &mesh->tetra[adj];
+   s3   = pt1->v[voy];
+
+   iadr = (adj-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   if(pt1->v[MMG_idir[voy][0]]==s2) {
+      k = MMG_idir[voy][0];
+   } else if(pt1->v[MMG_idir[voy][1]]==s2) {
+      k = MMG_idir[voy][1];
+   } else if(pt1->v[MMG_idir[voy][2]]==s2) {
+      k = MMG_idir[voy][2];
+   } else {
+     puts("point non existant");
+     exit(0);
+   }   
+   adj  = adja[k] / 4;
+   voy  = adja[k] % 4;
+   pt1  = &mesh->tetra[adj];
+   s4   = pt1->v[voy];
+  
+   iadr = (iel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   k    = MMG_isar[iar][1];
+   adj  = adja[k] / 4;
+   voy  = adja[k] % 4;
+   pt1  = &mesh->tetra[adj];
+   s5   = pt1->v[voy];
+
+   /* create 6 new tetra */
+   jel = MMG_newElt(mesh);
+   pt1 = &mesh->tetra[jel];
+   pt1->v[0] = ia;
+   pt1->v[1] = s1;
+   pt1->v[2] = s2;
+   pt1->v[3] = s5;
+   pt1->qual = list->qual[1];
+   pt1->flag = mesh->flag;
+   pt1->ref  = ref;
+  
+   kel = MMG_newElt(mesh);
+   pt1 = &mesh->tetra[kel];
+   pt1->v[0] = ib;
+   pt1->v[1] = s1;
+   pt1->v[2] = s5;
+   pt1->v[3] = s2;
+   pt1->qual = list->qual[2];
+   pt1->flag = mesh->flag;
+   pt1->ref  = ref;
+      
+   lel = MMG_newElt(mesh);
+   pt1 = &mesh->tetra[lel];
+   pt1->v[0] = ia;
+   pt1->v[1] = s2;
+   pt1->v[2] = s3;
+   pt1->v[3] = s4;
+   pt1->qual = list->qual[3];
+   pt1->flag = mesh->flag;
+   pt1->ref  = ref;
+
+   mel = MMG_newElt(mesh);
+   pt1 = &mesh->tetra[mel];
+   pt1->v[0] = ib;
+   pt1->v[1] = s2;
+   pt1->v[2] = s4;
+   pt1->v[3] = s3;
+   pt1->qual = list->qual[4];
+   pt1->flag = mesh->flag;
+   pt1->ref  = ref;
+
+   nel = MMG_newElt(mesh);
+   pt1 = &mesh->tetra[nel];
+   pt1->v[0] = ia;
+   pt1->v[1] = s2;
+   pt1->v[2] = s4;
+   pt1->v[3] = s5;
+   pt1->qual = list->qual[5];
+   pt1->flag = mesh->flag;
+   pt1->ref  = ref;
+
+   pel = MMG_newElt(mesh);
+   pt1 = &mesh->tetra[pel];
+   pt1->v[0] = ib;
+   pt1->v[1] = s2;
+   pt1->v[2] = s5;
+   pt1->v[3] = s4;
+   pt1->qual = list->qual[6];
+   pt1->flag = mesh->flag; 
+   pt1->ref  = ref;
+
+  /*external faces*/
+     /*tetra iel*/
+   iadr = (iel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   k    = MMG_iare[iar][1];
+   adj  = adja[k] / 4;
+   voy  = adja[k] % 4;
+  
+   iadr = (jel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[3] = adj*4 + voy;
+   mesh->tetra[jel].bdryref[3] = pt->bdryref[k];
+   
+   if (adj) {
+     iadr = (adj-1)*4 + 1;
+     adja = &mesh->adja[iadr];
+     adja[voy] = jel*4 + 3; 
+   }
+  
+   iadr = (iel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   k    = MMG_iare[iar][0];
+   adj  = adja[k] / 4;
+   voy  = adja[k] % 4;
+  
+   iadr = (kel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[2] = adj*4 + voy;
+   mesh->tetra[kel].bdryref[2] = pt->bdryref[k];  
+   
+   if (adj) {
+     iadr = (adj-1)*4 + 1;
+     adja = &mesh->adja[iadr];
+     adja[voy] = kel*4 + 2;  
+   }
+  
+   for(k=2 ; k<=5 ; k++) {
+    
+     old  = list->tetra[k] / 6;
+     iadr = (old-1)*4 + 1;
+     adja = &mesh->adja[iadr];
+
+     pt0 = &mesh->tetra[old];
+		  for(i=0 ; i<6 ; i++) {
+		  	MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		  }
+     iarold = list->tetra[k] % 6;
+     kk    = MMG_iare[iarold][1];
+     if(pt0->v[kk]==ib) {
+       adj_a  = adja[kk] / 4;
+       voy_a  = adja[kk] % 4; 
+       ref_a  = pt0->bdryref[kk];
+       kk    = MMG_iare[iarold][0];
+       adj_b  = adja[kk] / 4;
+       voy_b  = adja[kk] % 4;
+       ref_b  = pt0->bdryref[kk];
+     } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+       adj_b  = adja[kk] / 4;
+       voy_b  = adja[kk] % 4;
+       ref_b  = pt0->bdryref[kk]; 
+       kk    = MMG_iare[iarold][0];
+       adj_a  = adja[kk] / 4;
+       voy_a  = adja[kk] % 4;
+       ref_a  = pt0->bdryref[kk];
+     } 
+   
+     iadr = (iel-1)*4 + 1;
+     adja = &mesh->adja[iadr];
+     if(old==(adja[MMG_isar[iar][0]]/4)) {
+       iadr = (lel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[3] = adj_a*4 + voy_a;
+       mesh->tetra[lel].bdryref[3] = ref_a;
+       
+       if (adj_a) {
+         iadr = (adj_a-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_a] = lel*4 + 3; 
+       }
+      
+       iadr = (mel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[2] = adj_b*4 + voy_b;
+       mesh->tetra[mel].bdryref[2] = ref_b;
+       
+       if (adj_b) {
+         iadr = (adj_b-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_b] = mel*4 + 2;
+       }
+      
+     } else if(old==(adja[MMG_isar[iar][1]]/4)){
+       iadr = (jel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[2] = adj_a*4 + voy_a; 
+       mesh->tetra[jel].bdryref[2] = ref_a;
+       
+       if (adj_a) {
+         iadr = (adj_a-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_a] = jel*4 + 2;
+       }
+      
+       iadr = (kel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[3] = adj_b*4 + voy_b;
+       mesh->tetra[kel].bdryref[3] = ref_b;
+       
+       if (adj_b) {
+         iadr = (adj_b-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_b] = kel*4 + 3;
+       }
+     } else {
+
+     /*old n'est pas un voisin de iel*/
+       iadr = (iel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       j    = MMG_isar[iar][0];
+       adj  = adja[j] / 4;
+       voy  = adja[j] % 4;
+       pt1  = &mesh->tetra[adj];
+    
+      if(pt1->v[MMG_idir[voy][0]]==s2) {
+          j = MMG_idir[voy][0];
+      } else if(pt1->v[MMG_idir[voy][1]]==s2) {
+          j = MMG_idir[voy][1];
+      } else if(pt1->v[MMG_idir[voy][2]]==s2) {
+          j = MMG_idir[voy][2];
+      }
+
+       iadr = (adj-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       if(old==adja[j] / 4) {
+         
+         iadr = (lel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a; 
+         mesh->tetra[lel].bdryref[1] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = lel*4 + 1;
+         }
+      
+         iadr = (mel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[mel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = mel*4 + 1;
+         }
+       } else {
+         iadr = (nel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[nel].bdryref[1] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = nel*4 + 1; 
+         }
+      
+         iadr = (pel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[pel].bdryref[1] = ref_b;
+        
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = pel*4 + 1;
+         }
+       }
+    }
+  
+  }
+  
+   /*internal faces*/
+   iadr = (jel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = kel*4 + 0;
+   adja[1] = nel*4 + 2;
+
+   iadr = (kel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = jel*4 + 0;
+   adja[1] = pel*4 + 3;
+ 
+   iadr = (lel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = mel*4 + 0;
+   adja[2] = nel*4 + 3;
+   
+   
+   iadr = (mel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = lel*4 + 0;
+   adja[3] = pel*4 + 2;
+  
+   iadr = (nel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = pel*4 + 0;
+   adja[2] = jel*4 + 1;
+   adja[3] = lel*4 + 2;
+  
+   iadr = (pel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = nel*4 + 0;
+   adja[3] = kel*4 + 1;
+   adja[2] = mel*4 + 3;
+ 
+  /*bdryinfo*/           
+	pt1 = &mesh->tetra[jel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);   
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[kel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[lel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[mel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[nel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[pel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+  /* remove 5 old tetra */
+  for (k=1; k<=5; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = pel;
+  list->tetra[7] = 0;
+	M_free(hed.item);
+
+  return(6);
+}
+
+
+int MMG_swap56_3(pMesh mesh,pSol sol,pList list) {
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int i,ia,ib,s1,s2,s3,s4,s5;
+  int jel,kel,lel,mel,nel,pel;
+  int iadr,iarold,*adja,k,adj,old,kk,adj_a,adj_b,j,iel,iar,ref,ref_a,ref_b;
+  short voy,voy_a,voy_b;
+  
+  if ( !MMG_zaldy4(&hed,17) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP442 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref;
+
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  s1  = pt->v[ MMG_isar[iar][0] ];
+  s2  = pt->v[ MMG_isar[iar][1] ]; 
+	for(i=0 ; i<6 ; i++) { 
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s3   = pt1->v[voy];
+  
+  iadr = (adj-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  if(pt1->v[MMG_idir[voy][0]]==s2) {
+     k = MMG_idir[voy][0];
+  } else if(pt1->v[MMG_idir[voy][1]]==s2) {
+     k = MMG_idir[voy][1];
+  } else if(pt1->v[MMG_idir[voy][2]]==s2) {
+     k = MMG_idir[voy][2];
+  } else {
+    puts("point non existant");
+    exit(0);
+  }   
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s4   = pt1->v[voy];
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s5   = pt1->v[voy];
+  
+  /* create 6 new tetra */
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s1;
+  pt1->v[2] = s2;
+  pt1->v[3] = s3;
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+	 
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s1;
+  pt1->v[2] = s3;
+  pt1->v[3] = s2;
+  pt1->qual = list->qual[2];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s1;
+  pt1->v[2] = s3;
+  pt1->v[3] = s5;
+  pt1->qual = list->qual[3];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s1;
+  pt1->v[2] = s5;
+  pt1->v[3] = s3;
+  pt1->qual = list->qual[4];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s3;
+  pt1->v[2] = s4;
+  pt1->v[3] = s5;
+  pt1->qual = list->qual[5];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s3;
+  pt1->v[2] = s5;
+  pt1->v[3] = s4;
+  pt1->qual = list->qual[6];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  /*external faces*/
+  /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3; 
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  
+  for(k=2 ; k<=5 ; k++) {
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+  
+    pt0 = &mesh->tetra[old];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk]; 
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+  
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    if(old==(adja[MMG_isar[iar][0]]/4)) {
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_a*4 + voy_a;
+      mesh->tetra[jel].bdryref[1] = ref_a;
+      
+      if (adj_a){
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 1; 
+      }
+     
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[1] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 1; 
+      }
+     
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){
+      iadr = (lel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[lel].bdryref[2] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = lel*4 + 2; 
+      }
+     
+      iadr = (mel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[mel].bdryref[3] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = mel*4 + 3; 
+      }
+    } else {
+  
+    /*old n'est pas un voisin de iel*/
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      j    = MMG_isar[iar][0];
+      adj  = adja[j] / 4;
+      voy  = adja[j] % 4;
+      pt1  = &mesh->tetra[adj];
+   
+     if(pt1->v[MMG_idir[voy][0]]==s2) {
+         j = MMG_idir[voy][0];
+     } else if(pt1->v[MMG_idir[voy][1]]==s2) {
+         j = MMG_idir[voy][1];
+     } else if(pt1->v[MMG_idir[voy][2]]==s2) {
+         j = MMG_idir[voy][2];
+     }
+  
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      if(old==adja[j] / 4) {
+        
+        iadr = (nel-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[3] = adj_a*4 + voy_a;
+        mesh->tetra[nel].bdryref[3] = ref_a;
+        
+        if (adj_a) {
+          iadr = (adj_a-1)*4 + 1;
+          adja = &mesh->adja[iadr];
+          adja[voy_a] = nel*4 + 3;
+        }
+     
+        iadr = (pel-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[2] = adj_b*4 + voy_b;
+        mesh->tetra[pel].bdryref[2] = ref_b;
+        
+        if (adj_b) {
+          iadr = (adj_b-1)*4 + 1;
+          adja = &mesh->adja[iadr];
+          adja[voy_b] = pel*4 + 2;
+        }
+      } else {
+        iadr = (nel-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[1] = adj_a*4 + voy_a;
+        mesh->tetra[nel].bdryref[1] = ref_a;
+        
+        if (adj_a) {
+          iadr = (adj_a-1)*4 + 1;
+          adja = &mesh->adja[iadr];
+          adja[voy_a] = nel*4 + 1; 
+        }
+     
+        iadr = (pel-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[1] = adj_b*4 + voy_b;
+        mesh->tetra[pel].bdryref[1] = ref_b;
+        
+        if (adj_b) {
+          iadr = (adj_b-1)*4 + 1;
+          adja = &mesh->adja[iadr];
+          adja[voy_b] = pel*4 + 1;  
+        }
+      }
+   }
+  
+  }
+  
+   /*internal faces*/
+   iadr = (jel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = kel*4 + 0;
+   adja[2] = lel*4 + 3;
+
+   iadr = (kel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = jel*4 + 0;
+   adja[3] = mel*4 + 2;
+  
+   iadr = (lel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = mel*4 + 0;
+   adja[3] = jel*4 + 2;
+   adja[1] = nel*4 + 2;
+   
+   iadr = (mel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = lel*4 + 0;
+   adja[2] = kel*4 + 3;
+   adja[1] = pel*4 + 3;
+   
+   iadr = (nel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = pel*4 + 0;
+   adja[2] = lel*4 + 1;
+   
+   iadr = (pel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = nel*4 + 0;
+   adja[3] = mel*4 + 1;
+
+  /*bdryinfo*/           
+	pt1 = &mesh->tetra[jel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);   
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[kel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[lel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[mel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[nel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[pel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+  
+  /* remove 5 old tetra */
+  for (k=1; k<=5; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = pel;
+  list->tetra[7] = 0;
+ 	M_free(hed.item);
+
+  return(6);
+}
+
+
+int MMG_swap56_4(pMesh mesh,pSol sol,pList list) {
+   pTetra pt,pt1,pt0;
+ 	 Hedge			hed;
+   int i,ia,ib,s1,s2,s3,s4,s5;
+   int jel,kel,lel,mel,nel,pel;
+   int iadr,iarold,*adja,k,adj,old,kk,adj_a,adj_b,j,iel,iar,ref,ref_a,ref_b;
+   short voy,voy_a,voy_b;
+  if ( !MMG_zaldy4(&hed,17) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP442 IGNORED\n"); 
+  }   
+  
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref;
+
+   ia  = pt->v[ MMG_iare[iar][0] ];
+   ib  = pt->v[ MMG_iare[iar][1] ];
+   s1  = pt->v[ MMG_isar[iar][0] ];
+   s2  = pt->v[ MMG_isar[iar][1] ]; 
+	for(i=0 ; i<6 ; i++) { 
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+  
+   iadr = (iel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   k    = MMG_isar[iar][0];
+   adj  = adja[k] / 4;
+   voy  = adja[k] % 4;
+   pt1  = &mesh->tetra[adj];
+   s3   = pt1->v[voy];
+
+   iadr = (adj-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   if(pt1->v[MMG_idir[voy][0]]==s2) {
+      k = MMG_idir[voy][0];
+   } else if(pt1->v[MMG_idir[voy][1]]==s2) {
+      k = MMG_idir[voy][1];
+   } else if(pt1->v[MMG_idir[voy][2]]==s2) {
+      k = MMG_idir[voy][2];
+   } else {
+     puts("point non existant");
+     exit(0);
+   }   
+   adj  = adja[k] / 4;
+   voy  = adja[k] % 4;
+   pt1  = &mesh->tetra[adj];
+   s4   = pt1->v[voy];
+  
+   iadr = (iel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   k    = MMG_isar[iar][1];
+   adj  = adja[k] / 4;
+   voy  = adja[k] % 4;
+   pt1  = &mesh->tetra[adj];
+   s5   = pt1->v[voy];
+
+   /* create 6 new tetra */
+   jel = MMG_newElt(mesh);
+   pt1 = &mesh->tetra[jel];
+   pt1->v[0] = ia;
+   pt1->v[1] = s1;
+   pt1->v[2] = s4;
+   pt1->v[3] = s5;
+   pt1->qual = list->qual[1];
+   pt1->flag = mesh->flag;
+   pt1->ref  = ref;
+
+   kel = MMG_newElt(mesh);
+   pt1 = &mesh->tetra[kel];
+   pt1->v[0] = ib;
+   pt1->v[1] = s1;
+   pt1->v[2] = s5;
+   pt1->v[3] = s4;
+   pt1->qual = list->qual[2];
+   pt1->flag = mesh->flag;
+   pt1->ref  = ref;
+    
+   lel = MMG_newElt(mesh);
+   pt1 = &mesh->tetra[lel];
+   pt1->v[0] = ia;
+   pt1->v[1] = s2;
+   pt1->v[2] = s3;
+   pt1->v[3] = s4;
+   pt1->qual = list->qual[3];
+   pt1->flag = mesh->flag;
+   pt1->ref  = ref;
+     
+   mel = MMG_newElt(mesh);
+   pt1 = &mesh->tetra[mel];
+   pt1->v[0] = ib;
+   pt1->v[1] = s2;
+   pt1->v[2] = s4;
+   pt1->v[3] = s3;
+   pt1->qual = list->qual[4];
+   pt1->flag = mesh->flag;
+   pt1->ref  = ref;
+  
+   nel = MMG_newElt(mesh);
+   pt1 = &mesh->tetra[nel];
+   pt1->v[0] = ia;
+   pt1->v[1] = s1;
+   pt1->v[2] = s2;
+   pt1->v[3] = s4;
+   pt1->qual = list->qual[5];
+   pt1->flag = mesh->flag;
+   pt1->ref  = ref;
+     
+   pel = MMG_newElt(mesh);
+   pt1 = &mesh->tetra[pel];
+   pt1->v[0] = ib;
+   pt1->v[1] = s1;
+   pt1->v[2] = s4;
+   pt1->v[3] = s2;
+   pt1->qual = list->qual[6];
+   pt1->flag = mesh->flag; 
+   pt1->ref  = ref;
+
+  /*external faces*/
+     /*tetra iel*/
+   iadr = (iel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   k    = MMG_iare[iar][1];
+   adj  = adja[k] / 4;
+   voy  = adja[k] % 4;
+  
+   iadr = (nel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[3] = adj*4 + voy;
+   mesh->tetra[nel].bdryref[3] = pt->bdryref[k];
+   
+   if (adj) {
+     iadr = (adj-1)*4 + 1;
+     adja = &mesh->adja[iadr];
+     adja[voy] = nel*4 + 3; 
+   }
+  
+   iadr = (iel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   k    = MMG_iare[iar][0];
+   adj  = adja[k] / 4;
+   voy  = adja[k] % 4;
+  
+   iadr = (pel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[2] = adj*4 + voy; 
+   mesh->tetra[pel].bdryref[2] = pt->bdryref[k];
+   
+   if (adj) {
+     iadr = (adj-1)*4 + 1;
+     adja = &mesh->adja[iadr];
+     adja[voy] = pel*4 + 2;
+   }
+  
+   for(k=2 ; k<=5 ; k++) {
+    
+     old  = list->tetra[k] / 6;
+     iadr = (old-1)*4 + 1;
+     adja = &mesh->adja[iadr];
+
+     pt0 = &mesh->tetra[old];
+		  for(i=0 ; i<6 ; i++) {
+		  	MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		  }
+     iarold = list->tetra[k] % 6;
+     kk    = MMG_iare[iarold][1];
+     if(pt0->v[kk]==ib) {
+       adj_a  = adja[kk] / 4;
+       voy_a  = adja[kk] % 4;
+       ref_a  = pt0->bdryref[kk];
+       kk    = MMG_iare[iarold][0];
+       adj_b  = adja[kk] / 4;
+       voy_b  = adja[kk] % 4;
+       ref_b  = pt0->bdryref[kk]; 
+     } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+       adj_b  = adja[kk] / 4;
+       voy_b  = adja[kk] % 4;
+       ref_b  = pt0->bdryref[kk];  
+       kk    = MMG_iare[iarold][0];
+       adj_a  = adja[kk] / 4;
+       voy_a  = adja[kk] % 4;
+       ref_a  = pt0->bdryref[kk]; 
+     } 
+   
+     iadr = (iel-1)*4 + 1;
+     adja = &mesh->adja[iadr];
+     if(old==(adja[MMG_isar[iar][0]]/4)) {
+       iadr = (lel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[3] = adj_a*4 + voy_a;
+       mesh->tetra[lel].bdryref[3] = ref_a;
+       
+       if (adj_a) {
+         iadr = (adj_a-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_a] = lel*4 + 3; 
+       }
+      
+       iadr = (mel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[2] = adj_b*4 + voy_b; 
+       mesh->tetra[mel].bdryref[2] = ref_b;
+       
+       if (adj_b) {
+         iadr = (adj_b-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_b] = mel*4 + 2;
+       }
+      
+     } else if(old==(adja[MMG_isar[iar][1]]/4)){
+       iadr = (jel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[2] = adj_a*4 + voy_a; 
+       mesh->tetra[jel].bdryref[2] = ref_a;
+       
+       if (adj_a) {
+         iadr = (adj_a-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_a] = jel*4 + 2;
+       }
+      
+       iadr = (kel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[3] = adj_b*4 + voy_b;
+       mesh->tetra[kel].bdryref[3] = ref_b;
+       
+       if (adj_b) {
+         iadr = (adj_b-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_b] = kel*4 + 3; 
+       }
+     } else {
+
+     /*old n'est pas un voisin de iel*/
+       iadr = (iel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       j    = MMG_isar[iar][0];
+       adj  = adja[j] / 4;
+       voy  = adja[j] % 4;
+       pt1  = &mesh->tetra[adj];
+    
+      if(pt1->v[MMG_idir[voy][0]]==s2) {
+          j = MMG_idir[voy][0];
+      } else if(pt1->v[MMG_idir[voy][1]]==s2) {
+          j = MMG_idir[voy][1];
+      } else if(pt1->v[MMG_idir[voy][2]]==s2) {
+          j = MMG_idir[voy][2];
+      }
+
+       iadr = (adj-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       if(old==adja[j] / 4) {
+         
+         iadr = (lel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[lel].bdryref[1] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = lel*4 + 1;
+         }
+      
+         iadr = (mel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b; 
+         mesh->tetra[mel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = mel*4 + 1; 
+         }
+       } else {
+         iadr = (jel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[jel].bdryref[1] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = jel*4 + 1;
+         }
+      
+         iadr = (kel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b; 
+         mesh->tetra[kel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = kel*4 + 1; 
+         }
+       }
+    }
+  
+  }
+  
+   /*internal faces*/
+   iadr = (jel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = kel*4 + 0;
+   adja[3] = nel*4 + 2;
+
+   iadr = (kel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = jel*4 + 0;
+   adja[2] = pel*4 + 3;
+  
+   iadr = (lel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = mel*4 + 0;
+   adja[2] = nel*4 + 1;
+   
+   iadr = (mel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = lel*4 + 0;
+   adja[3] = pel*4 + 1;
+  
+   iadr = (nel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = pel*4 + 0;
+   adja[2] = jel*4 + 3;
+   adja[1] = lel*4 + 2;
+   
+   iadr = (pel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = nel*4 + 0;
+   adja[3] = kel*4 + 2;
+   adja[1] = mel*4 + 3;
+  
+  /*bdryinfo*/           
+	pt1 = &mesh->tetra[jel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);   
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[kel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[lel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[mel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[nel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[pel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+  /* remove 5 old tetra */
+  for (k=1; k<=5; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = pel;
+  list->tetra[7] = 0;
+  
+  M_free(hed.item);
+
+  return(6);
+}
+
+
+int MMG_swap56_5(pMesh mesh,pSol sol,pList list) {
+   pTetra pt,pt1,pt0;
+	 Hedge			hed;
+   int i,ia,ib,s1,s2,s3,s4,s5;
+   int jel,kel,lel,mel,nel,pel;
+   int iadr,iarold,*adja,k,adj,old,kk,adj_a,adj_b,j,iel,iar,ref,ref_a,ref_b;
+   short voy,voy_a,voy_b;
+  if ( !MMG_zaldy4(&hed,17) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP442 IGNORED\n"); 
+  }   
+
+  iel  = list->tetra[1] / 6;
+  iar  = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref;
+
+   ia  = pt->v[ MMG_iare[iar][0] ];
+   ib  = pt->v[ MMG_iare[iar][1] ];
+   s1  = pt->v[ MMG_isar[iar][0] ];
+   s2  = pt->v[ MMG_isar[iar][1] ]; 
+	for(i=0 ; i<6 ; i++) { 
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+  
+   iadr = (iel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   k    = MMG_isar[iar][0];
+   adj  = adja[k] / 4;
+   voy  = adja[k] % 4;
+   pt1  = &mesh->tetra[adj];
+   s3   = pt1->v[voy];
+
+   iadr = (adj-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   if(pt1->v[MMG_idir[voy][0]]==s2) {
+      k = MMG_idir[voy][0];
+   } else if(pt1->v[MMG_idir[voy][1]]==s2) {
+      k = MMG_idir[voy][1];
+   } else if(pt1->v[MMG_idir[voy][2]]==s2) {
+      k = MMG_idir[voy][2];
+   } else {
+     puts("point non existant");
+     exit(0);
+   }   
+   adj  = adja[k] / 4;
+   voy  = adja[k] % 4;
+   pt1  = &mesh->tetra[adj];
+   s4   = pt1->v[voy];
+  
+   iadr = (iel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   k    = MMG_isar[iar][1];
+   adj  = adja[k] / 4;
+   voy  = adja[k] % 4;
+   pt1  = &mesh->tetra[adj];
+   s5   = pt1->v[voy];
+
+   /* create 6 new tetra */
+   jel = MMG_newElt(mesh);
+   pt1 = &mesh->tetra[jel];
+   pt1->v[0] = ia;
+   pt1->v[1] = s1;
+   pt1->v[2] = s2;
+   pt1->v[3] = s5;
+   pt1->qual = list->qual[1];
+   pt1->flag = mesh->flag;
+   pt1->ref  = ref;
+   
+   kel = MMG_newElt(mesh);
+   pt1 = &mesh->tetra[kel];
+   pt1->v[0] = ib;
+   pt1->v[1] = s1;
+   pt1->v[2] = s5;
+   pt1->v[3] = s2;
+   pt1->qual = list->qual[2];
+   pt1->flag = mesh->flag;
+   pt1->ref  = ref;
+   
+   lel = MMG_newElt(mesh);
+   pt1 = &mesh->tetra[lel];
+   pt1->v[0] = ia;
+   pt1->v[1] = s2;
+   pt1->v[2] = s3;
+   pt1->v[3] = s5;
+   pt1->qual = list->qual[3];
+   pt1->flag = mesh->flag;
+   pt1->ref  = ref;
+   
+   mel = MMG_newElt(mesh);
+   pt1 = &mesh->tetra[mel];
+   pt1->v[0] = ib;
+   pt1->v[1] = s2;
+   pt1->v[2] = s5;
+   pt1->v[3] = s3;
+   pt1->qual = list->qual[4];
+   pt1->flag = mesh->flag;
+   pt1->ref  = ref;
+
+   nel = MMG_newElt(mesh);
+   pt1 = &mesh->tetra[nel];
+   pt1->v[0] = ia;
+   pt1->v[1] = s3;
+   pt1->v[2] = s4;
+   pt1->v[3] = s5;
+   pt1->qual = list->qual[5];
+   pt1->flag = mesh->flag;
+   pt1->ref  = ref;
+   
+   pel = MMG_newElt(mesh);
+   pt1 = &mesh->tetra[pel];
+   pt1->v[0] = ib;
+   pt1->v[1] = s3;
+   pt1->v[2] = s5;
+   pt1->v[3] = s4;
+   pt1->qual = list->qual[6];
+   pt1->flag = mesh->flag; 
+   pt1->ref  = ref;
+   
+   /*external faces*/
+     /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2; 
+  }
+  
+  for(k=2 ; k<=5 ; k++) {
+    
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0 = &mesh->tetra[old];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4; 
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4; 
+      ref_b  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    if(old==(adja[MMG_isar[iar][0]]/4)) {
+      iadr = (lel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_a*4 + voy_a;
+      mesh->tetra[lel].bdryref[3] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = lel*4 + 3;
+      }
+      
+      iadr = (mel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_b*4 + voy_b;
+      mesh->tetra[mel].bdryref[2] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = mel*4 + 2; 
+      }
+      
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[jel].bdryref[2] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 2;
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[3] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 3;
+      }
+    } else {
+      /*old n'est pas un voisin de iel*/
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      j    = MMG_isar[iar][0];
+      adj  = adja[j] / 4;
+      voy  = adja[j] % 4;
+      pt1  = &mesh->tetra[adj];
+    
+     if(pt1->v[MMG_idir[voy][0]]==s2) {
+         j = MMG_idir[voy][0];
+      } else if(pt1->v[MMG_idir[voy][1]]==s2) {
+         j = MMG_idir[voy][1];
+      } else if(pt1->v[MMG_idir[voy][2]]==s2) {
+         j = MMG_idir[voy][2];
+      }
+
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      if(old==adja[j] / 4) {
+         iadr = (nel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[3] = adj_a*4 + voy_a;
+         mesh->tetra[nel].bdryref[3] = ref_a;
+          
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = nel*4 + 3;
+         }
+      
+         iadr = (pel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[2] = adj_b*4 + voy_b;
+         mesh->tetra[pel].bdryref[2] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = pel*4 + 2;
+         }
+      } else {
+         iadr = (nel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[nel].bdryref[1] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = nel*4 + 1;
+         }
+      
+         iadr = (pel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[pel].bdryref[1] = ref_b;
+          
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = pel*4 + 1;
+         }
+      }
+    }
+  
+  }
+  
+   /*internal faces*/
+   iadr = (jel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = kel*4 + 0;
+   adja[1] = lel*4 + 2;
+   
+   iadr = (kel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = jel*4 + 0;
+   adja[1] = mel*4 + 3;
+  
+   iadr = (lel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = mel*4 + 0;
+   adja[1] = nel*4 + 2;
+   adja[2] = jel*4 + 1;
+   
+   iadr = (mel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = lel*4 + 0;
+   adja[1] = pel*4 + 3;
+   adja[3] = kel*4 + 1;
+   
+   iadr = (nel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = pel*4 + 0;
+   adja[2] = lel*4 + 1;
+   
+   iadr = (pel-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[0] = nel*4 + 0;
+   adja[3] = mel*4 + 1;
+  
+  /*bdryinfo*/           
+	pt1 = &mesh->tetra[jel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);   
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[kel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[lel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[mel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[nel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+	pt1 = &mesh->tetra[pel];
+	for(i=0 ; i<6 ; i++) { 
+		pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+		if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	}
+  /* remove 5 old tetra */
+  for (k=1; k<=5; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = pel;
+  list->tetra[7] = 0;
+ 	M_free(hed.item);
+
+  return(6);
+}
diff --git a/contrib/mmg3d/build/sources/swap68.c b/contrib/mmg3d/build/sources/swap68.c
new file mode 100644
index 0000000000000000000000000000000000000000..ec7c45dc7e936b3796d84f4a85f458aa41c3b2b4
--- /dev/null
+++ b/contrib/mmg3d/build/sources/swap68.c
@@ -0,0 +1,5674 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+/*find points of polygone*/
+static int MMG_findpolygone(pMesh mesh,int iel,int iar,int *s) {
+  pTetra pt,pt1;
+  int ia,ib;
+  int iadr,*adja,k,adj;
+  int s1,s2,s3,s4,s5,s6;
+  short voy;
+
+  pt  = &mesh->tetra[iel];
+
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  s1  = pt->v[ MMG_isar[iar][0] ];
+  s2  = pt->v[ MMG_isar[iar][1] ]; 
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  
+  s3  = pt1->v[voy];
+  iadr = (adj-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  if(pt1->v[MMG_idir[voy][0]]==s2) {
+     k = MMG_idir[voy][0];
+  } else if(pt1->v[MMG_idir[voy][1]]==s2) {
+     k = MMG_idir[voy][1];
+  } else if(pt1->v[MMG_idir[voy][2]]==s2) {
+     k = MMG_idir[voy][2];
+  } else {
+    puts("MMG_simu56_ani: point s2 non existant");
+    exit(0);
+  }  
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s4   = pt1->v[voy];
+  iadr = (adj-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  if(pt1->v[MMG_idir[voy][0]]==s3) {
+     k = MMG_idir[voy][0];
+  } else if(pt1->v[MMG_idir[voy][1]]==s3) {
+     k = MMG_idir[voy][1];
+  } else if(pt1->v[MMG_idir[voy][2]]==s3) {
+     k = MMG_idir[voy][2];
+  } else {
+    puts("MMG_simu56_ani: point s4 non existant");
+    exit(0);
+  }  
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s5   = pt1->v[voy]; 
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  s6   = pt1->v[voy];
+  
+  /*printf("polygone : %d %d %d %d %d %d\n",s1,s2,s3,s4,s5,s6);*/
+  s[0]=s1;
+  s[1]=s2;
+  s[2]=s3;
+  s[3]=s4;
+  s[4]=s5;
+  s[5]=s6;
+  return(1);
+}
+
+static int MMG_updatebdryinfo(pMesh mesh,pHedge hed,pList list) { 
+	pTetra  pt1;
+	int     iel,i,k;
+	
+	for(k=1 ; k<=8 ; k++) { 
+		iel = list->tetra[k];
+	  pt1 = &mesh->tetra[iel];
+	  for(i=0 ; i<6 ; i++) { 
+	  	pt1->bdryinfo[i] = MMG_edgePut(hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+	  	if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	  }
+	}
+	
+	return(1);
+}
+
+int MMG_swap68_1(pMesh mesh,pSol sol,pList list) { 
+  pTetra pt1,pt,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[6],j;
+  int    jel,kel,lel,mel,nel,oel,pel,qel;
+  int    iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b;
+  short   voy,voy_a,voy_b;
+
+  if ( !MMG_zaldy4(&hed,21) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP661 IGNORED\n"); 
+  }   
+
+  /*find points of polygone*/
+  iel  = list->tetra[1] / 6;
+  iar  = list->tetra[1] % 6;
+  if(!MMG_findpolygone(mesh,iel,iar,s)) return(0);
+  
+  pt  = &mesh->tetra[iel];  
+  ref = pt->ref;
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  
+  /*create 8 tetras*/
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[3];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[4];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[5];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[8];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  //printf("nx : %d %d %d %d %d %d %d %d\n",jel,kel,lel,mel,nel,oel,pel,qel);
+  /*external faces*/
+  /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3; 
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  
+  for(k=2 ; k<=6 ; k++) {    
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0 = &mesh->tetra[old];
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4; 
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4; 
+      ref_b  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+   
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    if(old==(adja[MMG_isar[iar][0]]/4)) {
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_a*4 + voy_a;
+      mesh->tetra[jel].bdryref[1] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 1;
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[1] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 1;
+      }
+      
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){
+      iadr = (pel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[pel].bdryref[2] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = pel*4 + 2;
+      }
+      
+      iadr = (qel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[qel].bdryref[3] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = qel*4 + 3;
+      }
+    } else {
+       /*old n'est pas un voisin de iel*/
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      j    = MMG_isar[iar][0];
+      adj  = adja[j] / 4;
+      voy  = adja[j] % 4;
+      pt1  = &mesh->tetra[adj];
+    
+     if(pt1->v[MMG_idir[voy][0]]==s[1]) {
+         j = MMG_idir[voy][0];
+      } else if(pt1->v[MMG_idir[voy][1]]==s[1]) {
+         j = MMG_idir[voy][1];
+      } else if(pt1->v[MMG_idir[voy][2]]==s[1]) {
+         j = MMG_idir[voy][2];
+      }
+
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      if(old == adja[j] / 4) {        
+         iadr = (lel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[lel].bdryref[1] = ref_a;
+          
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = lel*4 + 1; 
+         }
+      
+         iadr = (mel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[mel].bdryref[1] = ref_b;         
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = mel*4 + 1;
+         }
+      } else {
+        iadr = (iel-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        j    = MMG_isar[iar][1];
+        adj  = adja[j] / 4;
+        voy  = adja[j] % 4;
+        pt1  = &mesh->tetra[adj];
+    
+       if(pt1->v[MMG_idir[voy][0]]==s[0]) {
+           j = MMG_idir[voy][0];
+       } else if(pt1->v[MMG_idir[voy][1]]==s[0]) {
+           j = MMG_idir[voy][1];
+       } else if(pt1->v[MMG_idir[voy][2]]==s[0]) {
+          j = MMG_idir[voy][2];
+       }
+
+       iadr = (adj-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       if(old == adja[j] / 4) {   
+         iadr = (pel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[pel].bdryref[1] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = pel*4 + 1;  
+         }
+      
+         iadr = (qel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[qel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = qel*4 + 1; 
+         }
+      }
+      else {
+       iadr = (nel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[1] = adj_a*4 + voy_a;
+       mesh->tetra[nel].bdryref[1] = ref_a;
+       
+       if (adj_a) {
+         iadr = (adj_a-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_a] = nel*4 + 1;
+       }
+      
+       iadr = (oel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[1] = adj_b*4 + voy_b;
+       mesh->tetra[oel].bdryref[1] = ref_b;
+       
+       if (adj_b) {
+         iadr = (adj_b-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_b] = oel*4 + 1; 
+       }    
+     }
+    }
+   }
+ }
+ 
+  /*internal faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[3] = jel*4 + 2;
+  adja[2] = nel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[2] = kel*4 + 3;
+  adja[3] = oel*4 + 2;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[3] = lel*4 + 2;
+  adja[2] = pel*4 + 3;	
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[2] = mel*4 + 3;
+  adja[3] = qel*4 + 2; 
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[3] = nel*4 + 2;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[2] = oel*4 + 3;
+
+  /* remove 6 old tetra */
+  for (k=1; k<=6; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = oel;
+  list->tetra[7] = pel;
+  list->tetra[8] = qel;
+  list->tetra[9] = 0;
+
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(8);
+}
+
+int MMG_swap68_2(pMesh mesh,pSol sol,pList list){ 
+  pTetra pt1,pt,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[6],j;
+  int    jel,kel,lel,mel,nel,oel,pel,qel;
+  int    iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b;
+  short  voy,voy_a,voy_b;
+
+  if ( !MMG_zaldy4(&hed,21) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP662 IGNORED\n"); 
+  }   
+
+
+  /*find points of polygone*/
+  iel  = list->tetra[1] / 6;
+  iar  = list->tetra[1] % 6;
+  if(!MMG_findpolygone(mesh,iel,iar,s)) return(0);
+  
+  pt  = &mesh->tetra[iel];  
+  ref = pt->ref;
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+ 
+  /*create 8 tetras*/
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[3];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[4];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[8];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  /*external faces*/
+  /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;   
+  }
+  
+  for(k=2 ; k<=6 ; k++) {    
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0 = &mesh->tetra[old];
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4; 
+      ref_b  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+   
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    /*s[1] appartient a old */
+    if(old==(adja[MMG_isar[iar][0]]/4)) {
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_a*4 + voy_a;
+      mesh->tetra[jel].bdryref[1] = ref_a;
+        
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 1; 
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[1] = ref_b;
+       
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 1; 
+      }
+      
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){
+      /*s[0] appartient a old*/
+      iadr = (nel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[nel].bdryref[2] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = nel*4 + 2;
+      }
+      
+      iadr = (oel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[oel].bdryref[3] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = oel*4 + 3;
+      }
+    } else {
+      /*old n'est pas un voisin de iel*/
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      j    = MMG_isar[iar][0];
+      adj  = adja[j] / 4;
+      voy  = adja[j] % 4;
+      pt1  = &mesh->tetra[adj];
+    
+     if(pt1->v[MMG_idir[voy][0]]==s[1]) {
+         j = MMG_idir[voy][0];
+      } else if(pt1->v[MMG_idir[voy][1]]==s[1]) {
+         j = MMG_idir[voy][1];
+      } else if(pt1->v[MMG_idir[voy][2]]==s[1]) {
+         j = MMG_idir[voy][2];
+      }
+
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      /*s[2] s[3] appartient a old*/
+      if(old == adja[j] / 4) {        
+         iadr = (lel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[lel].bdryref[1] = ref_a;
+          
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = lel*4 + 1; 
+         }
+      
+         iadr = (mel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[mel].bdryref[1] = ref_b;
+          
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = mel*4 + 1; 
+         }
+      } else {
+        iadr = (iel-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        j    = MMG_isar[iar][1];
+        adj  = adja[j] / 4;
+        voy  = adja[j] % 4;
+        pt1  = &mesh->tetra[adj];
+    
+       if(pt1->v[MMG_idir[voy][0]]==s[0]) {
+           j = MMG_idir[voy][0];
+       } else if(pt1->v[MMG_idir[voy][1]]==s[0]) {
+           j = MMG_idir[voy][1];
+       } else if(pt1->v[MMG_idir[voy][2]]==s[0]) {
+          j = MMG_idir[voy][2];
+       }
+
+       iadr = (adj-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       /*s[4] s[5] appartient a old*/
+       if(old == adja[j] / 4) {   
+         iadr = (pel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[pel].bdryref[1] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = pel*4 + 1; 
+         }
+      
+         iadr = (qel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[qel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = qel*4 + 1;
+         }
+      }
+      else {
+      /*s[3] s[4] appartient a old*/
+       iadr = (pel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[3] = adj_a*4 + voy_a;
+       mesh->tetra[pel].bdryref[3] = ref_a;
+       
+       if (adj_a) {
+         iadr = (adj_a-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_a] = pel*4 + 3;
+       }
+      
+       iadr = (qel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[2] = adj_b*4 + voy_b;
+       mesh->tetra[qel].bdryref[2] = ref_b;
+        
+       if (adj_b) {
+         iadr = (adj_b-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_b] = qel*4 + 2;
+       }     
+     }
+    }
+   }
+ }  
+ 
+   /*internal faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[3] = jel*4 + 2;
+  adja[2] = nel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[2] = kel*4 + 3;
+  adja[3] = oel*4 + 2;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[3] = lel*4 + 2;
+  adja[1] = pel*4 + 2;	
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[2] = mel*4 + 3;
+  adja[1] = qel*4 + 3; 
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = nel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = oel*4 + 1;
+  /* remove 6 old tetra */
+  for (k=1; k<=6; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = oel;
+  list->tetra[7] = pel;
+  list->tetra[8] = qel;
+  list->tetra[9] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(8);
+}
+
+int MMG_swap68_3(pMesh mesh,pSol sol,pList list){ 
+  pTetra pt1,pt,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[6],j;
+  int    jel,kel,lel,mel,nel,oel,pel,qel;
+  int    iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b;
+  short  voy,voy_a,voy_b;    
+
+  if ( !MMG_zaldy4(&hed,21) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+    
+  /*find points of polygone*/
+  iel  = list->tetra[1] / 6;
+  iar  = list->tetra[1] % 6;
+  if(!MMG_findpolygone(mesh,iel,iar,s)) return(0);
+  
+  pt  = &mesh->tetra[iel];  
+	for(i=0 ; i<6 ; i++) { 
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+  ref = pt->ref;
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+ 
+  /*create 8 tetras*/
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[3];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[4];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[6];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[7];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[8];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  /*external faces*/
+  /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3; 
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2; 
+  }
+  
+  for(k=2 ; k<=6 ; k++) {    
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0 = &mesh->tetra[old];
+	  for(i=0 ; i<6 ; i++) {
+	  	MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+	  }
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4; 
+      ref_b  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+   
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    /*s[1] appartient a old */
+    if(old==(adja[MMG_isar[iar][0]]/4)) {
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_a*4 + voy_a;
+      mesh->tetra[jel].bdryref[1] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 1;
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[1] = ref_b;
+
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 1;
+      }
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){
+      /*s[0] appartient a old*/
+      iadr = (lel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[lel].bdryref[2] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = lel*4 + 2; 
+      }
+      
+      iadr = (mel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[mel].bdryref[3] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = mel*4 + 3;
+      }
+    } else {
+      /*old n'est pas un voisin de iel*/
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      j    = MMG_isar[iar][0];
+      adj  = adja[j] / 4;
+      voy  = adja[j] % 4;
+      pt1  = &mesh->tetra[adj];
+    
+     if(pt1->v[MMG_idir[voy][0]]==s[1]) {
+         j = MMG_idir[voy][0];
+      } else if(pt1->v[MMG_idir[voy][1]]==s[1]) {
+         j = MMG_idir[voy][1];
+      } else if(pt1->v[MMG_idir[voy][2]]==s[1]) {
+         j = MMG_idir[voy][2];
+      }
+
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      /*s[2] s[3] appartient a old*/
+      if(old == adja[j] / 4) {        
+         iadr = (pel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[3] = adj_a*4 + voy_a;
+         mesh->tetra[pel].bdryref[3] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = pel*4 + 3;
+         }
+      
+         iadr = (qel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[2] = adj_b*4 + voy_b;
+         mesh->tetra[qel].bdryref[2] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = qel*4 + 2;
+         }
+      } else {
+        iadr = (iel-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        j    = MMG_isar[iar][1];
+        adj  = adja[j] / 4;
+        voy  = adja[j] % 4;
+        pt1  = &mesh->tetra[adj];
+    
+       if(pt1->v[MMG_idir[voy][0]]==s[0]) {
+           j = MMG_idir[voy][0];
+       } else if(pt1->v[MMG_idir[voy][1]]==s[0]) {
+           j = MMG_idir[voy][1];
+       } else if(pt1->v[MMG_idir[voy][2]]==s[0]) {
+          j = MMG_idir[voy][2];
+       }
+
+       iadr = (adj-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       /*s[4] s[5] appartient a old*/
+       if(old == adja[j] / 4) {   
+         iadr = (nel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[nel].bdryref[1] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = nel*4 + 1; 
+         }
+      
+         iadr = (oel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[oel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = oel*4 + 1;
+         }
+      }
+      else {
+      /*s[3] s[4] appartient a old*/
+       iadr = (pel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[1] = adj_a*4 + voy_a;
+       mesh->tetra[pel].bdryref[1] = ref_a;
+        
+       if (adj_a) {
+         iadr = (adj_a-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_a] = pel*4 + 1;
+       }
+      
+       iadr = (qel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[1] = adj_b*4 + voy_b;
+       mesh->tetra[qel].bdryref[1] = ref_b;
+       
+       if (adj_b) {
+         iadr = (adj_b-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_b] = qel*4 + 1;
+       }     
+     }
+    }
+   }
+  }  
+
+  /*internal faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[3] = jel*4 + 2;
+  adja[1] = nel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[2] = kel*4 + 3;
+  adja[1] = oel*4 + 3;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = lel*4 + 1;
+  adja[3] = pel*4 + 2;	
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = mel*4 + 1;
+  adja[2] = qel*4 + 3; 
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = nel*4 + 3;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = oel*4 + 2;
+  /* remove 6 old tetra */
+  for (k=1; k<=6; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = oel;
+  list->tetra[7] = pel;
+  list->tetra[8] = qel;
+  list->tetra[9] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(8);
+}
+
+int MMG_swap68_4(pMesh mesh,pSol sol,pList list){ 
+  pTetra pt1,pt,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[6],j;
+  int    jel,kel,lel,mel,nel,oel,pel,qel;
+  int    iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b;
+  short  voy,voy_a,voy_b;
+
+  if ( !MMG_zaldy4(&hed,21) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP684 IGNORED\n"); 
+  }   
+
+  
+  /*find points of polygone*/
+  iel  = list->tetra[1] / 6;
+  iar  = list->tetra[1] % 6;
+  if(!MMG_findpolygone(mesh,iel,iar,s)) return(0);
+  
+  pt  = &mesh->tetra[iel];  
+	for(i=0 ; i<6 ; i++) { 
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+  ref = pt->ref;
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+ 
+  /*create 8 tetras*/
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[3];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[4];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[8];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  /*external faces*/
+  /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3; 
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;  
+  }
+  
+  for(k=2 ; k<=6 ; k++) {    
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0 = &mesh->tetra[old];
+	  for(i=0 ; i<6 ; i++) {
+	  	MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+	  }
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4; 
+      ref_b  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+   
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    /*s[1] appartient a old */
+    if(old==(adja[MMG_isar[iar][0]]/4)) {
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_a*4 + voy_a;
+      mesh->tetra[jel].bdryref[1] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 1;
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[1] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 1;
+      }
+      
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){
+      /*s[0] appartient a old*/
+      iadr = (lel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[lel].bdryref[2] = ref_a;
+       
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = lel*4 + 2;
+      }
+      
+      iadr = (mel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[mel].bdryref[3] = ref_b;
+       
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = mel*4 + 3;
+      }
+    } else {
+      /*old n'est pas un voisin de iel*/
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      j    = MMG_isar[iar][0];
+      adj  = adja[j] / 4;
+      voy  = adja[j] % 4;
+      pt1  = &mesh->tetra[adj];
+    
+     if(pt1->v[MMG_idir[voy][0]]==s[1]) {
+         j = MMG_idir[voy][0];
+      } else if(pt1->v[MMG_idir[voy][1]]==s[1]) {
+         j = MMG_idir[voy][1];
+      } else if(pt1->v[MMG_idir[voy][2]]==s[1]) {
+         j = MMG_idir[voy][2];
+      }
+
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      /*s[2] s[3] appartient a old*/
+      if(old == adja[j] / 4) {        
+         iadr = (nel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[3] = adj_a*4 + voy_a;
+         mesh->tetra[nel].bdryref[3] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = nel*4 + 3;
+         }
+      
+         iadr = (oel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[2] = adj_b*4 + voy_b;
+         mesh->tetra[oel].bdryref[2] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = oel*4 + 2; 
+         }
+      } else {
+        iadr = (iel-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        j    = MMG_isar[iar][1];
+        adj  = adja[j] / 4;
+        voy  = adja[j] % 4;
+        pt1  = &mesh->tetra[adj];
+    
+       if(pt1->v[MMG_idir[voy][0]]==s[0]) {
+           j = MMG_idir[voy][0];
+       } else if(pt1->v[MMG_idir[voy][1]]==s[0]) {
+           j = MMG_idir[voy][1];
+       } else if(pt1->v[MMG_idir[voy][2]]==s[0]) {
+          j = MMG_idir[voy][2];
+       }
+
+       iadr = (adj-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       /*s[4] s[5] appartient a old*/
+       if(old == adja[j] / 4) {   
+         iadr = (pel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[pel].bdryref[1] = ref_a;
+          
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = pel*4 + 1;
+         }
+      
+         iadr = (qel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[qel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = qel*4 + 1;
+         }
+      }
+      else {
+      /*s[3] s[4] appartient a old*/
+       iadr = (pel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[3] = adj_a*4 + voy_a;
+       mesh->tetra[pel].bdryref[3] = ref_a;
+       
+       if (adj_a) {
+         iadr = (adj_a-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_a] = pel*4 + 3;
+       }
+      
+       iadr = (qel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[2] = adj_b*4 + voy_b;
+       mesh->tetra[qel].bdryref[2] = ref_b;
+       
+       if (adj_b) {
+         iadr = (adj_b-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_b] = qel*4 + 2;
+       }     
+     }
+    }
+   }
+ }  
+ 
+   /*internal faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[3] = jel*4 + 2;
+  adja[1] = nel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[2] = kel*4 + 3;
+  adja[1] = oel*4 + 3;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = lel*4 + 1;
+  adja[1] = pel*4 + 2;	
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = mel*4 + 1;
+  adja[1] = qel*4 + 3; 
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = nel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = oel*4 + 1;
+  /* remove 6 old tetra */
+  for (k=1; k<=6; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = oel;
+  list->tetra[7] = pel;
+  list->tetra[8] = qel;
+  list->tetra[9] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(8);
+}
+
+int MMG_swap68_5(pMesh mesh,pSol sol,pList list){ 
+  pTetra pt1,pt,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[6],j;
+  int    jel,kel,lel,mel,nel,oel,pel,qel;
+  int    iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b;
+  short  voy,voy_a,voy_b;
+
+  if ( !MMG_zaldy4(&hed,21) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP685 IGNORED\n"); 
+  }   
+
+  
+  /*find points of polygone*/
+  iel  = list->tetra[1] / 6;
+  iar  = list->tetra[1] % 6;
+  if(!MMG_findpolygone(mesh,iel,iar,s)) return(0);
+  
+  pt  = &mesh->tetra[iel];  
+	for(i=0 ; i<6 ; i++) { 
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+  ref = pt->ref;
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+ 
+  /*create 8 tetras*/
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[2];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[3];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[4];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[8];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  /*external faces*/
+  /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;
+  }
+  
+  for(k=2 ; k<=6 ; k++) {    
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0 = &mesh->tetra[old];
+	  for(i=0 ; i<6 ; i++) {
+	  	MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+	  }
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4; 
+      ref_b  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+   
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    /*s[1] appartient a old */
+    if(old==(adja[MMG_isar[iar][0]]/4)) {
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_a*4 + voy_a;
+      mesh->tetra[jel].bdryref[3] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 3;
+      }  
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[2] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 2;
+      }
+      
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){
+      /*s[0] appartient a old*/
+      iadr = (nel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[nel].bdryref[2] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = nel*4 + 2;
+      }
+      
+      iadr = (oel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[oel].bdryref[3] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = oel*4 + 3;
+      }
+    } else {
+      /*old n'est pas un voisin de iel*/
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      j    = MMG_isar[iar][0];
+      adj  = adja[j] / 4;
+      voy  = adja[j] % 4;
+      pt1  = &mesh->tetra[adj];
+    
+     if(pt1->v[MMG_idir[voy][0]]==s[1]) {
+         j = MMG_idir[voy][0];
+      } else if(pt1->v[MMG_idir[voy][1]]==s[1]) {
+         j = MMG_idir[voy][1];
+      } else if(pt1->v[MMG_idir[voy][2]]==s[1]) {
+         j = MMG_idir[voy][2];
+      }
+
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      /*s[2] s[3] appartient a old*/
+      if(old == adja[j] / 4) {        
+         iadr = (jel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[jel].bdryref[1] = ref_a;
+         
+         if (adj_a){
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = jel*4 + 1;
+         }
+         
+         iadr = (kel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[kel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = kel*4 + 1; 
+         }
+      } else {
+        iadr = (iel-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        j    = MMG_isar[iar][1];
+        adj  = adja[j] / 4;
+        voy  = adja[j] % 4;
+        pt1  = &mesh->tetra[adj];
+    
+       if(pt1->v[MMG_idir[voy][0]]==s[0]) {
+           j = MMG_idir[voy][0];
+       } else if(pt1->v[MMG_idir[voy][1]]==s[0]) {
+           j = MMG_idir[voy][1];
+       } else if(pt1->v[MMG_idir[voy][2]]==s[0]) {
+          j = MMG_idir[voy][2];
+       }
+
+       iadr = (adj-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       /*s[4] s[5] appartient a old*/
+       if(old == adja[j] / 4) {   
+         iadr = (pel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[pel].bdryref[1] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = pel*4 + 1;
+         }
+      
+         iadr = (qel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[qel].bdryref[1] = ref_b;
+          
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = qel*4 + 1;
+         }
+      }
+      else {
+      /*s[3] s[4] appartient a old*/
+       iadr = (pel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[3] = adj_a*4 + voy_a;
+       mesh->tetra[pel].bdryref[3] = ref_a;
+       
+       if (adj_a) {
+         iadr = (adj_a-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_a] = pel*4 + 3;
+       }
+      
+       iadr = (qel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[2] = adj_b*4 + voy_b;
+       mesh->tetra[qel].bdryref[2] = ref_b;
+       
+       if (adj_b) {
+         iadr = (adj_b-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_b] = qel*4 + 2;
+       }     
+     }
+    }
+   }
+ }  
+ 
+   /*internal faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 1;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 1;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[1] = jel*4 + 2;
+  adja[2] = nel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[1] = kel*4 + 3;
+  adja[3] = oel*4 + 2;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[3] = lel*4 + 2;
+  adja[1] = pel*4 + 2;	
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[2] = mel*4 + 3;
+  adja[1] = qel*4 + 3; 
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = nel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = oel*4 + 1;
+  /* remove 6 old tetra */
+  for (k=1; k<=6; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = oel;
+  list->tetra[7] = pel;
+  list->tetra[8] = qel;
+  list->tetra[9] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(8);
+}
+
+int MMG_swap68_6(pMesh mesh,pSol sol,pList list){ 
+  pTetra pt1,pt,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[6],j;
+  int    jel,kel,lel,mel,nel,oel,pel,qel;
+  int    iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b;
+  short  voy,voy_a,voy_b;
+
+  if ( !MMG_zaldy4(&hed,21) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP686 IGNORED\n"); 
+  }   
+
+  
+  /*find points of polygone*/
+  iel  = list->tetra[1] / 6;
+  iar  = list->tetra[1] % 6;
+  if(!MMG_findpolygone(mesh,iel,iar,s)) return(0);
+  
+  pt  = &mesh->tetra[iel];  
+	for(i=0 ; i<6 ; i++) { 
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+  ref = pt->ref;
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+ 
+  /*create 8 tetras*/
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[2];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[3];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[4];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[5];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[8];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  /*external faces*/
+  /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3; 
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;
+  }
+  
+  for(k=2 ; k<=6 ; k++) {    
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0 = &mesh->tetra[old];
+	  for(i=0 ; i<6 ; i++) {
+	  	MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+	  }
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;  
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4; 
+      ref_b  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+   
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    /*s[1] appartient a old */
+    if(old==(adja[MMG_isar[iar][0]]/4)) {
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_a*4 + voy_a;
+      mesh->tetra[jel].bdryref[3] = ref_a;
+     
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 3;
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[2] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 2;
+      }
+      
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){
+      /*s[0] appartient a old*/
+      iadr = (pel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[pel].bdryref[2] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = pel*4 + 2;
+      }
+      
+      iadr = (qel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[qel].bdryref[3] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = qel*4 + 3;
+      }
+    } else {
+      /*old n'est pas un voisin de iel*/
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      j    = MMG_isar[iar][0];
+      adj  = adja[j] / 4;
+      voy  = adja[j] % 4;
+      pt1  = &mesh->tetra[adj];
+    
+     if(pt1->v[MMG_idir[voy][0]]==s[1]) {
+         j = MMG_idir[voy][0];
+      } else if(pt1->v[MMG_idir[voy][1]]==s[1]) {
+         j = MMG_idir[voy][1];
+      } else if(pt1->v[MMG_idir[voy][2]]==s[1]) {
+         j = MMG_idir[voy][2];
+      }
+
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      /*s[2] s[3] appartient a old*/
+      if(old == adja[j] / 4) {        
+         iadr = (jel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[jel].bdryref[1] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = jel*4 + 1;
+         }
+      
+         iadr = (kel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[kel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = kel*4 + 1;
+         }
+      } else {
+        iadr = (iel-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        j    = MMG_isar[iar][1];
+        adj  = adja[j] / 4;
+        voy  = adja[j] % 4;
+        pt1  = &mesh->tetra[adj];
+    
+       if(pt1->v[MMG_idir[voy][0]]==s[0]) {
+           j = MMG_idir[voy][0];
+       } else if(pt1->v[MMG_idir[voy][1]]==s[0]) {
+           j = MMG_idir[voy][1];
+       } else if(pt1->v[MMG_idir[voy][2]]==s[0]) {
+          j = MMG_idir[voy][2];
+       }
+
+       iadr = (adj-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       /*s[4] s[5] appartient a old*/
+       if(old == adja[j] / 4) {   
+         iadr = (pel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[pel].bdryref[1] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = pel*4 + 1;
+         }
+      
+         iadr = (qel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[qel].bdryref[1] = ref_b;
+          
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = qel*4 + 1; 
+         }
+      }
+      else {
+      /*s[3] s[4] appartient a old*/
+       iadr = (nel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[1] = adj_a*4 + voy_a;
+       mesh->tetra[nel].bdryref[1] = ref_a;
+       
+       if (adj_a) {
+         iadr = (adj_a-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_a] = nel*4 + 1; 
+       }
+      
+       iadr = (oel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[1] = adj_b*4 + voy_b;
+       mesh->tetra[oel].bdryref[1] = ref_b;
+       
+       if (adj_b) {
+         iadr = (adj_b-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_b] = oel*4 + 1;
+       }     
+     }
+    }
+   }
+  }  
+ 
+  /*internal faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 1;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 1;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[1] = jel*4 + 2;
+  adja[2] = nel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[1] = kel*4 + 3;
+  adja[3] = oel*4 + 2;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[3] = lel*4 + 2;
+  adja[2] = pel*4 + 3;	
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[2] = mel*4 + 3;
+  adja[3] = qel*4 + 2; 
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[3] = nel*4 + 2;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[2] = oel*4 + 3;
+  /* remove 6 old tetra */
+  for (k=1; k<=6; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = oel;
+  list->tetra[7] = pel;
+  list->tetra[8] = qel;
+  list->tetra[9] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(8);
+}
+
+int MMG_swap68_7(pMesh mesh,pSol sol,pList list){ 
+  pTetra pt1,pt,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[6],j;
+  int    jel,kel,lel,mel,nel,oel,pel,qel;
+  int    iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b;
+  short  voy,voy_a,voy_b;
+
+  if ( !MMG_zaldy4(&hed,21) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP687 IGNORED\n"); 
+  }   
+
+  
+  /*find points of polygone*/
+  iel  = list->tetra[1] / 6;
+  iar  = list->tetra[1] % 6;
+  if(!MMG_findpolygone(mesh,iel,iar,s)) return(0);
+  
+  pt  = &mesh->tetra[iel];  
+	for(i=0 ; i<6 ; i++) { 
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+  ref = pt->ref;
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+ 
+  /*create 8 tetras*/
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[2];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[3];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[4];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[5];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[6];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[7];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[8];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  /*external faces*/
+  /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;  
+  }
+  
+  for(k=2 ; k<=6 ; k++) {    
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0 = &mesh->tetra[old];
+	  for(i=0 ; i<6 ; i++) {
+	  	MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+	  }
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4; 
+      ref_b  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+   
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    /*s[1] appartient a old */
+    if(old==(adja[MMG_isar[iar][0]]/4)) {
+      iadr = (nel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_a*4 + voy_a;
+      mesh->tetra[nel].bdryref[3] = ref_a; 
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = nel*4 + 3;
+      }
+      
+      iadr = (oel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_b*4 + voy_b;
+      mesh->tetra[oel].bdryref[2] = ref_b; 
+       
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = oel*4 + 2; 
+      }
+      
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){
+      /*s[0] appartient a old*/
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[jel].bdryref[2] = ref_a; 
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 2;
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[3] = ref_b; 
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 3;
+      }
+    } else {
+      /*old n'est pas un voisin de iel*/
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      j    = MMG_isar[iar][0];
+      adj  = adja[j] / 4;
+      voy  = adja[j] % 4;
+      pt1  = &mesh->tetra[adj];
+    
+     if(pt1->v[MMG_idir[voy][0]]==s[1]) {
+         j = MMG_idir[voy][0];
+      } else if(pt1->v[MMG_idir[voy][1]]==s[1]) {
+         j = MMG_idir[voy][1];
+      } else if(pt1->v[MMG_idir[voy][2]]==s[1]) {
+         j = MMG_idir[voy][2];
+      }
+
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      /*s[2] s[3] appartient a old*/
+      if(old == adja[j] / 4) {        
+         iadr = (pel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[3] = adj_a*4 + voy_a;
+         mesh->tetra[pel].bdryref[3] = ref_a; 
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = pel*4 + 3;
+         }
+      
+         iadr = (qel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[2] = adj_b*4 + voy_b;
+         mesh->tetra[qel].bdryref[2] = ref_b; 
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = qel*4 + 2; 
+         }
+      } else {
+        iadr = (iel-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        j    = MMG_isar[iar][1];
+        adj  = adja[j] / 4;
+        voy  = adja[j] % 4;
+        pt1  = &mesh->tetra[adj];
+    
+       if(pt1->v[MMG_idir[voy][0]]==s[0]) {
+           j = MMG_idir[voy][0];
+       } else if(pt1->v[MMG_idir[voy][1]]==s[0]) {
+           j = MMG_idir[voy][1];
+       } else if(pt1->v[MMG_idir[voy][2]]==s[0]) {
+          j = MMG_idir[voy][2];
+       }
+
+       iadr = (adj-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       /*s[4] s[5] appartient a old*/
+       if(old == adja[j] / 4) {   
+         iadr = (jel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[jel].bdryref[1] = ref_a; 
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = jel*4 + 1; 
+         }
+      
+         iadr = (kel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[kel].bdryref[1] = ref_b; 
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = kel*4 + 1;
+         }
+      }
+      else {
+      /*s[3] s[4] appartient a old*/
+       iadr = (pel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[1] = adj_a*4 + voy_a;
+       mesh->tetra[pel].bdryref[1] = ref_a; 
+       
+       if (adj_a) {
+         iadr = (adj_a-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_a] = pel*4 + 1; 
+       }
+      
+       iadr = (qel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[1] = adj_b*4 + voy_b;
+       mesh->tetra[qel].bdryref[1] = ref_b; 
+       
+       if (adj_b) {
+         iadr = (adj_b-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_b] = qel*4 + 1;
+       }     
+     }
+    }
+   }
+ }  
+ 
+   /*internal faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[3] = lel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[2] = mel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = jel*4 + 3;
+  adja[1] = nel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = kel*4 + 2;
+  adja[1] = oel*4 + 3;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = lel*4 + 1;
+  adja[1] = pel*4 + 2;	
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = mel*4 + 1;
+  adja[1] = qel*4 + 3; 
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = nel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = oel*4 + 1;
+  /* remove 6 old tetra */
+  for (k=1; k<=6; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = oel;
+  list->tetra[7] = pel;
+  list->tetra[8] = qel;
+  list->tetra[9] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(8);
+}
+
+int MMG_swap68_8(pMesh mesh,pSol sol,pList list){ 
+  pTetra pt1,pt,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[6],j;
+  int    jel,kel,lel,mel,nel,oel,pel,qel;
+  int    iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b;
+  short  voy,voy_a,voy_b;
+
+  if ( !MMG_zaldy4(&hed,21) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP688 IGNORED\n"); 
+  }   
+
+  
+  /*find points of polygone*/
+  iel  = list->tetra[1] / 6;
+  iar  = list->tetra[1] % 6;
+  if(!MMG_findpolygone(mesh,iel,iar,s)) return(0);
+  
+  pt  = &mesh->tetra[iel];  
+	for(i=0 ; i<6 ; i++) { 
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+  ref = pt->ref;
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+ 
+  /*create 8 tetras*/
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[3];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[4];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[8];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  /*external faces*/
+  /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;  
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  
+  for(k=2 ; k<=6 ; k++) {    
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0 = &mesh->tetra[old];
+	  for(i=0 ; i<6 ; i++) {
+	  	MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+	  }
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4; 
+      ref_b  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+   
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    /*s[1] appartient a old */
+    if(old==(adja[MMG_isar[iar][0]]/4)) {
+      iadr = (lel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_a*4 + voy_a;
+      mesh->tetra[lel].bdryref[3] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = lel*4 + 3;    
+      }
+      
+      iadr = (mel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_b*4 + voy_b;
+      mesh->tetra[mel].bdryref[2] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = mel*4 + 2;  
+      }
+      
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){
+      /*s[0] appartient a old*/
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[jel].bdryref[2] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 2;
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[3] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 3;
+      }
+    } else {
+      /*old n'est pas un voisin de iel*/
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      j    = MMG_isar[iar][0];
+      adj  = adja[j] / 4;
+      voy  = adja[j] % 4;
+      pt1  = &mesh->tetra[adj];
+    
+     if(pt1->v[MMG_idir[voy][0]]==s[1]) {
+         j = MMG_idir[voy][0];
+      } else if(pt1->v[MMG_idir[voy][1]]==s[1]) {
+         j = MMG_idir[voy][1];
+      } else if(pt1->v[MMG_idir[voy][2]]==s[1]) {
+         j = MMG_idir[voy][2];
+      }
+
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      /*s[2] s[3] appartient a old*/
+      if(old == adja[j] / 4) {        
+         iadr = (nel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[3] = adj_a*4 + voy_a;
+         mesh->tetra[nel].bdryref[3] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = nel*4 + 3;
+         }
+      
+         iadr = (oel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[2] = adj_b*4 + voy_b;
+         mesh->tetra[oel].bdryref[2] = ref_b;
+          
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = oel*4 + 2;
+         }
+      } else {
+        iadr = (iel-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        j    = MMG_isar[iar][1];
+        adj  = adja[j] / 4;
+        voy  = adja[j] % 4;
+        pt1  = &mesh->tetra[adj];
+    
+       if(pt1->v[MMG_idir[voy][0]]==s[0]) {
+           j = MMG_idir[voy][0];
+       } else if(pt1->v[MMG_idir[voy][1]]==s[0]) {
+           j = MMG_idir[voy][1];
+       } else if(pt1->v[MMG_idir[voy][2]]==s[0]) {
+          j = MMG_idir[voy][2];
+       }
+
+       iadr = (adj-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       /*s[4] s[5] appartient a old*/
+       if(old == adja[j] / 4) {   
+         iadr = (pel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[pel].bdryref[1] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = pel*4 + 1; 
+         }
+      
+         iadr = (qel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[qel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = qel*4 + 1;
+         }
+      }
+      else {
+      /*s[3] s[4] appartient a old*/
+       iadr = (pel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[3] = adj_a*4 + voy_a;
+       mesh->tetra[pel].bdryref[3] = ref_a;
+       
+       if (adj_a) {
+         iadr = (adj_a-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_a] = pel*4 + 3;
+       }
+      
+       iadr = (qel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[2] = adj_b*4 + voy_b;
+       mesh->tetra[qel].bdryref[2] = ref_b;
+       
+       if (adj_b) {
+         iadr = (adj_b-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_b] = qel*4 + 2;
+       }     
+     }
+    }
+   }
+ }  
+ 
+   /*internal faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[1] = lel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[1] = mel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = jel*4 + 1;
+  adja[1] = nel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = kel*4 + 1;
+  adja[1] = oel*4 + 3;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = lel*4 + 1;
+  adja[1] = pel*4 + 2;	
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = mel*4 + 1;
+  adja[1] = qel*4 + 3; 
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = nel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = oel*4 + 1;
+  /* remove 6 old tetra */
+  for (k=1; k<=6; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = oel;
+  list->tetra[7] = pel;
+  list->tetra[8] = qel;
+  list->tetra[9] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(8);
+}
+
+int MMG_swap68_9(pMesh mesh,pSol sol,pList list){
+  pTetra pt1,pt,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[6],j;
+  int    jel,kel,lel,mel,nel,oel,pel,qel;
+  int    iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b;
+  short  voy,voy_a,voy_b;
+
+  if ( !MMG_zaldy4(&hed,21) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP689 IGNORED\n"); 
+  }   
+
+  
+  /*find points of polygone*/
+  iel  = list->tetra[1] / 6;
+  iar  = list->tetra[1] % 6;
+  if(!MMG_findpolygone(mesh,iel,iar,s)) return(0);
+  
+  pt  = &mesh->tetra[iel];  
+	for(i=0 ; i<6 ; i++) { 
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+  ref = pt->ref;
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+ 
+  /*create 8 tetras*/
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[3];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[4];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[6];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[7];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[8];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  /*external faces*/
+  /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2; 
+  }
+  
+  for(k=2 ; k<=6 ; k++) {    
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0 = &mesh->tetra[old];
+	  for(i=0 ; i<6 ; i++) {
+	  	MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+	  }
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4; 
+      ref_b  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+   
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    /*s[1] appartient a old */
+    if(old==(adja[MMG_isar[iar][0]]/4)) {
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_a*4 + voy_a; 
+      mesh->tetra[jel].bdryref[1] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 1;
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[1] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[1] = ref_b;
+       
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 1;
+      }
+      
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){
+      /*s[0] appartient a old*/
+      iadr = (nel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[nel].bdryref[2] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = nel*4 + 2; 
+      }
+      
+      iadr = (oel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[oel].bdryref[3] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = oel*4 + 3;
+      }
+    } else {
+      /*old n'est pas un voisin de iel*/
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      j    = MMG_isar[iar][0];
+      adj  = adja[j] / 4;
+      voy  = adja[j] % 4;
+      pt1  = &mesh->tetra[adj];
+    
+     if(pt1->v[MMG_idir[voy][0]]==s[1]) {
+         j = MMG_idir[voy][0];
+      } else if(pt1->v[MMG_idir[voy][1]]==s[1]) {
+         j = MMG_idir[voy][1];
+      } else if(pt1->v[MMG_idir[voy][2]]==s[1]) {
+         j = MMG_idir[voy][2];
+      }
+
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      /*s[2] s[3] appartient a old*/
+      if(old == adja[j] / 4) {        
+         iadr = (lel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[3] = adj_a*4 + voy_a;
+         mesh->tetra[lel].bdryref[3] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = lel*4 + 3;
+         }
+      
+         iadr = (mel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[2] = adj_b*4 + voy_b;
+         mesh->tetra[mel].bdryref[2] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = mel*4 + 2;
+         }
+      } else {
+        iadr = (iel-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        j    = MMG_isar[iar][1];
+        adj  = adja[j] / 4;
+        voy  = adja[j] % 4;
+        pt1  = &mesh->tetra[adj];
+    
+       if(pt1->v[MMG_idir[voy][0]]==s[0]) {
+           j = MMG_idir[voy][0];
+       } else if(pt1->v[MMG_idir[voy][1]]==s[0]) {
+           j = MMG_idir[voy][1];
+       } else if(pt1->v[MMG_idir[voy][2]]==s[0]) {
+          j = MMG_idir[voy][2];
+       }
+
+       iadr = (adj-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       /*s[4] s[5] appartient a old*/
+       if(old == adja[j] / 4) {   
+         iadr = (nel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[nel].bdryref[1] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = nel*4 + 1;
+         }
+      
+         iadr = (oel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[oel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = oel*4 + 1; 
+         }
+      }
+      else {
+      /*s[3] s[4] appartient a old*/
+       iadr = (lel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[1] = adj_a*4 + voy_a;
+       mesh->tetra[lel].bdryref[1] = ref_a;
+       
+       if (adj_a) {
+         iadr = (adj_a-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_a] = lel*4 + 1;
+       }
+      
+       iadr = (mel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[1] = adj_b*4 + voy_b;
+       mesh->tetra[mel].bdryref[1] = ref_b;
+       
+       if (adj_b) {
+         iadr = (adj_b-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_b] = mel*4 + 1; 
+       }    
+     }
+    }
+   }
+ }  
+ 
+   /*internal faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = pel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = qel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = pel*4 + 1;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = qel*4 + 1;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[3] = pel*4 + 2;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[2] = qel*4 + 3;
+
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = lel*4 + 2;
+  adja[2] = nel*4 + 3;
+  adja[3] = jel*4 + 2;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = mel*4 + 3;
+  adja[3] = oel*4 + 2;
+  adja[2] = kel*4 + 3;
+  /* remove 6 old tetra */
+  for (k=1; k<=6; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = oel;
+  list->tetra[7] = pel;
+  list->tetra[8] = qel;
+  list->tetra[9] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(8);
+}
+
+int MMG_swap68_10(pMesh mesh,pSol sol,pList list){ 
+  pTetra pt1,pt,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[6],j;
+  int    jel,kel,lel,mel,nel,oel,pel,qel;
+  int    iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b;
+  short  voy,voy_a,voy_b;
+
+  if ( !MMG_zaldy4(&hed,21) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP6810 IGNORED\n"); 
+  }   
+
+  
+  /*find points of polygone*/
+  iel  = list->tetra[1] / 6;
+  iar  = list->tetra[1] % 6;
+  if(!MMG_findpolygone(mesh,iel,iar,s)) return(0);
+  
+  pt  = &mesh->tetra[iel];  
+	for(i=0 ; i<6 ; i++) { 
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+  ref = pt->ref;
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+ 
+  /*create 8 tetras*/
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[2];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[3];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[4];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[5];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[6];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[8];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  /*external faces*/
+  /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3; 
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;  
+  }
+  
+  for(k=2 ; k<=6 ; k++) {    
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0 = &mesh->tetra[old];
+	  for(i=0 ; i<6 ; i++) {
+	  	MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+	  }
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4; 
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4; 
+      ref_b  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+   
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    /*s[1] appartient a old */
+    if(old==(adja[MMG_isar[iar][0]]/4)) {
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_a*4 + voy_a;
+      mesh->tetra[jel].bdryref[3] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 3;
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[2] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 2;
+      }
+      
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){
+      /*s[0] appartient a old*/
+      iadr = (pel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[pel].bdryref[2] = ref_a;
+        
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = pel*4 + 2;
+      }
+      
+      iadr = (qel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[qel].bdryref[3] = ref_b;
+       
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = qel*4 + 3;
+      }
+    } else {
+      /*old n'est pas un voisin de iel*/
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      j    = MMG_isar[iar][0];
+      adj  = adja[j] / 4;
+      voy  = adja[j] % 4;
+      pt1  = &mesh->tetra[adj];
+    
+     if(pt1->v[MMG_idir[voy][0]]==s[1]) {
+         j = MMG_idir[voy][0];
+      } else if(pt1->v[MMG_idir[voy][1]]==s[1]) {
+         j = MMG_idir[voy][1];
+      } else if(pt1->v[MMG_idir[voy][2]]==s[1]) {
+         j = MMG_idir[voy][2];
+      }
+
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      /*s[2] s[3] appartient a old*/
+      if(old == adja[j] / 4) {        
+         iadr = (jel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[jel].bdryref[1] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = jel*4 + 1;
+         }
+      
+         iadr = (kel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[kel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = kel*4 + 1;
+         }
+      } else {
+        iadr = (iel-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        j    = MMG_isar[iar][1];
+        adj  = adja[j] / 4;
+        voy  = adja[j] % 4;
+        pt1  = &mesh->tetra[adj];
+    
+       if(pt1->v[MMG_idir[voy][0]]==s[0]) {
+           j = MMG_idir[voy][0];
+       } else if(pt1->v[MMG_idir[voy][1]]==s[0]) {
+           j = MMG_idir[voy][1];
+       } else if(pt1->v[MMG_idir[voy][2]]==s[0]) {
+          j = MMG_idir[voy][2];
+       }
+
+       iadr = (adj-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       /*s[4] s[5] appartient a old*/
+       if(old == adja[j] / 4) {   
+         iadr = (pel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[pel].bdryref[1] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = pel*4 + 1;
+         }
+      
+         iadr = (qel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[qel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = qel*4 + 1; 
+         }
+      }
+      else {
+      /*s[3] s[4] appartient a old*/
+       iadr = (lel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[1] = adj_a*4 + voy_a;
+       mesh->tetra[lel].bdryref[1] = ref_a;
+       
+       if (adj_a) {
+         iadr = (adj_a-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_a] = lel*4 + 1;
+       }
+      
+       iadr = (mel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[1] = adj_b*4 + voy_b;
+       mesh->tetra[mel].bdryref[1] = ref_b;
+       
+       if (adj_b) {
+         iadr = (adj_b-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_b] = mel*4 + 1; 
+       }    
+     }
+    }
+   }
+ }  
+ 
+   /*internal faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[3] = jel*4 + 2;
+  adja[2] = nel*4 + 1;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[2] = kel*4 + 3;
+  adja[3] = oel*4 + 1;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[1] = lel*4 + 2;
+  adja[2] = pel*4 + 3;	
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[1] = mel*4 + 3;
+  adja[3] = qel*4 + 2; 
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[3] = nel*4 + 2;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[2] = oel*4 + 3;
+  /* remove 6 old tetra */
+  for (k=1; k<=6; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = oel;
+  list->tetra[7] = pel;
+  list->tetra[8] = qel;
+  list->tetra[9] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(8);
+}
+
+int MMG_swap68_11(pMesh mesh,pSol sol,pList list){ 
+  pTetra pt1,pt,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[6],j;
+  int    jel,kel,lel,mel,nel,oel,pel,qel;
+  int    iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b;
+  short  voy,voy_a,voy_b;
+
+  if ( !MMG_zaldy4(&hed,21) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP6811 IGNORED\n"); 
+  }   
+
+  
+  /*find points of polygone*/
+  iel  = list->tetra[1] / 6;
+  iar  = list->tetra[1] % 6;
+  if(!MMG_findpolygone(mesh,iel,iar,s)) return(0);
+  
+  pt  = &mesh->tetra[iel];  
+	for(i=0 ; i<6 ; i++) { 
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+  ref = pt->ref;
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+ 
+  /*create 8 tetras*/
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[2];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[3];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[4];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[6];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[8];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  /*external faces*/
+  /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3; 
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2; 
+  }
+  
+  for(k=2 ; k<=6 ; k++) {    
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0 = &mesh->tetra[old];
+	  for(i=0 ; i<6 ; i++) {
+	  	MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+	  }
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4; 
+      ref_b  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+   
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    /*s[1] appartient a old */
+    if(old==(adja[MMG_isar[iar][0]]/4)) {
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_a*4 + voy_a; 
+      mesh->tetra[jel].bdryref[3] = ref_a; 
+       
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 3;
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[2] = ref_b; 
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 2; 
+      }
+      
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){
+      /*s[0] appartient a old*/
+      iadr = (pel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[pel].bdryref[2] = ref_a; 
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = pel*4 + 2;
+      }
+      
+      iadr = (qel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[qel].bdryref[3] = ref_b; 
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = qel*4 + 3;
+      }
+    } else {
+      /*old n'est pas un voisin de iel*/
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      j    = MMG_isar[iar][0];
+      adj  = adja[j] / 4;
+      voy  = adja[j] % 4;
+      pt1  = &mesh->tetra[adj];
+    
+     if(pt1->v[MMG_idir[voy][0]]==s[1]) {
+         j = MMG_idir[voy][0];
+      } else if(pt1->v[MMG_idir[voy][1]]==s[1]) {
+         j = MMG_idir[voy][1];
+      } else if(pt1->v[MMG_idir[voy][2]]==s[1]) {
+         j = MMG_idir[voy][2];
+      }
+
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      /*s[2] s[3] appartient a old*/
+      if(old == adja[j] / 4) {        
+         iadr = (jel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[jel].bdryref[1] = ref_a; 
+        
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = jel*4 + 1;
+         }
+      
+         iadr = (kel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[kel].bdryref[1] = ref_b; 
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = kel*4 + 1; 
+         }
+      } else {
+        iadr = (iel-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        j    = MMG_isar[iar][1];
+        adj  = adja[j] / 4;
+        voy  = adja[j] % 4;
+        pt1  = &mesh->tetra[adj];
+    
+       if(pt1->v[MMG_idir[voy][0]]==s[0]) {
+           j = MMG_idir[voy][0];
+       } else if(pt1->v[MMG_idir[voy][1]]==s[0]) {
+           j = MMG_idir[voy][1];
+       } else if(pt1->v[MMG_idir[voy][2]]==s[0]) {
+          j = MMG_idir[voy][2];
+       }
+
+       iadr = (adj-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       /*s[4] s[5] appartient a old*/
+       if(old == adja[j] / 4) {   
+         iadr = (nel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[nel].bdryref[1] = ref_a; 
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = nel*4 + 1;
+         }
+      
+         iadr = (oel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[oel].bdryref[1] = ref_b; 
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = oel*4 + 1;
+         }
+      }
+      else {
+      /*s[3] s[4] appartient a old*/
+       iadr = (lel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[1] = adj_a*4 + voy_a;
+       mesh->tetra[lel].bdryref[1] = ref_a; 
+       
+       if (adj_a) {
+         iadr = (adj_a-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_a] = lel*4 + 1;
+       }
+      
+       iadr = (mel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[1] = adj_b*4 + voy_b;
+       mesh->tetra[mel].bdryref[1] = ref_b; 
+       
+       if (adj_b) {
+         iadr = (adj_b-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_b] = mel*4 + 1;
+       }     
+     }
+    }
+   }
+ }  
+ 
+   /*internal faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[3] = jel*4 + 2;
+  adja[2] = nel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[2] = kel*4 + 3;
+  adja[3] = oel*4 + 2;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[3] = lel*4 + 2;
+  adja[2] = pel*4 + 1;	
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[2] = mel*4 + 3;
+  adja[3] = qel*4 + 1; 
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = nel*4 + 2;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = oel*4 + 3;
+  /* remove 6 old tetra */
+  for (k=1; k<=6; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = oel;
+  list->tetra[7] = pel;
+  list->tetra[8] = qel;
+  list->tetra[9] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(8);
+}
+
+int MMG_swap68_12(pMesh mesh,pSol sol,pList list){ 
+  pTetra pt1,pt,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[6],j;
+  int    jel,kel,lel,mel,nel,oel,pel,qel;
+  int    iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b;
+  short  voy,voy_a,voy_b;
+
+  if ( !MMG_zaldy4(&hed,21) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP6812 IGNORED\n"); 
+  }   
+
+  
+  /*find points of polygone*/
+  iel  = list->tetra[1] / 6;
+  iar  = list->tetra[1] % 6;
+  if(!MMG_findpolygone(mesh,iel,iar,s)) return(0);
+  
+  pt  = &mesh->tetra[iel];  
+	for(i=0 ; i<6 ; i++) { 
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+  ref = pt->ref;
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+ 
+  /*create 8 tetras*/
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[3];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[4];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[5];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[6];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[7];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[8];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  /*external faces*/
+  /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3; 
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;  
+  }
+  
+  for(k=2 ; k<=6 ; k++) {    
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0 = &mesh->tetra[old];
+	  for(i=0 ; i<6 ; i++) {
+	  	MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+	  }
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4; 
+      ref_b  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+   
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    /*s[1] appartient a old */
+    if(old==(adja[MMG_isar[iar][0]]/4)) {
+      iadr = (nel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_a*4 + voy_a;
+      mesh->tetra[nel].bdryref[3] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = nel*4 + 3;
+      }
+      
+      iadr = (oel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_b*4 + voy_b;
+      mesh->tetra[oel].bdryref[2] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = oel*4 + 2;  
+      }
+      
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){
+      /*s[0] appartient a old*/
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[jel].bdryref[2] = ref_a;
+       
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 2; 
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[3] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 3;
+      }
+    } else {
+      /*old n'est pas un voisin de iel*/
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      j    = MMG_isar[iar][0];
+      adj  = adja[j] / 4;
+      voy  = adja[j] % 4;
+      pt1  = &mesh->tetra[adj];
+    
+     if(pt1->v[MMG_idir[voy][0]]==s[1]) {
+         j = MMG_idir[voy][0];
+      } else if(pt1->v[MMG_idir[voy][1]]==s[1]) {
+         j = MMG_idir[voy][1];
+      } else if(pt1->v[MMG_idir[voy][2]]==s[1]) {
+         j = MMG_idir[voy][2];
+      }
+
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      /*s[2] s[3] appartient a old*/
+      if(old == adja[j] / 4) {        
+         iadr = (pel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[3] = adj_a*4 + voy_a;
+         mesh->tetra[pel].bdryref[3] = ref_a;
+          
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = pel*4 + 3;
+         }
+      
+         iadr = (qel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[2] = adj_b*4 + voy_b;
+         mesh->tetra[qel].bdryref[2] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = qel*4 + 2; 
+         }
+      } else {
+        iadr = (iel-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        j    = MMG_isar[iar][1];
+        adj  = adja[j] / 4;
+        voy  = adja[j] % 4;
+        pt1  = &mesh->tetra[adj];
+    
+       if(pt1->v[MMG_idir[voy][0]]==s[0]) {
+           j = MMG_idir[voy][0];
+       } else if(pt1->v[MMG_idir[voy][1]]==s[0]) {
+           j = MMG_idir[voy][1];
+       } else if(pt1->v[MMG_idir[voy][2]]==s[0]) {
+          j = MMG_idir[voy][2];
+       }
+
+       iadr = (adj-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       /*s[4] s[5] appartient a old*/
+       if(old == adja[j] / 4) {   
+         iadr = (lel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[lel].bdryref[1] = ref_a;
+          
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = lel*4 + 1;
+         }
+      
+         iadr = (mel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[mel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = mel*4 + 1;
+         }
+      }
+      else {
+      /*s[3] s[4] appartient a old*/
+       iadr = (pel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[1] = adj_a*4 + voy_a;
+       mesh->tetra[pel].bdryref[1] = ref_a;
+       
+       if (adj_a){
+         iadr = (adj_a-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_a] = pel*4 + 1;   
+       }
+      
+       iadr = (qel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[1] = adj_b*4 + voy_b;
+       mesh->tetra[qel].bdryref[1] = ref_b;
+       
+       if (adj_b) {
+         iadr = (adj_b-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_b] = qel*4 + 1;
+       }     
+     }
+    }
+   }
+ }  
+ 
+   /*internal faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[1] = lel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[1] = mel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = jel*4 + 1;
+  adja[3] = nel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = kel*4 + 1;
+  adja[2] = oel*4 + 3;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = lel*4 + 3;
+  adja[1] = pel*4 + 2;	
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = mel*4 + 2;
+  adja[1] = qel*4 + 3; 
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = nel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = oel*4 + 1;
+  /* remove 6 old tetra */
+  for (k=1; k<=6; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = oel;
+  list->tetra[7] = pel;
+  list->tetra[8] = qel;
+  list->tetra[9] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(8);
+}
+
+int MMG_swap68_13(pMesh mesh,pSol sol,pList list){ 
+  pTetra pt1,pt,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[6],j;
+  int    jel,kel,lel,mel,nel,oel,pel,qel;
+  int    iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b;
+  short  voy,voy_a,voy_b;
+
+  if ( !MMG_zaldy4(&hed,21) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP6813 IGNORED\n"); 
+  }   
+
+
+  /*find points of polygone*/
+  iel  = list->tetra[1] / 6;
+  iar  = list->tetra[1] % 6;
+  if(!MMG_findpolygone(mesh,iel,iar,s)) return(0);
+  
+  pt  = &mesh->tetra[iel];  
+	for(i=0 ; i<6 ; i++) { 
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+  ref = pt->ref;
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+ 
+  /*create 8 tetras*/
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[3];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[4];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[6];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[7];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[8];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  /*external faces*/
+  /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  
+  for(k=2 ; k<=6 ; k++) {    
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0 = &mesh->tetra[old];
+	  for(i=0 ; i<6 ; i++) {
+	  	MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+	  }
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4; 
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4; 
+      ref_b  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+   
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    /*s[1] appartient a old */
+    if(old==(adja[MMG_isar[iar][0]]/4)) {
+      iadr = (lel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_a*4 + voy_a;
+      mesh->tetra[lel].bdryref[3] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = lel*4 + 3;
+      }
+      
+      iadr = (mel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_b*4 + voy_b;
+      mesh->tetra[mel].bdryref[2] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = mel*4 + 2;
+      }
+      
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){
+      /*s[0] appartient a old*/
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[jel].bdryref[2] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 2;
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[3] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 3; 
+      }
+    } else {
+      /*old n'est pas un voisin de iel*/
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      j    = MMG_isar[iar][0];
+      adj  = adja[j] / 4;
+      voy  = adja[j] % 4;
+      pt1  = &mesh->tetra[adj];
+    
+     if(pt1->v[MMG_idir[voy][0]]==s[1]) {
+         j = MMG_idir[voy][0];
+      } else if(pt1->v[MMG_idir[voy][1]]==s[1]) {
+         j = MMG_idir[voy][1];
+      } else if(pt1->v[MMG_idir[voy][2]]==s[1]) {
+         j = MMG_idir[voy][2];
+      }
+
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      /*s[2] s[3] appartient a old*/
+      if(old == adja[j] / 4) {        
+         iadr = (pel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[3] = adj_a*4 + voy_a;
+         mesh->tetra[pel].bdryref[3] = ref_a;
+          
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = pel*4 + 3;
+         }
+      
+         iadr = (qel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[2] = adj_b*4 + voy_b;
+         mesh->tetra[qel].bdryref[2] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = qel*4 + 2;  
+         }
+      } else {
+        iadr = (iel-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        j    = MMG_isar[iar][1];
+        adj  = adja[j] / 4;
+        voy  = adja[j] % 4;
+        pt1  = &mesh->tetra[adj];
+    
+       if(pt1->v[MMG_idir[voy][0]]==s[0]) {
+           j = MMG_idir[voy][0];
+       } else if(pt1->v[MMG_idir[voy][1]]==s[0]) {
+           j = MMG_idir[voy][1];
+       } else if(pt1->v[MMG_idir[voy][2]]==s[0]) {
+          j = MMG_idir[voy][2];
+       }
+
+       iadr = (adj-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       /*s[4] s[5] appartient a old*/
+       if(old == adja[j] / 4) {   
+         iadr = (nel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[nel].bdryref[1] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = nel*4 + 1;
+         }
+      
+         iadr = (oel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[oel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = oel*4 + 1; 
+         }
+      }
+      else {
+      /*s[3] s[4] appartient a old*/
+       iadr = (pel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[1] = adj_a*4 + voy_a;
+       mesh->tetra[pel].bdryref[1] = ref_a;
+       
+       if (adj_a) {
+         iadr = (adj_a-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_a] = pel*4 + 1;
+       }
+      
+       iadr = (qel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[1] = adj_b*4 + voy_b;
+       mesh->tetra[qel].bdryref[1] = ref_b;
+       
+       if (adj_b) {
+         iadr = (adj_b-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_b] = qel*4 + 1;
+       }     
+     }
+    }
+   }
+ }  
+ 
+   /*internal faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[1] = lel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[1] = mel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = jel*4 + 1;
+  adja[1] = nel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = kel*4 + 1;
+  adja[1] = oel*4 + 3;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = lel*4 + 1;
+  adja[3] = pel*4 + 2;	
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = mel*4 + 1;
+  adja[2] = qel*4 + 3; 
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = nel*4 + 3;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = oel*4 + 2;
+  /* remove 6 old tetra */
+  for (k=1; k<=6; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = oel;
+  list->tetra[7] = pel;
+  list->tetra[8] = qel;
+  list->tetra[9] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(8);
+}
+
+int MMG_swap68_14(pMesh mesh,pSol sol,pList list){ 
+  pTetra pt1,pt,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[6],j;
+  int    jel,kel,lel,mel,nel,oel,pel,qel;
+  int    iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b;
+  short  voy,voy_a,voy_b;
+
+  if ( !MMG_zaldy4(&hed,21) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP6814 IGNORED\n"); 
+  }   
+
+  
+  /*find points of polygone*/
+  iel  = list->tetra[1] / 6;
+  iar  = list->tetra[1] % 6;
+  if(!MMG_findpolygone(mesh,iel,iar,s)) return(0);
+  
+  pt  = &mesh->tetra[iel];  
+	for(i=0 ; i<6 ; i++) { 
+		MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]);
+	}
+  ref = pt->ref;
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+ 
+  /*create 8 tetras*/
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[1];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[3];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[4];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[6];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->flag = mesh->flag;
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[8];
+  pt1->flag = mesh->flag; 
+  pt1->ref  = ref;
+  
+  /*external faces*/
+  /*tetra iel*/
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_iare[iar][0];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k];
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;  
+  }
+  
+  for(k=2 ; k<=6 ; k++) {    
+    old  = list->tetra[k] / 6;
+    iadr = (old-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+
+    pt0 = &mesh->tetra[old];
+	  for(i=0 ; i<6 ; i++) {
+	  	MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+	  }
+    iarold = list->tetra[k] % 6;
+    kk    = MMG_iare[iarold][1];
+    if(pt0->v[kk]==ib) {
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;  
+      ref_a  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4;
+      ref_b  = pt0->bdryref[kk];
+    } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{
+      adj_b  = adja[kk] / 4;
+      voy_b  = adja[kk] % 4; 
+      ref_b  = pt0->bdryref[kk];
+      kk    = MMG_iare[iarold][0];
+      adj_a  = adja[kk] / 4;
+      voy_a  = adja[kk] % 4;
+      ref_a  = pt0->bdryref[kk];
+    } 
+   
+    iadr = (iel-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    /*s[1] appartient a old */
+    if(old==(adja[MMG_isar[iar][0]]/4)) {
+      iadr = (lel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_a*4 + voy_a;
+      mesh->tetra[lel].bdryref[3] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = lel*4 + 3;  
+      }
+      
+      iadr = (mel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_b*4 + voy_b;
+      mesh->tetra[mel].bdryref[2] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = mel*4 + 2;
+      }
+      
+    } else if(old==(adja[MMG_isar[iar][1]]/4)){
+      /*s[0] appartient a old*/
+      iadr = (jel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[2] = adj_a*4 + voy_a;
+      mesh->tetra[jel].bdryref[2] = ref_a;
+      
+      if (adj_a) {
+        iadr = (adj_a-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_a] = jel*4 + 2; 
+      }
+      
+      iadr = (kel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      adja[3] = adj_b*4 + voy_b;
+      mesh->tetra[kel].bdryref[3] = ref_b;
+      
+      if (adj_b) {
+        iadr = (adj_b-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        adja[voy_b] = kel*4 + 3; 
+      }
+    } else {
+      /*old n'est pas un voisin de iel*/
+      iadr = (iel-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      j    = MMG_isar[iar][0];
+      adj  = adja[j] / 4;
+      voy  = adja[j] % 4;
+      pt1  = &mesh->tetra[adj];
+    
+     if(pt1->v[MMG_idir[voy][0]]==s[1]) {
+         j = MMG_idir[voy][0];
+      } else if(pt1->v[MMG_idir[voy][1]]==s[1]) {
+         j = MMG_idir[voy][1];
+      } else if(pt1->v[MMG_idir[voy][2]]==s[1]) {
+         j = MMG_idir[voy][2];
+      }
+
+      iadr = (adj-1)*4 + 1;
+      adja = &mesh->adja[iadr];
+      /*s[2] s[3] appartient a old*/
+      if(old == adja[j] / 4) {        
+         iadr = (lel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[lel].bdryref[1] = ref_a;
+         
+         if (adj_a) {
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = lel*4 + 1;
+         }
+      
+         iadr = (mel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[mel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = mel*4 + 1;
+         }
+      } else {
+        iadr = (iel-1)*4 + 1;
+        adja = &mesh->adja[iadr];
+        j    = MMG_isar[iar][1];
+        adj  = adja[j] / 4;
+        voy  = adja[j] % 4;
+        pt1  = &mesh->tetra[adj];
+    
+       if(pt1->v[MMG_idir[voy][0]]==s[0]) {
+           j = MMG_idir[voy][0];
+       } else if(pt1->v[MMG_idir[voy][1]]==s[0]) {
+           j = MMG_idir[voy][1];
+       } else if(pt1->v[MMG_idir[voy][2]]==s[0]) {
+          j = MMG_idir[voy][2];
+       }
+
+       iadr = (adj-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       /*s[4] s[5] appartient a old*/
+       if(old == adja[j] / 4) {   
+         iadr = (nel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_a*4 + voy_a;
+         mesh->tetra[nel].bdryref[1] = ref_a;
+         
+         if (adj_a) { 
+           iadr = (adj_a-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_a] = nel*4 + 1;
+         }
+      
+         iadr = (oel-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[1] = adj_b*4 + voy_b;
+         mesh->tetra[oel].bdryref[1] = ref_b;
+         
+         if (adj_b) {
+           iadr = (adj_b-1)*4 + 1;
+           adja = &mesh->adja[iadr];
+           adja[voy_b] = oel*4 + 1;   
+         }
+      }
+      else {
+      /*s[3] s[4] appartient a old*/
+       iadr = (nel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[3] = adj_a*4 + voy_a;
+       mesh->tetra[nel].bdryref[3] = ref_a;
+       
+       if (adj_a) {
+         iadr = (adj_a-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_a] = nel*4 + 3;
+       }
+      
+       iadr = (oel-1)*4 + 1;
+       adja = &mesh->adja[iadr];
+       adja[2] = adj_b*4 + voy_b;
+       mesh->tetra[oel].bdryref[2] = ref_b;
+       
+       if (adj_b) {
+         iadr = (adj_b-1)*4 + 1;
+         adja = &mesh->adja[iadr];
+         adja[voy_b] = oel*4 + 2;
+       }     
+     }
+    }
+   }
+ }  
+ 
+   /*internal faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[1] = pel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[1] = qel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = pel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = qel*4 + 2;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = pel*4 + 1;
+
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = qel*4 + 1;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = nel*4 + 2;
+  adja[2] = jel*4 + 1;
+  adja[3] = lel*4 + 2;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = oel*4 + 3;
+  adja[3] = kel*4 + 1;
+  adja[2] = mel*4 + 3;
+  /* remove 6 old tetra */
+  for (k=1; k<=6; k++)
+    MMG_delElt(mesh,list->tetra[k]/6);
+
+  list->tetra[1] = jel;
+  list->tetra[2] = kel;
+  list->tetra[3] = lel;
+  list->tetra[4] = mel;
+  list->tetra[5] = nel;
+  list->tetra[6] = oel;
+  list->tetra[7] = pel;
+  list->tetra[8] = qel;
+  list->tetra[9] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(8);
+}
diff --git a/contrib/mmg3d/build/sources/swap710.c b/contrib/mmg3d/build/sources/swap710.c
new file mode 100644
index 0000000000000000000000000000000000000000..b58b84adf2794eb3310cea6a95e017afbf29d4aa
--- /dev/null
+++ b/contrib/mmg3d/build/sources/swap710.c
@@ -0,0 +1,19044 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+/*find points of polygone*/
+static int MMG_findpolygone(pMesh mesh,pList list,int *s) {
+  pTetra pt,pt1;
+  int ia,ib;
+  int j,iadr,*adja,k,adj,iar,iel;
+  short voy;
+ 
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+
+  /*find points of polygone*/
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+//  printf("MMG_swap edge %d %d\n",ia,ib);
+  s[0]  = pt->v[ MMG_isar[iar][0] ];
+  s[1]  = pt->v[ MMG_isar[iar][1] ]; 
+
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][0];
+  
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  for(j=0 ; j<6 ; j++)
+    if((ia == pt1->v[MMG_iare[j][0]] && ib ==pt1->v[MMG_iare[j][1]]) ||
+       (ia == pt1->v[MMG_iare[j][1]] && ib ==pt1->v[MMG_iare[j][0]])) break;
+  assert(j<6);
+  iar = j;
+  list->tetra[2] = 6*adj + iar;
+       
+  s[2]  = pt1->v[voy];
+
+  iadr = (adj-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  if(pt1->v[MMG_isar[iar][0]] == s[1]) {
+    k = MMG_isar[iar][0];
+  } else {
+    assert(pt1->v[MMG_isar[iar][1]] == s[1]);
+    k = MMG_isar[iar][1];
+  }
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  for(j=0 ; j<6 ; j++)
+    if((ia == pt1->v[MMG_iare[j][0]] && ib ==pt1->v[MMG_iare[j][1]]) ||
+       (ia == pt1->v[MMG_iare[j][1]] && ib ==pt1->v[MMG_iare[j][0]])) break;
+  assert(j<6);
+  iar = j;
+  list->tetra[3] = 6*adj + iar;
+  
+  s[3]   = pt1->v[voy];
+  iadr = (adj-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  if(pt1->v[MMG_isar[iar][0]] == s[2]) {
+    k = MMG_isar[iar][0];
+  } else {
+    assert(pt1->v[MMG_isar[iar][1]] == s[2]);
+    k = MMG_isar[iar][1];
+  }
+     
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  for(j=0 ; j<6 ; j++)
+    if((ia == pt1->v[MMG_iare[j][0]] && ib ==pt1->v[MMG_iare[j][1]]) ||
+       (ia == pt1->v[MMG_iare[j][1]] && ib ==pt1->v[MMG_iare[j][0]])) break;
+  assert(j<6);
+  iar = j;
+  list->tetra[4] = 6*adj + iar;
+  
+  s[4]   = pt1->v[voy];
+  iadr = (adj-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  if(pt1->v[MMG_isar[iar][0]] == s[3]) {
+    k = MMG_isar[iar][0];
+  } else {
+    assert(pt1->v[MMG_isar[iar][1]] == s[3]);
+    k = MMG_isar[iar][1];
+  }
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  for(j=0 ; j<6 ; j++)
+    if((ia == pt1->v[MMG_iare[j][0]] && ib ==pt1->v[MMG_iare[j][1]]) ||
+       (ia == pt1->v[MMG_iare[j][1]] && ib ==pt1->v[MMG_iare[j][0]])) break;
+  assert(j<6);
+  iar = j;
+  list->tetra[5] = 6*adj + iar;
+  
+  s[5]   = pt1->v[voy]; 
+  
+  iadr = (adj-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  if(pt1->v[MMG_isar[iar][0]] == s[4]) {
+    k = MMG_isar[iar][0];
+  } else {
+    assert(pt1->v[MMG_isar[iar][1]] == s[4]);
+    k = MMG_isar[iar][1];
+  }
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  for(j=0 ; j<6 ; j++)
+    if((ia == pt1->v[MMG_iare[j][0]] && ib ==pt1->v[MMG_iare[j][1]]) ||
+       (ia == pt1->v[MMG_iare[j][1]] && ib ==pt1->v[MMG_iare[j][0]])) break;
+  assert(j<6);
+  iar = j;
+  list->tetra[6] = 6*adj + j;
+    
+  iar  = list->tetra[1] % 6;  
+  iadr = (iel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  k    = MMG_isar[iar][1];
+  adj  = adja[k] / 4;
+  voy  = adja[k] % 4;
+  pt1  = &mesh->tetra[adj];
+  for(j=0 ; j<6 ; j++)
+    if((ia == pt1->v[MMG_iare[j][0]] && ib ==pt1->v[MMG_iare[j][1]]) ||
+       (ia == pt1->v[MMG_iare[j][1]] && ib ==pt1->v[MMG_iare[j][0]])) break;
+  assert(j<6);
+  list->tetra[7] = 6*adj + j;
+  
+  s[6]   = pt1->v[voy];
+  
+  return(1);
+}
+
+static int MMG_updatebdryinfo(pMesh mesh,pHedge hed,pList list) { 
+	pTetra  pt1;
+	int     iel,i,k;
+	
+	for(k=1 ; k<=10 ; k++) { 
+		iel = list->tetra[k];
+	  pt1 = &mesh->tetra[iel];
+	  for(i=0 ; i<6 ; i++) { 
+	  	pt1->bdryinfo[i] = MMG_edgePut(hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1);
+	  	if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0;
+	  }
+	}
+	
+	return(1);
+}
+
+int MMG_swap710_1(pMesh mesh,pSol sol,pList list){
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+  
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+	ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+     
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy; 
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;  
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy; 
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;  
+  mesh->tetra[rel].bdryref[1] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;  
+  mesh->tetra[sel].bdryref[1] = pt->bdryref[k1]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;  
+  mesh->tetra[rel].bdryref[2] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[3] = pt->bdryref[k1]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[3] = jel*4 + 2;
+  adja[2] = nel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[2] = kel*4 + 3;
+  adja[3] = oel*4 + 2;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[3] = lel*4 + 2;
+  adja[2] = pel*4 + 3;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[2] = mel*4 + 3;
+  adja[3] = qel*4 + 2;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[3] = nel*4 + 2;
+  adja[2] = rel*4 + 3;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[2] = oel*4 + 3;
+  adja[3] = sel*4 + 2;
+ 
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[3] = pel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[2] = qel*4 + 3; 
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);  
+
+}
+int MMG_swap710_2(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+	ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+ 
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy; 
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy; 
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy; 
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy; 
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;  
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy; 
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;   
+  mesh->tetra[sel].bdryref[3] = pt->bdryref[k1]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;  
+  mesh->tetra[rel].bdryref[1] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[1] = pt->bdryref[k1]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;   
+  mesh->tetra[pel].bdryref[2] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy; 
+  mesh->tetra[qel].bdryref[3] = pt->bdryref[k1]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[3] = jel*4 + 2;
+  adja[2] = nel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[2] = kel*4 + 3;
+  adja[3] = oel*4 + 2;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[3] = lel*4 + 2;
+  adja[2] = pel*4 + 3;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[2] = mel*4 + 3;
+  adja[3] = qel*4 + 2;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[3] = nel*4 + 2;
+  adja[1] = rel*4 + 2;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[2] = oel*4 + 3;
+  adja[1] = sel*4 + 3;
+ 
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[2] = pel*4 + 1;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[3] = qel*4 + 1; 
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);  
+
+}
+int MMG_swap710_3(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+ 
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[3];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[3] = jel*4 + 2;
+  adja[2] = rel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[2] = kel*4 + 3;
+  adja[3] = sel*4 + 2;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = pel*4 + 1;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = qel*4 + 1;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = nel*4 + 2;
+  adja[2] = rel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = oel*4 + 3;
+  adja[3] = sel*4 + 1;
+ 
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[3] = lel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[2] = mel*4 + 3;
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+  
+return(1);
+}
+int MMG_swap710_4(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+ 
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[3] = jel*4 + 2;
+  adja[2] = nel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[2] = kel*4 + 3;
+  adja[3] = oel*4 + 2;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[3] = lel*4 + 2;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[1] = qel*4 + 3;
+  adja[2] = mel*4 + 3;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = nel*4 + 1;
+  adja[3] = rel*4 + 2;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = oel*4 + 1;
+  adja[2] = sel*4 + 3;
+ 
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[2] = pel*4 + 3;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[3] = qel*4 + 2; 
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+ 
+return(1);
+}
+int MMG_swap710_5(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+ 
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[3];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+   iadr = (adj-1)*4 + 1;
+   adja = &mesh->adja[iadr];
+   adja[voy] = oel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[3] = jel*4 + 2;
+  adja[2] = rel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[2] = kel*4 + 3;
+  adja[3] = sel*4 + 2;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[2] = sel*4 + 3;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = rel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = sel*4 + 1;
+ 
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = nel*4 + 3;
+  adja[3] = lel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = oel*4 + 2;
+  adja[2] = mel*4 + 3;
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+return(1);
+}
+int MMG_swap710_6(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+ 
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[1];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  } 
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[3] = lel*4 + 2;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[2] = mel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = nel*4 + 3;
+  adja[3] = jel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = oel*4 + 2;
+  adja[2] = kel*4 + 3;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 3;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 2;
+  adja[2] = sel*4 + 3;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = rel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = sel*4 + 1;
+ 
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = jel*4 + 3;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = kel*4 + 2;
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+return(1);
+}
+int MMG_swap710_7(pMesh mesh,pSol sol,pList list){  
+ pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[4];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[1];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 3;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 2;
+  adja[2] = sel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[3] = jel*4 + 2;
+  adja[1] = nel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[2] = kel*4 + 3;
+  adja[1] = oel*4 + 3;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = lel*4 + 1;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = mel*4 + 1;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = rel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = sel*4 + 1;
+ 
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = jel*4 + 3;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = kel*4 + 2;
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+  
+return(1);
+}
+int MMG_swap710_8(pMesh mesh,pSol sol,pList list){  
+ pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[4];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[1];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 1;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 1;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[1] = jel*4 + 2;
+  adja[2] = nel*4 + 1;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[1] = kel*4 + 3;
+  adja[3] = oel*4 + 1;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[1] = lel*4 + 2;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[1] = mel*4 + 3;
+  adja[2] = sel*4 + 3;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = rel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = sel*4 + 1;
+ 
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = nel*4 + 3;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = oel*4 + 2;
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+return(1);
+}
+int MMG_swap710_9(pMesh mesh,pSol sol,pList list){
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+  
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+  
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+ 
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+  
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[1];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[1] = lel*4 + 2;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[1] = mel*4 + 3;
+  adja[2] = sel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = jel*4 + 1;
+  adja[3] = nel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = kel*4 + 1;
+  adja[2] = oel*4 + 3;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = lel*4 + 3;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = mel*4 + 2;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = rel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = sel*4 + 1;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[2] = jel*4 + 3;
+  adja[1] = pel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[3] = kel*4 + 2; 
+  adja[1] = qel*4 + 3;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+/*printf("new tets %d %d %d %d %d %d %d %d %d %d\n",jel,kel,lel,mel,nel,oel,pel,qel,rel,sel);
+  */list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+        
+  return(1);
+  
+}
+int MMG_swap710_10(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[1];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1; 
+  }  
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[3] = nel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[2] = oel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = nel*4 + 1;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = oel*4 + 1;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[1] = lel*4 + 2;
+  adja[2] = jel*4 + 3;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[1] = mel*4 + 3;
+  adja[3] = kel*4 + 2;
+  adja[2] = sel*4 + 3;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = rel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = sel*4 + 1;
+ 
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = nel*4 + 3;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = oel*4 + 2;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);  
+
+}
+int MMG_swap710_11(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[1];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3; 
+  }
+  
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2; 
+  }
+  
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  } 
+
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1; 
+  }
+  
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+    
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = rel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = sel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[1] = nel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[1] = oel*4 + 3;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = lel*4 + 1;
+  adja[3] = pel*4 + 2;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = mel*4 + 1;
+  adja[2] = qel*4 + 3;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = nel*4 + 3;
+  adja[3] = rel*4 + 2;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = oel*4 + 2;
+  adja[2] = sel*4 + 3;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[2] = pel*4 + 3;
+  adja[3] = jel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[3] = qel*4 + 2; 
+  adja[2] = kel*4 + 3;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);  
+
+}
+int MMG_swap710_12(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[2];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[1] = lel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[1] = mel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = jel*4 + 1;
+  adja[3] = nel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = kel*4 + 1;
+  adja[2] = oel*4 + 3;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = lel*4 + 3;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = mel*4 + 2;
+  adja[2] = sel*4 + 3;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = rel*4 + 1;
+ 
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = sel*4 + 1;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = nel*4 + 3;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = oel*4 + 2;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);  
+
+}
+int MMG_swap710_13(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+  
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[1] = lel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[1] = mel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = jel*4 + 1;
+  adja[3] = pel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = kel*4 + 1;
+  adja[2] = qel*4 + 3;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = rel*4 + 3;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = sel*4 + 2;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = rel*4 + 2;
+  adja[2] = lel*4 + 3;
+ 
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = sel*4 + 3;
+  adja[3] = mel*4 + 2;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[2] = pel*4 + 1;
+  adja[3] = nel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[3] = qel*4 + 1; 
+  adja[2] = oel*4 + 3;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);  
+
+}
+int MMG_swap710_14(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[1];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[3];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = rel*4 + 1;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = sel*4 + 1;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[1] = nel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[1] = oel*4 + 3;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = lel*4 + 1;
+  adja[3] = pel*4 + 2;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = mel*4 + 1;
+  adja[2] = qel*4 + 3;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = rel*4 + 2;
+  adja[2] = nel*4 + 3;
+ 
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = sel*4 + 3;
+  adja[3] = oel*4 + 2;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = jel*4 + 2;
+  adja[2] = pel*4 + 1;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = kel*4 + 3; 
+  adja[3] = qel*4 + 1;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);  
+}
+int MMG_swap710_15(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[3];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = rel*4 + 1;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = sel*4 + 1;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = rel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = sel*4 + 2;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[1] = pel*4 + 2;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[1] = qel*4 + 3;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = nel*4 + 1;
+  adja[3] = rel*4 + 2;
+ 
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = oel*4 + 1;
+  adja[2] = sel*4 + 3;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = jel*4 + 2;
+  adja[2] = pel*4 + 3;
+  adja[3] = lel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = kel*4 + 3; 
+  adja[3] = qel*4 + 2;  
+  adja[2] = mel*4 + 3;
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);  
+}
+int MMG_swap710_16(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[1];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+                                            
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[2] = sel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = pel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = qel*4 + 2;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = nel*4 + 3;
+  adja[3] = lel*4 + 2;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = oel*4 + 2;
+  adja[2] = mel*4 + 3;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = rel*4 + 1;
+  adja[3] = pel*4 + 2;
+ 
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = sel*4 + 1;
+  adja[2] = qel*4 + 3;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = nel*4 + 2;
+  adja[2] = jel*4 + 3;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = oel*4 + 3; 
+  adja[3] = kel*4 + 2;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);  
+}
+int MMG_swap710_17(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[1];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[2] = sel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = rel*4 + 1;
+  adja[3] = pel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = sel*4 + 1;
+  adja[2] = qel*4 + 3;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = pel*4 + 1;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = qel*4 + 1;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = nel*4 + 2;
+  adja[2] = lel*4 + 3;
+ 
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = oel*4 + 3;
+  adja[3] = mel*4 + 2;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = lel*4 + 2;
+  adja[2] = jel*4 + 3;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = mel*4 + 3; 
+  adja[3] = kel*4 + 2;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1); 
+}
+int MMG_swap710_18(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[1];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[2] = sel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = pel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = qel*4 + 2;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = rel*4 + 1;
+  adja[1] = pel*4 + 2;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = sel*4 + 1;
+  adja[1] = qel*4 + 3;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = nel*4 + 1;
+  adja[3] = lel*4 + 2;
+ 
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = oel*4 + 1;
+  adja[2] = mel*4 + 3;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = nel*4 + 2;
+  adja[2] = jel*4 + 3;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = oel*4 + 3; 
+  adja[3] = kel*4 + 2;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1); 
+}
+int MMG_swap710_19(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[1];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[2] = sel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = pel*4 + 1;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = qel*4 + 1;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = rel*4 + 1;
+  adja[1] = pel*4 + 2;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = sel*4 + 1;
+  adja[1] = qel*4 + 3;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = lel*4 + 2;
+  adja[2] = nel*4 + 1;
+ 
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = mel*4 + 3;
+  adja[3] = oel*4 + 1;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = nel*4 + 2;
+  adja[2] = jel*4 + 3;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = oel*4 + 3; 
+  adja[3] = kel*4 + 2;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1); 
+}
+
+int MMG_swap710_20(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[1];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[2] = sel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = pel*4 + 1;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = qel*4 + 1;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = pel*4 + 3;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = qel*4 + 2;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = lel*4 + 2;
+  adja[2] = rel*4 + 1;
+  adja[3] = nel*4 + 2;
+ 
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = mel*4 + 3;
+  adja[3] = sel*4 + 1;
+  adja[2] = oel*4 + 3;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = jel*4 + 3;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = kel*4 + 2;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1); 
+}
+int MMG_swap710_21(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[2];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt = &mesh->tetra[iel];
+  assert(  pt->v[k] == ib);
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = rel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = sel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = nel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = oel*4 + 2;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = pel*4 + 3;
+  adja[3] = lel*4 + 2;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = qel*4 + 2;
+  adja[2] = mel*4 + 3;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = rel*4 + 1;
+  adja[3] = nel*4 + 2;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = sel*4 + 1;
+  adja[2] = oel*4 + 3;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[3] = jel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[2] = kel*4 + 3;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);
+}
+int MMG_swap710_22(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = pel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = qel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = nel*4 + 1;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = oel*4 + 1;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[1] = lel*4 + 2;
+  adja[2] = rel*4 + 3;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[1] = mel*4 + 3;
+  adja[3] = sel*4 + 2;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = rel*4 + 2;
+  adja[3] = jel*4 + 2;
+ 
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = sel*4 + 3;
+  adja[2] = kel*4 + 3;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[2] = pel*4 + 1;
+  adja[3] = nel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[3] = qel*4 + 1; 
+  adja[2] = oel*4 + 3;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1); 
+}
+int MMG_swap710_23(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[3];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = pel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = qel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = rel*4 + 1;
+  adja[3] = nel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = sel*4 + 1;
+  adja[2] = oel*4 + 3;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = lel*4 + 3;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = mel*4 + 2;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = rel*4 + 2;
+  adja[3] = jel*4 + 2;
+ 
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = sel*4 + 3;
+  adja[2] = kel*4 + 3;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = lel*4 + 2;
+  adja[2] = pel*4 + 1;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = mel*4 + 3; 
+  adja[3] = qel*4 + 1;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);
+}
+int MMG_swap710_24(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[3];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = pel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = qel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = nel*4 + 1;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = oel*4 + 1;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[1] = lel*4 + 2;
+  adja[2] = rel*4 + 1;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[1] = mel*4 + 3;
+  adja[3] = sel*4 + 1;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = rel*4 + 2;
+  adja[3] = jel*4 + 2;
+ 
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = sel*4 + 3;
+  adja[2] = kel*4 + 3;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = nel*4 + 2;
+  adja[2] = pel*4 + 1;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = oel*4 + 3; 
+  adja[3] = qel*4 + 1;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);
+}
+int MMG_swap710_25(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[4];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = pel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = qel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = rel*4 + 1;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = sel*4 + 1;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = rel*4 + 3;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = sel*4 + 2;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = rel*4 + 2;
+  adja[3] = jel*4 + 2;
+ 
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = sel*4 + 3;
+  adja[2] = kel*4 + 3;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = lel*4 + 2;
+  adja[2] = pel*4 + 1;
+  adja[3] = nel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = mel*4 + 3; 
+  adja[3] = qel*4 + 1;  
+  adja[2] = oel*4 + 3;
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);
+}
+int MMG_swap710_26(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[2];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt = &mesh->tetra[iel];
+  assert(  pt->v[k] == ib);
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[1] = rel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[1] = sel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = nel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = oel*4 + 2;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = pel*4 + 3;
+  adja[3] = lel*4 + 2;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = qel*4 + 2;
+  adja[2] = mel*4 + 3;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = rel*4 + 1;
+  adja[3] = nel*4 + 2;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = sel*4 + 1;
+  adja[2] = oel*4 + 3;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = jel*4 + 1;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = kel*4 + 1;  
+  
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);  
+}
+int MMG_swap710_27(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+     
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+  
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[1];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = nel*4 + 1;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = oel*4 + 1;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[1] = pel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[1] = qel*4 + 3;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[1] = jel*4 + 2;
+  adja[2] = rel*4 + 3;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[1] = kel*4 + 3;
+  adja[3] = sel*4 + 2;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = rel*4 + 2;
+  adja[2] = lel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = sel*4 + 3;
+  adja[3] = mel*4 + 1;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[2] = pel*4 + 1;
+  adja[3] = nel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[3] = qel*4 + 1; 
+  adja[2] = oel*4 + 3;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+ 
+  return(1);
+}
+int MMG_swap710_28(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[2];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = pel*4 + 1;
+  adja[3] = lel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = qel*4 + 1;
+  adja[2] = mel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = jel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = kel*4 + 2;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[1] = rel*4 + 2;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[1] = sel*4 + 3;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = jel*4 + 2;
+  adja[2] = rel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = kel*4 + 3;
+  adja[3] = sel*4 + 1;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = nel*4 + 1;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = oel*4 + 1;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);
+}
+int MMG_swap710_29(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[4];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[2];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 1;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 1;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[1] = jel*4 + 2;
+  adja[2] = pel*4 + 1;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[1] = kel*4 + 3;
+  adja[3] = qel*4 + 1;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[1] = rel*4 + 2;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[1] = sel*4 + 3;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = lel*4 + 2;
+  adja[2] = rel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = mel*4 + 3;
+  adja[3] = sel*4 + 1;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = nel*4 + 1;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = oel*4 + 1;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);
+}
+int MMG_swap710_30(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[1];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[2];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k]; 
+
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = pel*4 + 1;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = qel*4 + 1;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[1] = rel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[1] = sel*4 + 3;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = pel*4 + 3;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = qel*4 + 2;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = jel*4 + 2;
+  adja[2] = rel*4 + 1;
+  adja[3] = nel*4 + 2;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = kel*4 + 3;
+  adja[3] = sel*4 + 1;
+  adja[2] = oel*4 + 3;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = lel*4 + 1;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = mel*4 + 1;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);
+}
+int MMG_swap710_31(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[3];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k]; 
+
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[2] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[3] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = rel*4 + 1;
+  adja[3] = lel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = sel*4 + 1;
+  adja[2] = mel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = jel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = kel*4 + 2;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = rel*4 + 3;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = sel*4 + 2;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = rel*4 + 2;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = sel*4 + 3;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = jel*4 + 2;
+  adja[2] = pel*4 + 1;
+  adja[3] = nel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = kel*4 + 3; 
+  adja[3] = qel*4 + 1;  
+  adja[2] = oel*4 + 3;
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);
+}
+int MMG_swap710_32(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[4];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[3];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k]; 
+
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[2] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[3] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 1;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 1;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[1] = jel*4 + 2;
+  adja[2] = rel*4 + 1;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[1] = kel*4 + 3;
+  adja[3] = sel*4 + 1;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = rel*4 + 3;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = sel*4 + 2;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = rel*4 + 2;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = sel*4 + 3;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = lel*4 + 2;
+  adja[2] = pel*4 + 1;
+  adja[3] = nel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = mel*4 + 3; 
+  adja[3] = qel*4 + 1;  
+  adja[2] = oel*4 + 3;
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);
+}
+int MMG_swap710_33(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[2];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = rel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = sel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = nel*4 + 3;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = oel*4 + 2;
+  adja[2] = sel*4 + 3;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[3] = lel*4 + 2;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[2] = mel*4 + 3;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = rel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = sel*4 + 1;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = lel*4 + 3;
+  adja[3] = jel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = mel*4 + 2;  
+  adja[2] = kel*4 + 3;
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);
+}
+int MMG_swap710_34(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[1];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 3;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 2;
+  adja[2] = sel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[3] = jel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[2] = kel*4 + 3;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = pel*4 + 1;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = qel*4 + 1;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = nel*4 + 2;
+  adja[2] = rel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = oel*4 + 3;
+  adja[3] = sel*4 + 1;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = jel*4 + 3;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = kel*4 + 2;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);
+}
+int MMG_swap710_35(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+  int    ia,ib,s[7];
+	Hedge			hed;
+  int    i,iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[1];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = lel*4 + 3;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = mel*4 + 2;
+  adja[2] = sel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[3] = jel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[2] = kel*4 + 3;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = pel*4 + 3;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = qel*4 + 2;
+ 
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[3] = nel*4 + 2;
+  adja[2] = rel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[2] = oel*4 + 3;
+  adja[3] = sel*4 + 1;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = jel*4 + 3;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = kel*4 + 2;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);
+}
+int MMG_swap710_36(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[4];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[2];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = rel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = sel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[1] = nel*4 + 2;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[1] = oel*4 + 3;
+  adja[2] = sel*4 + 3;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = lel*4 + 1;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = mel*4 + 1;
+ 
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = rel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = sel*4 + 1;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = lel*4 + 3;
+  adja[3] = jel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = mel*4 + 2;  
+  adja[2] = kel*4 + 3;
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+return(1);
+}
+int MMG_swap710_37(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[1];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; 
+
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; 
+  if (adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[1] = lel*4 + 2;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[1] = mel*4 + 3;
+  adja[2] = sel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = jel*4 + 1;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = kel*4 + 1;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = pel*4 + 1;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = qel*4 + 1;
+ 
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = nel*4 + 2;
+  adja[2] = rel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = oel*4 + 3;
+  adja[3] = sel*4 + 1;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = jel*4 + 3;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = kel*4 + 2;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+return(1);
+}
+int MMG_swap710_38(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[1];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; 
+
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = rel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; 
+
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = sel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[1] = lel*4 + 2;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[1] = mel*4 + 3;
+  adja[2] = sel*4 + 3;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = jel*4 + 1;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = kel*4 + 1;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = pel*4 + 3;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = qel*4 + 2;
+ 
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = rel*4 + 1;
+  adja[3] = nel*4 + 2;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = sel*4 + 1;
+  adja[2] = oel*4 + 3;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = jel*4 + 3;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = kel*4 + 2;  
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+return(1);  
+}
+int MMG_swap710_39(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[1];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[4];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k]; 
+
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = rel*4 + 1;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = sel*4 + 1;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[1] = rel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[1] = sel*4 + 3;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = pel*4 + 1;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = qel*4 + 1;
+ 
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = nel*4 + 2;
+  adja[2] = rel*4 + 3;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = oel*4 + 3;
+  adja[3] = sel*4 + 2;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = jel*4 + 2;
+  adja[2] = lel*4 + 1;
+  adja[3] = pel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = kel*4 + 3; 
+  adja[3] = mel*4 + 1;  
+  adja[2] = qel*4 + 3;
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+return(1);   
+}
+int MMG_swap710_40(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[4];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[3]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[2];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[6];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[1];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[4];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k]; 
+
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 2; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[2] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[3] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = rel*4 + 1;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = sel*4 + 1;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[2] = pel*4 + 3;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[3] = qel*4 + 2;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[1] = rel*4 + 2;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[1] = sel*4 + 3;
+ 
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[2] = rel*4 + 3;
+  adja[3] = lel*4 + 2;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[3] = sel*4 + 2;
+  adja[2] = mel*4 + 3;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = jel*4 + 2;
+  adja[2] = nel*4 + 1;
+  adja[3] = pel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = kel*4 + 3; 
+  adja[3] = oel*4 + 1;  
+  adja[2] = qel*4 + 3;
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+//MMG_chkmsh(mesh,1,0);
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+  return(1); 
+}
+int MMG_swap710_41(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[3];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[2];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = rel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = sel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[2] = sel*4 + 3;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = pel*4 + 1;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = qel*4 + 1;
+ 
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[1] = nel*4 + 2;
+  adja[2] = rel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[1] = oel*4 + 3;
+  adja[3] = sel*4 + 1;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = lel*4 + 3;
+  adja[3] = jel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = mel*4 + 2;  
+  adja[2] = kel*4 + 3;
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+  return(1);  
+}
+int MMG_swap710_42(pMesh mesh,pSol sol,pList list){  
+  pTetra pt,pt1,pt0;
+	Hedge			hed;
+  int    i,ia,ib,s[7];
+  int    iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar;
+  int    jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref;
+  short  voy;
+
+  if ( !MMG_zaldy4(&hed,25) ) {
+    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); 
+  }   
+
+  iel = list->tetra[1] / 6;
+  iar = list->tetra[1] % 6;
+  pt  = &mesh->tetra[iel];
+  ref = pt->ref; 
+  MMG_findpolygone(mesh,list,s);
+    
+  ia  = pt->v[ MMG_iare[iar][0] ];
+  ib  = pt->v[ MMG_iare[iar][1] ];
+
+  jel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[jel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[1];
+  pt1->v[3] = s[2];
+  pt1->qual = list->qual[1];
+  pt1->ref  = ref;
+
+  kel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[kel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[1];
+  pt1->qual = list->qual[2];
+  pt1->ref  = ref;
+
+  lel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[lel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[6]; 
+  pt1->qual = list->qual[3];
+  pt1->ref  = ref;
+  
+  mel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[mel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[6];
+  pt1->v[3] = s[5];    
+  pt1->qual = list->qual[4];
+  pt1->ref  = ref;
+  
+  nel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[nel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[3];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[5];
+  pt1->ref  = ref;
+  
+  oel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[oel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[3];
+  pt1->qual = list->qual[6];
+  pt1->ref  = ref;
+  
+  pel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[pel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[4];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[7];
+  pt1->ref  = ref;
+  
+  qel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[qel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[2];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[4];
+  pt1->qual = list->qual[8];
+  pt1->ref  = ref;
+  
+  rel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[rel];
+  pt1->v[0] = ia;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[2];
+  pt1->v[3] = s[5];
+  pt1->qual = list->qual[9];
+  pt1->ref  = ref;
+
+  sel = MMG_newElt(mesh);
+  pt1 = &mesh->tetra[sel];
+  pt1->v[0] = ib;
+  pt1->v[1] = s[0];
+  pt1->v[2] = s[5];
+  pt1->v[3] = s[2];	    
+  pt1->qual = list->qual[10];
+  pt1->ref  = ref;
+
+  /*adj of iel*/
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; 
+
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 3;
+  }
+  k    = MMG_iare[iar][0];
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; 
+
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 2;
+  }
+  /*adj list->tetra[2]*/
+  iel = list->tetra[2] / 6;
+  iar = list->tetra[2] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = jel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = kel*4 + 1; 
+  }
+  /*adj list->tetra[3]*/
+  iel = list->tetra[3] / 6;
+  iar = list->tetra[3] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  pt1 = &mesh->tetra[adj];
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 3;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  pt1 = &mesh->tetra[adj];
+   
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 2;
+  }  
+  /*adj list->tetra[4]*/
+  iel = list->tetra[4] / 6;
+  iar = list->tetra[4] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = nel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = oel*4 + 1;
+  }
+  /*adj list->tetra[5]*/
+  iel = list->tetra[5] / 6;
+  iar = list->tetra[5] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = pel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = qel*4 + 1; 
+  }
+  /*adj list->tetra[6]*/
+  iel = list->tetra[6] / 6;
+  pt = &mesh->tetra[iel];
+  iar = list->tetra[6] % 6;
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 1;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[1] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 1;
+  }
+  /*adj list->tetra[7]*/
+  iel = list->tetra[7] / 6;
+  iar = list->tetra[7] % 6;
+  pt = &mesh->tetra[iel];
+  iadr2 = (iel-1)*4 + 1;
+  adja2 = &mesh->adja[iadr2];
+  k    = MMG_iare[iar][1];
+  if(pt->v[k] == ib) 
+    k1 = MMG_iare[iar][0];
+  else {
+    k  = MMG_iare[iar][0];
+    k1 = MMG_iare[iar][1];
+  }
+  adj  = adja2[k] / 4;
+  voy  = adja2[k] % 4;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[2] = adj*4 + voy;
+  mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = lel*4 + 2;
+  }
+  adj  = adja2[k1] / 4;
+  voy  = adja2[k1] % 4;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[3] = adj*4 + voy;
+  mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; 
+  if(adj) {
+    iadr = (adj-1)*4 + 1;
+    adja = &mesh->adja[iadr];
+    adja[voy] = mel*4 + 3;
+  }
+  /*internals faces*/
+  iadr = (jel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = kel*4 + 0;
+  adja[2] = rel*4 + 3;
+  
+  iadr = (kel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = jel*4 + 0;
+  adja[3] = sel*4 + 2;
+  
+  iadr = (lel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = mel*4 + 0;
+  adja[3] = rel*4 + 2;
+  
+  iadr = (mel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = lel*4 + 0;
+  adja[2] = sel*4 + 3;
+    
+  iadr = (nel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = oel*4 + 0;
+  adja[2] = pel*4 + 3;
+  
+  iadr = (oel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = nel*4 + 0;
+  adja[3] = qel*4 + 2;
+ 
+  iadr = (pel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = qel*4 + 0;
+  adja[3] = nel*4 + 2;
+  adja[2] = rel*4 + 1;
+
+  iadr = (qel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = pel*4 + 0;
+  adja[2] = oel*4 + 3;
+  adja[3] = sel*4 + 1;
+
+  iadr = (rel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = sel*4 + 0;
+  adja[1] = pel*4 + 2;
+  adja[2] = lel*4 + 3;
+  adja[3] = jel*4 + 2;
+
+  iadr = (sel-1)*4 + 1;
+  adja = &mesh->adja[iadr];
+  adja[0] = rel*4 + 0;
+  adja[1] = qel*4 + 3; 
+  adja[3] = mel*4 + 2;  
+  adja[2] = kel*4 + 3;
+  
+  /* remove 7 old tetra */
+  for (k=1; k<=7; k++) { 
+		pt0 = &mesh->tetra[list->tetra[k]/6];
+		for(i=0 ; i<6 ; i++) {
+			MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]);
+		}
+    MMG_delElt(mesh,list->tetra[k]/6); 
+  }
+
+  list->tetra[1]  = jel;
+  list->tetra[2]  = kel;
+  list->tetra[3]  = lel;
+  list->tetra[4]  = mel;
+  list->tetra[5]  = nel;
+  list->tetra[6]  = oel;
+  list->tetra[7]  = pel;
+  list->tetra[8]  = qel;
+  list->tetra[9]  = rel;
+  list->tetra[10] = sel;
+  list->tetra[11] = 0;
+	MMG_updatebdryinfo(mesh,&hed,list);
+	M_free(hed.item);
+
+return(1);
+}
diff --git a/contrib/mmg3d/build/sources/swapar.c b/contrib/mmg3d/build/sources/swapar.c
new file mode 100644
index 0000000000000000000000000000000000000000..043f858142ece48b71c06f5cb72f5a635bfb1d5d
--- /dev/null
+++ b/contrib/mmg3d/build/sources/swapar.c
@@ -0,0 +1,106 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+int MMG_swapar(pMesh mesh,pSol sol,pQueue q,List *list,int lon,double crit,double declic) {
+  pTetra   pt;
+  int      i,l,jel,ncas,ddebug;
+
+  MMG_swpptr = 0;
+  ncas   = 0;
+  if ( !MMG_getnElt(mesh,10) )  return(-1);
+	if(0 && list->tetra[1]/6==144988) ddebug=1;
+	else ddebug=0;
+	
+  switch(lon) {
+  case 3:
+  	  ncas = MMG_simu32(mesh,sol,list,crit);
+    break;
+  case 4:
+  	  ncas = MMG_simu44(mesh,sol,list,crit); 
+    break;
+  case 5:
+  	  ncas = MMG_simu56(mesh,sol,list,crit);
+    break;
+  case 6:
+  	  ncas = MMG_simu68(mesh,sol,list,crit); 
+			if(ddebug) printf("on vient avec %d\n",list->tetra[1]/6);
+    break;
+  case 7:
+    ncas = MMG_simu710(mesh,sol,list,crit);
+    break;  
+  default:
+    return(0);
+  }
+
+  if ( ncas && MMG_swpptr ) {
+		if(ddebug) MMG_saveMesh(mesh,"avt.mesh");
+    for (l=1; l<=lon; l++) {
+      jel = list->tetra[l]/6;
+      pt  = &mesh->tetra[jel]; 
+			if(ddebug) {
+				printf("tet %d : %d %d %d %d -- %d %d %d %d %d %d\n",jel,pt->v[0],pt->v[1],pt->v[2],pt->v[3],
+					pt->bdryinfo[0],pt->bdryinfo[1],pt->bdryinfo[2],pt->bdryinfo[3],pt->bdryinfo[4],pt->bdryinfo[5]);
+			}     
+			MMG_kiudel(q,jel);
+    }
+    lon = MMG_swpptr(mesh,sol,list);
+    assert(lon);
+    if(!lon) return(0); 
+    
+    for (l=1; l<=lon; l++) {
+      jel = list->tetra[l];
+      pt  = &mesh->tetra[jel]; 
+      if ( pt->qual >= declic )  MMG_kiuput(q,jel);
+      for (i=0; i<4; i++)  mesh->point[pt->v[i]].flag = mesh->flag; 
+    }
+		if(ddebug) MMG_saveMesh(mesh,"sw.mesh");
+    return(1);
+  }
+
+  return(0);
+}
+
diff --git a/contrib/mmg3d/build/sources/swaptet.c b/contrib/mmg3d/build/sources/swaptet.c
new file mode 100644
index 0000000000000000000000000000000000000000..c9d75b00edd935bcc06ddb1d9949d194b6951db6
--- /dev/null
+++ b/contrib/mmg3d/build/sources/swaptet.c
@@ -0,0 +1,105 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+#define SCRIT    0.95
+
+int MMG_swaptet(pMesh mesh,pSol sol,pQueue queue,double declic,int iel) {
+  pTetra pt,pt1;
+  List   list;
+  double crit;
+  int    i,*adja,iadr,lon,ier,adj,j,jel;
+  char   tabar,done;
+  
+  pt = &mesh->tetra[iel];
+  if ( !pt->v[0] )  return(0);
+
+  /* mark internal edges */
+  tabar = 0;
+  iadr  = 4*(iel-1) + 1;
+  adja  = &mesh->adja[iadr];
+  for (i=0; i<4; i++) {
+    adj = adja[i] >> 2;
+    if ( !adj || pt->ref != mesh->tetra[adj].ref ) {
+      tabar |= 1 << MMG_iarf[i][0];
+      tabar |= 1 << MMG_iarf[i][1];
+      tabar |= 1 << MMG_iarf[i][2];
+    }
+  }
+  if ( tabar == ALL_BDRY )  return(0);
+  
+  /* MMG_swap for anisotropy */
+  done = 0;
+  for (i=0; i<6; i++) {
+    if ( tabar & 1<<i )  continue;
+
+    lon  = MMG_coquil(mesh,iel,i,&list);
+    if ( lon < 3 || lon > 7 )  continue;
+
+    /* qual crit */
+    crit = pt->qual;
+    for (j=2; j<=lon; j++) {
+      jel  = list.tetra[j] / 6;
+      pt1  = &mesh->tetra[jel];
+      crit = M_MAX(crit,pt1->qual);
+    }
+    crit *= SCRIT;
+
+    ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,declic);
+    if ( ier > 0 ) {
+      return(1);
+      break;
+    }
+    else if ( ier < 0 ) {
+      fprintf(stdout,"  ## UNABLE TO MMG_swap.\n");
+      return(-1);
+    }
+    
+  }
+  
+  return(0);
+ 
+}
diff --git a/contrib/mmg3d/build/sources/typelt.c b/contrib/mmg3d/build/sources/typelt.c
new file mode 100644
index 0000000000000000000000000000000000000000..659c8eb0337249bc138b09f277a98cd7a2a56b6a
--- /dev/null
+++ b/contrib/mmg3d/build/sources/typelt.c
@@ -0,0 +1,378 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+#define EPSVOL    0.001
+#define RAPMAX    0.25
+
+
+/* identify type of element :
+  ityp= 0: 4 faces bonnes          (elt ok)
+        1: 4 faces bonnes, vol nul (sliver)
+        2: 4 faces ok, vol nul+sommet proche face   (chapeau)
+        3: 3 faces bonnes, 1 obtuse    (aileron)
+        4: 2 faces bonnes, 2 faces aigu => 1 petite arete
+        5: 1 face bonne, 3 petites aretes
+        6: 2 faces grandes aretes, 2 faces petites iaretes
+        7: 4 faces grandes aretes 
+   item: bad entity
+*/
+
+
+/* nb face obtuse :    nb faces aigu : 
+ityp :  0: 0		0
+	1: 0		0
+	2: 0		0
+	3: 1		0
+	4: 0		2
+	5: 0		3
+	6: 2		2
+	7: 0		4
+*/
+/* nb gde arete :    nb petite arete : 
+ityp :  0: 0		0
+	1: 0		0
+	2: 0		0
+	3: 1		0
+	4: 0		1
+	5: 0		3
+	6: 1		1
+	7: 0		2
+*/
+
+int MMG_typelt(pMesh mesh,int iel,int *item) {
+  pTetra    pt;
+  pPoint    pa,pb,pc,pd;
+  double    abx,aby,abz,acx,acy,acz,adx,ady,adz,v1,v2,v3,vol;
+  double    bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz,h[6],volchk,ssmall;
+  double    s[4],dd,rapmin,rapmax,surmin,surmax;
+  int       i,k,ia,ib,ic,id,ityp,isur,isurmax,isurmin,iarmax,iarmin;
+  int       nobtus,naigu;
+  short     i0,i1,i2;
+
+  ityp = 0;
+  pt = &mesh->tetra[iel];
+  if ( !pt->v[0] )  return(-1);
+
+  ia = pt->v[0];
+  ib = pt->v[1];
+  ic = pt->v[2];
+  id = pt->v[3];
+  pa = &mesh->point[ia];
+  pb = &mesh->point[ib];
+  pc = &mesh->point[ic];
+  pd = &mesh->point[id];
+
+  /* volume */
+  abx = pb->c[0] - pa->c[0]; 
+  aby = pb->c[1] - pa->c[1]; 
+  abz = pb->c[2] - pa->c[2]; 
+
+  acx = pc->c[0] - pa->c[0]; 
+  acy = pc->c[1] - pa->c[1]; 
+  acz = pc->c[2] - pa->c[2]; 
+
+  adx = pd->c[0] - pa->c[0]; 
+  ady = pd->c[1] - pa->c[1]; 
+  adz = pd->c[2] - pa->c[2]; 
+
+  v1  = acy*adz - acz*ady;
+  v2  = acz*adx - acx*adz;
+  v3  = acx*ady - acy*adx;
+  vol = abx * v1 + aby * v2 + abz * v3;
+
+  /* max edge */
+  h[0] = abx*abx + aby*aby + abz*abz;
+  h[1] = acx*acx + acy*acy + acz*acz;
+  h[2] = adx*adx + ady*ady + adz*adz;
+
+  bcx = pc->c[0] - pb->c[0];
+  bcy = pc->c[1] - pb->c[1];
+  bcz = pc->c[2] - pb->c[2];
+
+  bdx = pd->c[0] - pb->c[0];
+  bdy = pd->c[1] - pb->c[1];
+  bdz = pd->c[2] - pb->c[2];
+
+  cdx = pd->c[0] - pc->c[0];
+  cdy = pd->c[1] - pc->c[1];
+  cdz = pd->c[2] - pc->c[2];
+
+  h[3] = bcx*bcx + bcy*bcy + bcz*bcz;
+  h[4] = bdx*bdx + bdy*bdy + bdz*bdz;
+  h[5] = cdx*cdx + cdy*cdy + cdz*cdz;
+
+  /* face areas */
+  dd = cdy*bdz - cdz*bdy; 
+  s[0] = dd * dd;
+  dd = cdz*bdx - cdx*bdz;
+  s[0] = s[0] + dd * dd;
+  dd = cdx*bdy - cdy*bdx;
+  s[0] = s[0] + dd * dd;
+  s[0] = sqrt(s[0]);
+
+  s[1] = sqrt(v1*v1 + v2*v2 + v3*v3);
+
+  dd = bdy*adz - bdz*ady;
+  s[2] = dd * dd;
+  dd = bdz*adx - bdx*adz;
+  s[2] = s[2] + dd * dd;
+  dd = bdx*ady - bdy*adx;
+  s[2] = s[2] + dd * dd;
+  s[2] = sqrt(s[2]);
+
+  dd = aby*acz - abz*acy;
+  s[3] = dd * dd;
+  dd = abz*acx - abx*acz;
+  s[3] = s[3] + dd * dd;
+  dd = abx*acy - aby*acx;
+  s[3] = s[3] + dd * dd;
+  s[3] = sqrt(s[3]);
+
+  /* classification */
+  rapmin = h[0];
+  rapmax = h[0];
+  iarmin = 0;
+  iarmax = 0;
+  for (i=1; i<6; i++) {
+    if ( h[i] < rapmin ) {
+      rapmin = h[i];
+      iarmin = i;
+    }
+    else if ( h[i] > rapmax ) {
+      rapmax = h[i];
+      iarmax = i;
+    }
+  }
+  rapmin = sqrt(rapmin);
+  rapmax = sqrt(rapmax);
+  volchk = EPSVOL * rapmin*rapmin*rapmin;
+
+  /* small volume: types 1,2,3,4 */
+  if ( vol < volchk ) {
+//puts("volume nul : type 1,2,3,4");
+    
+    ssmall = 0.4 * (s[0]+s[1]+s[2]+s[3]);
+    isur   = 0;
+    for (i=0; i<4; i++)
+      isur += s[i] > ssmall;
+
+    /* types 2,3 */
+    item[0] = iarmax;
+    item[1] = MMG_isar[iarmax][0];    
+    if ( isur == 1 ) {
+      surmin   = s[0];
+      isurmin = 0;
+      surmax   = s[0];
+      isurmax = 0;
+      for (i=1; i<4; i++) {
+        if ( s[i] < surmin ) {
+          surmin  = s[i];
+	  isurmin = i;
+	}  
+        else if ( s[i] > surmax ) {
+	  surmax  = s[i];
+	  isurmax = i;
+	}  
+      }
+      dd = surmin / surmax;
+      if ( dd < RAPMAX ) {
+        item[1] = MMG_isar[iarmax][0];
+        return(3);
+      }
+      else {
+        item[0] = isurmax;
+	item[1] = isurmin;
+        return(2);
+      }	
+    }
+
+    /* types 1 */
+    isur = 0;
+    if ( s[0]+s[1] > ssmall )  isur = 1;
+    if ( s[0]+s[2] > ssmall )  isur++;
+    if ( s[0]+s[3] > ssmall )  isur++;
+
+    if ( isur > 2 ) {
+      dd = rapmin / rapmax;
+      item[0] = iarmin;
+      item[1] = MMG_idir[iarmin][0];
+      if ( dd < 0.01 )  return(4);
+      if ( s[0]+s[1] > ssmall ) {
+        item[0] = 0;
+        return(1);
+      }
+      if ( s[0]+s[2] > ssmall ) {
+        item[0] = 1;
+        return(1);
+      }
+      if ( s[0]+s[3] > ssmall ) {
+        item[0] = 2;
+        return(1);
+      }
+    }
+    
+//puts("default");
+    item[0] = 0;
+    return(1);
+  }/*end chkvol*/
+
+ dd = rapmin / rapmax;
+  /* types 3,6,7 */
+ if ( dd < RAPMAX ) { /*ie une arete 4 fois plus gde qu'une autre*/
+    
+    for (i=0; i<6; i++)  h[i] = sqrt(h[i]);
+
+    nobtus = 0;
+    for (k=0; k<4; k++) {
+      for (i=0; i<3; i++) {
+        i0 = MMG_idir[k][i];
+        i1 = MMG_idir[k][MMG_inxt[i]];
+        i2 = MMG_idir[k][MMG_inxt[i+1]];
+        if ( h[i0]+h[i1] < 1.2*h[i2] ) {/*1.4 ie une face obtus*/
+	  nobtus++;
+          item[0] = i2;
+	  item[1] = MMG_idir[k][MMG_inxt[i+1]];
+        }
+      }
+    }
+    
+    switch(nobtus){
+      case 0 : 
+       break;
+      case 1: 
+       item[0] = iarmax;
+       item[1] = MMG_isar[iarmax][0];
+       return(3);
+      case 2:  
+       item[0] = iarmin;
+       item[1] = iarmax;
+       return(6);
+      default:
+       item[0] = iarmin;
+       item[1] = iarmax;
+//printf("default obtus %d\n",nobtus);
+       return(7);
+    }
+  }
+
+  /* type 4,5,7 */
+  else if ( dd < 0.7*RAPMAX ) {
+    naigu = 0;
+    for (k=0; k<4; k++) {
+      for (i=0; i<3; i++) {
+        i0 = MMG_idir[k][i];
+        i1 = MMG_idir[k][MMG_inxt[i]];
+        i2 = MMG_idir[k][MMG_inxt[i+1]];
+    	if ( h[i0]+h[i1] > 1.5*h[i2] )  naigu++;/*1.5*/
+      }
+    }
+    switch(naigu){
+      case 0 : 
+       break;
+      case 1: 
+       break;
+      case 2:  
+       item[0] = iarmin;
+       return(4);
+      case 3:
+/*#warning definir item*/
+       return(5);  
+      default:
+       item[0] = iarmin;
+       item[1] = iarmax;
+//printf("default aigu\n");
+       return(7);
+    }
+  }
+
+//   /* types 3,4,5,6,7 */
+//   else {
+//     isur = 0;
+//     for (i=0; i<6; i++) {
+//       if ( h[i] < 2.0*rapmin )  isur++;
+//     }
+// 
+//     switch(isur){
+//       case 2: 
+//        puts("2 aretes tres grande retourne 7");
+//        return(7);
+//       case 3:  return(5);
+//       case 1:
+//         for (k=0; k<4; k++) {
+//           for (i=0; i<3; i++) {
+//             i0 = MMG_idir[k][i];
+//             i1 = MMG_idir[k][i+1];
+//             i2 = MMG_idir[k][i+2];
+//             if ( h[i0]+h[i1] < 1.25*h[i2] )  return(6);
+//           }
+//         }
+// 	puts("on retourne 4 la");
+//         return(4);
+//     }
+//   }
+      
+//   surmin   = s[0];
+//   isurmin = 0;
+//   surmax   = s[0];
+//   isurmax = 0;
+//   for (i=1; i<4; i++) {
+//     if ( s[i] < surmin ) {
+//       surmin  = s[i];
+//       isurmin = i;
+//     }  
+//     else if ( s[i] > surmax ) {
+//       surmax  = s[i];
+//       isurmax = i;
+//     }  
+//   }
+// 
+//   item[0] = isurmax;
+//   item[1] = isurmin;
+  item[0] = 0;
+  //puts("default");
+  return(1);
+}
diff --git a/contrib/mmg3d/build/sources/zaldy.c b/contrib/mmg3d/build/sources/zaldy.c
new file mode 100644
index 0000000000000000000000000000000000000000..6bc7cd271c8688be93248d11cf1a177389e6d599
--- /dev/null
+++ b/contrib/mmg3d/build/sources/zaldy.c
@@ -0,0 +1,256 @@
+/****************************************************************************
+Logiciel initial: MMG3D Version 4.0
+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+Propriétaires :IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+diffusé sous les termes et conditions de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.  
+
+Ce fichier est une partie de MMG3D.
+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+suivant les termes de la licence publique générale de GNU
+Version 3 ou toute version ultérieure.
+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+Voir la licence publique générale de GNU pour plus de détails.
+MMG3D est diffusé en espérant qu’il sera utile, 
+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
+y compris les garanties de commercialisation ou 
+d’adaptation dans un but spécifique. 
+Reportez-vous à la licence publique générale de GNU pour plus de détails.
+Vous devez avoir reçu une copie de la licence publique générale de GNU 
+en même temps que ce document. 
+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+/****************************************************************************
+Initial software: MMG3D Version 4.0
+Co-authors: Cecile Dobrzynski et Pascal Frey.
+Owners: IPB - UPMC -INRIA.
+
+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+spread under the terms and conditions of the license GNU General Public License 
+as published Version 3, or (at your option) any later version.
+
+This file is part of MMG3D
+MMG3D is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+MMG3D is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
+****************************************************************************/
+#include "mesh.h"
+
+/* get new point address */
+int MMG_newPt(pMesh mesh,double c[3]) {
+  pPoint  ppt;
+  int     curpt;
+
+  if ( !mesh->npnil )  return(0);
+
+  curpt = mesh->npnil;
+  if ( mesh->npnil > mesh->np )  mesh->np = mesh->npnil;
+  ppt   = &mesh->point[curpt];
+  memcpy(ppt->c,c,3*sizeof(double));
+  ppt->tag   &= ~M_UNUSED;
+  mesh->npnil = ppt->tmp;
+  ppt->tmp    = 0;
+  ppt->flag   = mesh->flag;
+
+  return(curpt);
+}
+
+
+void MMG_delPt(pMesh mesh,int ip) {
+  pPoint   ppt;
+  ppt = &mesh->point[ip];
+  memset(ppt,0,sizeof(Point));
+  ppt->tag    = M_UNUSED;
+  ppt->tmp    = mesh->npnil;
+  mesh->npnil = ip;
+  if ( ip == mesh->np )  mesh->np--;
+}
+
+
+/* get new elt address */
+int MMG_newElt(pMesh mesh) {
+  int     curiel;
+
+  if ( !mesh->nenil ) {
+    fprintf(stdout,"  ## UNABLE TO ALLOCATE NEW ELEMENT.\n");
+    return(0);
+  }
+  curiel      = mesh->nenil;
+  if ( mesh->nenil > mesh->ne )  mesh->ne = mesh->nenil;
+  mesh->nenil = mesh->tetra[curiel].v[3];
+  mesh->tetra[curiel].v[3] = 0;
+
+  return(curiel);
+}
+
+
+void MMG_delElt(pMesh mesh,int iel) {
+  pTetra   pt;
+  int      iadr,i;
+
+  pt = &mesh->tetra[iel];
+  if ( !pt->v[0] ) {
+    fprintf(stdout,"  ## INVALID TETRA.\n");
+    return;
+  }
+  memset(pt,0,sizeof(Tetra));
+  pt->v[3] = mesh->nenil;
+  pt->qual = 0.0;
+  pt->edge = 0;
+	iadr = (iel-1)*4 + 1;
+  memset(&mesh->adja[iadr],0,4*sizeof(int));
+
+  mesh->nenil = iel;
+  if ( iel == mesh->ne )  mesh->ne--;
+}
+
+
+/* check if n elets available */
+int MMG_getnElt(pMesh mesh,int n) {
+  int     curiel;
+
+  if ( !mesh->nenil )  return(0);
+  curiel = mesh->nenil;
+  do {
+    curiel = mesh->tetra[curiel].v[3];
+  }
+  while (--n);
+
+  return(n == 0);
+}
+
+
+/* get new elt address */
+int MMG_newTria(pMesh mesh) {
+  int     curiel;
+
+  if ( !mesh->ntnil ) {
+    fprintf(stdout,"  ## UNABLE TO ALLOCATE NEW TRIANGLE.\n");
+    return(0);
+  }
+  curiel      = mesh->ntnil;
+  if ( mesh->ntnil > mesh->nt )  mesh->nt = mesh->ntnil;
+  mesh->ntnil = mesh->tria[curiel].v[2];
+  mesh->tria[curiel].v[2] = 0;
+
+  return(curiel);
+}
+
+
+void MMG_delTria(pMesh mesh,int iel) {
+  pTria    pt;
+
+  pt = &mesh->tria[iel];
+  if ( !pt->v[0] ) {
+    fprintf(stdout,"  ## INVALID TRIANGLE.\n");
+    return;
+  }
+  memset(pt,0,sizeof(Tria));
+  pt->v[2]    = mesh->ntnil;
+  mesh->ntnil = iel;
+  if ( iel == mesh->nt )  mesh->nt--;
+}
+
+
+/* allocate main structure */
+int MMG_zaldy(pMesh mesh) {
+  int     million = 1048576L;
+  int     k,npask;
+
+  if ( mesh->info.memory < 0 ) {
+    mesh->npmax = M_MAX(1.5*mesh->np,NPMAX);
+    mesh->nemax = M_MAX(1.5*mesh->ne,NEMAX);
+    mesh->ntmax = M_MAX(1.5*mesh->nt,NTMAX);
+  }
+  else {
+    /* point+tria+tets+adja+sol+bucket+queue */
+    int bytes = sizeof(Point)   + 0.2*sizeof(Tria) \
+              + 6*sizeof(Tetra) + 4*sizeof(int) \
+	      + sizeof(Sol) + sizeof(Displ) \
+	      + sizeof(int) + 5*sizeof(int);
+
+    npask = (double)mesh->info.memory / bytes * million;
+    mesh->npmax = M_MAX(1.5*mesh->np,npask);
+    mesh->nemax = M_MAX(1.5*mesh->ne,6*npask);
+    mesh->ntmax = M_MAX(1.5*mesh->nt,(int)(0.3*npask));
+  }
+
+  mesh->point = (pPoint)M_calloc(mesh->npmax+1,sizeof(Point),"MMG_zaldy.point");
+  assert(mesh->point);
+  mesh->tetra = (pTetra)M_calloc(mesh->nemax+1,sizeof(Tetra),"MMG_zaldy.tetra");
+  assert(mesh->tetra);
+  mesh->tria  = (pTria)M_calloc(mesh->ntmax+1,sizeof(Tria),"MMG_zaldy.tria");
+  assert(mesh->tria);
+  mesh->adja = (int*)M_calloc(4*mesh->nemax+5,sizeof(int),"MMG_zaldy.adja");
+  assert(mesh->adja);
+  mesh->disp = (pDispl)M_calloc(1,sizeof(Displ),"MMG_zaldy.displ");
+  assert(mesh->disp);
+  mesh->disp->mv = (double*)M_calloc(3*(mesh->npmax + 1),sizeof(double),"MMG_zaldy.displ");
+  assert(mesh->disp->mv);
+  mesh->disp->alpha = (short*)M_calloc(mesh->npmax+1,sizeof(short),"MMG_zaldy.displ");
+  assert(mesh->disp->alpha);
+
+  /* keep track of empty links */
+  mesh->npnil = mesh->np + 1;
+  mesh->nenil = mesh->ne + 1;
+
+  for (k=mesh->npnil; k<mesh->npmax-1; k++)
+    mesh->point[k].tmp  = k+1;
+
+  for (k=mesh->nenil; k<mesh->nemax-1; k++)
+    mesh->tetra[k].v[3] = k+1;
+
+  if ( mesh->nt ) {
+    mesh->ntnil = mesh->nt + 1;
+    for (k=mesh->ntnil; k<mesh->ntmax-1; k++)
+      mesh->tria[k].v[2] = k+1;
+  }
+
+  return(1);
+}
+
+
+/* sol structure */
+int MMG_zaldy3(pSol sol) {
+  if ( sol->npmax ) {
+    sol->met = (double*)M_calloc(sol->npmax+1,sol->offset*sizeof(double),"MMG_zaldy3");
+    assert(sol->met);
+    sol->metold = (double*)M_calloc(sol->npmax+1,sol->offset*sizeof(double),"MMG_zaldy3");
+    assert(sol->metold);
+  }
+
+  return(1);
+}
+
+
+/* edge structure for cavity */
+int MMG_zaldy4(pHedge hedg,int size) { 
+  int   k;
+
+  hedg->size  = size;
+  hedg->hnxt  = size;
+  hedg->nhmax = (int)(16*size);
+  hedg->item  = (hedge*)M_calloc(hedg->nhmax+1,sizeof(hedge),"MMG_zaldy4");
+  //assert(hedg->item);
+
+  for (k=size; k<hedg->nhmax; k++)
+    hedg->item[k].nxt = k+1;
+
+  return(1);
+}
+
+
+/* internal edges */
+int MMG_zaldy5() {
+  return(1);
+}
+
diff --git a/contrib/mpeg_encode/bframe.cpp b/contrib/mpeg_encode/bframe.cpp
index 72eecb2deb496d80801d07cb58f408173753d372..53a185dcd67339524459c0e29f59f9fb860c0dc3 100644
--- a/contrib/mpeg_encode/bframe.cpp
+++ b/contrib/mpeg_encode/bframe.cpp
@@ -117,7 +117,7 @@
  *==============*/
 
 #include "all.h"
-//#include <sys/param.h>
+#include <string.h>
 #include <assert.h>
 #include "mtypes.h"
 #include "bitio.h"
diff --git a/contrib/mpeg_encode/bitio.cpp b/contrib/mpeg_encode/bitio.cpp
index 69b5303dea2e9e2e70220e983e79749d04800465..1b78bff6a4d073a4bfb6844fd67d7798e88e3d05 100644
--- a/contrib/mpeg_encode/bitio.cpp
+++ b/contrib/mpeg_encode/bitio.cpp
@@ -82,6 +82,7 @@
 #include <assert.h>
 #include <time.h>
 #include <stdio.h>
+#include <string.h>
 #include "all.h"
 #include "byteorder.h"
 #include "bitio.h"
diff --git a/contrib/mpeg_encode/block.cpp b/contrib/mpeg_encode/block.cpp
index f977a93fd00c165465079c2df2414159b1cff3c6..9fa2f013f2a6fabd6b1d3a9fdd1fad3d1eaa8438 100644
--- a/contrib/mpeg_encode/block.cpp
+++ b/contrib/mpeg_encode/block.cpp
@@ -102,6 +102,7 @@
  * HEADER FILES *
  *==============*/
 
+#include <string.h>
 #include "all.h"
 #include "mtypes.h"
 #include "frames.h"
diff --git a/contrib/mpeg_encode/iframe.cpp b/contrib/mpeg_encode/iframe.cpp
index 2fe01e7ec7e58623ee4637ed6414e9e007e5a3a3..552c92489a563f862c982eda9d6405ba77079ddb 100644
--- a/contrib/mpeg_encode/iframe.cpp
+++ b/contrib/mpeg_encode/iframe.cpp
@@ -138,7 +138,7 @@
 
 
 #include <time.h>
-//#include <sys/param.h>
+#include <string.h>
 #include "all.h"
 #include "mtypes.h"
 #include "frames.h"
diff --git a/contrib/mpeg_encode/pframe.cpp b/contrib/mpeg_encode/pframe.cpp
index 37ccb98cfb21100226541ccce4d6b03a7ebdcc7c..7b6963d5198e747038e070b7ceeaed2b33b8ceb8 100644
--- a/contrib/mpeg_encode/pframe.cpp
+++ b/contrib/mpeg_encode/pframe.cpp
@@ -126,7 +126,7 @@
  *==============*/
 
 #include <assert.h>
-//#include <sys/param.h>
+#include <string.h>
 #include "all.h"
 #include "mtypes.h"
 #include "bitio.h"