From 75663a4902fa8ceb7b3a1bb0f8f68050132a05fc Mon Sep 17 00:00:00 2001
From: Jean-Francois Remacle <jean-francois.remacle@uclouvain.be>
Date: Thu, 9 Jun 2011 08:21:44 +0000
Subject: [PATCH] This is a big commit : do not hesitate to shout if a file is
 missing ;-)

The delquad algo is now much more stable and nice

Two 3D meshers have been added.

One is an embryo of the 3D delhex mesh which is an extension of delquad.

The other one is MMG, the mobile mesh generator of CECILE DOBRZYNSKI (Bordeaux I) and PASCAL FREY (PARIS VI). We are very happy that this new anisotropic 3D mesher is now available as an open source !!
---
 CMakeLists.txt                                |     7 +
 Common/CommandLine.cpp                        |     8 +-
 Common/DefaultOptions.h                       |     2 +-
 Common/GmshConfig.h.in                        |     1 +
 Common/GmshDefines.h                          |     3 +
 Common/Options.cpp                            |     9 +
 Fltk/optionWindow.cpp                         |     6 +
 Geo/GEdge.cpp                                 |    11 +
 Geo/GFaceCompound.cpp                         |     7 +-
 Geo/Geo.cpp                                   |     2 +-
 Mesh/BackgroundMesh.cpp                       |    21 +-
 Mesh/CMakeLists.txt                           |     2 +-
 Mesh/Field.cpp                                |     4 +-
 Mesh/meshGFace.cpp                            |     4 +-
 Mesh/meshGFaceDelaunayInsertion.cpp           |   343 +-
 Mesh/meshGFaceDelaunayInsertion.h             |     2 +-
 Mesh/meshGRegion.cpp                          |    12 +-
 Mesh/meshGRegionDelaunayInsertion.cpp         |   419 +-
 Mesh/meshGRegionDelaunayInsertion.h           |     2 +
 Mesh/meshGRegionMMG3D.cpp                     |   153 +
 Mesh/meshGRegionMMG3D.h                       |     5 +
 benchmarks/3d/coin.geo                        |     3 +-
 benchmarks/3d/thai.geo                        |     3 +
 benchmarks/step/capot.geo                     |     9 +-
 benchmarks/stl/mobilette.geo                  |     5 +-
 contrib/mmg3d/CMakeLists.txt                  |    69 +
 contrib/mmg3d/INSTALL.txt                     |    40 +
 contrib/mmg3d/LICENCE.txt                     |   621 +
 contrib/mmg3d/README.txt                      |     8 +
 contrib/mmg3d/build/CMakeLists.txt            |    98 +
 contrib/mmg3d/build/libexamples/main.c        |   129 +
 contrib/mmg3d/build/sources/analar.c          |   357 +
 contrib/mmg3d/build/sources/analarcutting.c   |   319 +
 contrib/mmg3d/build/sources/baryct.c          |   112 +
 contrib/mmg3d/build/sources/boulep.c          |   206 +
 contrib/mmg3d/build/sources/bucket.c          |   385 +
 contrib/mmg3d/build/sources/cendel.c          |   222 +
 contrib/mmg3d/build/sources/cenrad.c          |   182 +
 contrib/mmg3d/build/sources/chkmsh.c          |   182 +
 contrib/mmg3d/build/sources/chrono.c          |   142 +
 contrib/mmg3d/build/sources/chrono.h          |    77 +
 contrib/mmg3d/build/sources/colpoi.c          |   523 +
 contrib/mmg3d/build/sources/coquil.c          |   106 +
 contrib/mmg3d/build/sources/cutelt.c          |   544 +
 contrib/mmg3d/build/sources/defines.h         |    97 +
 contrib/mmg3d/build/sources/delaunay.c        |   813 +
 contrib/mmg3d/build/sources/eigenv.c          |   666 +
 contrib/mmg3d/build/sources/eigenv.h          |    47 +
 contrib/mmg3d/build/sources/hash.c            |   551 +
 contrib/mmg3d/build/sources/heap.c            |   227 +
 contrib/mmg3d/build/sources/inout.c           |  1417 ++
 contrib/mmg3d/build/sources/length.c          |   235 +
 contrib/mmg3d/build/sources/libmmg3d.h        |   128 +
 .../mmg3d/build/sources/libmmg3d_internal.h   |    59 +
 contrib/mmg3d/build/sources/librnbg.c         |   461 +
 contrib/mmg3d/build/sources/librnbg.h         |    68 +
 contrib/mmg3d/build/sources/locate.c          |   141 +
 contrib/mmg3d/build/sources/matrix.c          |    96 +
 contrib/mmg3d/build/sources/memory.c          |   284 +
 contrib/mmg3d/build/sources/memory.h          |    67 +
 contrib/mmg3d/build/sources/mesh.h            |   411 +
 contrib/mmg3d/build/sources/mmg3d.c           |   701 +
 contrib/mmg3d/build/sources/mmg3d1.c          |   192 +
 contrib/mmg3d/build/sources/mmg3d4.c          |   237 +
 contrib/mmg3d/build/sources/mmg3d9.c          |   528 +
 contrib/mmg3d/build/sources/mmg3dConfig.h     |    50 +
 contrib/mmg3d/build/sources/mmg3dlib.c        |   494 +
 contrib/mmg3d/build/sources/movevertex.c      |   366 +
 contrib/mmg3d/build/sources/optbdry.c         |   272 +
 contrib/mmg3d/build/sources/optcoq.c          |   120 +
 contrib/mmg3d/build/sources/optcte.c          |   275 +
 contrib/mmg3d/build/sources/optlap.c          |   284 +
 contrib/mmg3d/build/sources/optlen.c          |   610 +
 contrib/mmg3d/build/sources/optlentet.c       |   349 +
 contrib/mmg3d/build/sources/optra4.c          |   106 +
 contrib/mmg3d/build/sources/opttet.c          |   133 +
 contrib/mmg3d/build/sources/opttyp.c          |   821 +
 contrib/mmg3d/build/sources/outqua.c          |   318 +
 contrib/mmg3d/build/sources/pattern.c         |  2440 ++
 contrib/mmg3d/build/sources/quality.c         |  1745 ++
 contrib/mmg3d/build/sources/queue.c           |   167 +
 contrib/mmg3d/build/sources/ratio.c           |   435 +
 contrib/mmg3d/build/sources/scalem.c          |   230 +
 contrib/mmg3d/build/sources/simu23.c          |   144 +
 contrib/mmg3d/build/sources/simu44.c          |   140 +
 contrib/mmg3d/build/sources/simu56.c          |   364 +
 contrib/mmg3d/build/sources/simu68.c          |  1130 +
 contrib/mmg3d/build/sources/simu710.c         |  4021 ++++
 contrib/mmg3d/build/sources/solmap.c          |   208 +
 contrib/mmg3d/build/sources/spledg.c          |   132 +
 contrib/mmg3d/build/sources/sproto.h          |   240 +
 contrib/mmg3d/build/sources/swap23.c          |   678 +
 contrib/mmg3d/build/sources/swap44.c          |   608 +
 contrib/mmg3d/build/sources/swap56.c          |  1956 ++
 contrib/mmg3d/build/sources/swap68.c          |  5674 +++++
 contrib/mmg3d/build/sources/swap710.c         | 19044 ++++++++++++++++
 contrib/mmg3d/build/sources/swapar.c          |   106 +
 contrib/mmg3d/build/sources/swaptet.c         |   105 +
 contrib/mmg3d/build/sources/typelt.c          |   378 +
 contrib/mmg3d/build/sources/zaldy.c           |   256 +
 contrib/mpeg_encode/bframe.cpp                |     2 +-
 contrib/mpeg_encode/bitio.cpp                 |     1 +
 contrib/mpeg_encode/block.cpp                 |     1 +
 contrib/mpeg_encode/iframe.cpp                |     2 +-
 contrib/mpeg_encode/pframe.cpp                |     2 +-
 105 files changed, 56927 insertions(+), 271 deletions(-)
 create mode 100644 Mesh/meshGRegionMMG3D.cpp
 create mode 100644 Mesh/meshGRegionMMG3D.h
 create mode 100644 contrib/mmg3d/CMakeLists.txt
 create mode 100644 contrib/mmg3d/INSTALL.txt
 create mode 100644 contrib/mmg3d/LICENCE.txt
 create mode 100644 contrib/mmg3d/README.txt
 create mode 100644 contrib/mmg3d/build/CMakeLists.txt
 create mode 100644 contrib/mmg3d/build/libexamples/main.c
 create mode 100644 contrib/mmg3d/build/sources/analar.c
 create mode 100644 contrib/mmg3d/build/sources/analarcutting.c
 create mode 100644 contrib/mmg3d/build/sources/baryct.c
 create mode 100644 contrib/mmg3d/build/sources/boulep.c
 create mode 100644 contrib/mmg3d/build/sources/bucket.c
 create mode 100644 contrib/mmg3d/build/sources/cendel.c
 create mode 100644 contrib/mmg3d/build/sources/cenrad.c
 create mode 100644 contrib/mmg3d/build/sources/chkmsh.c
 create mode 100644 contrib/mmg3d/build/sources/chrono.c
 create mode 100644 contrib/mmg3d/build/sources/chrono.h
 create mode 100644 contrib/mmg3d/build/sources/colpoi.c
 create mode 100644 contrib/mmg3d/build/sources/coquil.c
 create mode 100644 contrib/mmg3d/build/sources/cutelt.c
 create mode 100644 contrib/mmg3d/build/sources/defines.h
 create mode 100644 contrib/mmg3d/build/sources/delaunay.c
 create mode 100644 contrib/mmg3d/build/sources/eigenv.c
 create mode 100644 contrib/mmg3d/build/sources/eigenv.h
 create mode 100644 contrib/mmg3d/build/sources/hash.c
 create mode 100644 contrib/mmg3d/build/sources/heap.c
 create mode 100644 contrib/mmg3d/build/sources/inout.c
 create mode 100644 contrib/mmg3d/build/sources/length.c
 create mode 100644 contrib/mmg3d/build/sources/libmmg3d.h
 create mode 100644 contrib/mmg3d/build/sources/libmmg3d_internal.h
 create mode 100644 contrib/mmg3d/build/sources/librnbg.c
 create mode 100644 contrib/mmg3d/build/sources/librnbg.h
 create mode 100644 contrib/mmg3d/build/sources/locate.c
 create mode 100644 contrib/mmg3d/build/sources/matrix.c
 create mode 100644 contrib/mmg3d/build/sources/memory.c
 create mode 100644 contrib/mmg3d/build/sources/memory.h
 create mode 100644 contrib/mmg3d/build/sources/mesh.h
 create mode 100644 contrib/mmg3d/build/sources/mmg3d.c
 create mode 100644 contrib/mmg3d/build/sources/mmg3d1.c
 create mode 100644 contrib/mmg3d/build/sources/mmg3d4.c
 create mode 100644 contrib/mmg3d/build/sources/mmg3d9.c
 create mode 100644 contrib/mmg3d/build/sources/mmg3dConfig.h
 create mode 100644 contrib/mmg3d/build/sources/mmg3dlib.c
 create mode 100644 contrib/mmg3d/build/sources/movevertex.c
 create mode 100644 contrib/mmg3d/build/sources/optbdry.c
 create mode 100644 contrib/mmg3d/build/sources/optcoq.c
 create mode 100644 contrib/mmg3d/build/sources/optcte.c
 create mode 100644 contrib/mmg3d/build/sources/optlap.c
 create mode 100644 contrib/mmg3d/build/sources/optlen.c
 create mode 100644 contrib/mmg3d/build/sources/optlentet.c
 create mode 100644 contrib/mmg3d/build/sources/optra4.c
 create mode 100644 contrib/mmg3d/build/sources/opttet.c
 create mode 100644 contrib/mmg3d/build/sources/opttyp.c
 create mode 100644 contrib/mmg3d/build/sources/outqua.c
 create mode 100644 contrib/mmg3d/build/sources/pattern.c
 create mode 100644 contrib/mmg3d/build/sources/quality.c
 create mode 100644 contrib/mmg3d/build/sources/queue.c
 create mode 100644 contrib/mmg3d/build/sources/ratio.c
 create mode 100644 contrib/mmg3d/build/sources/scalem.c
 create mode 100644 contrib/mmg3d/build/sources/simu23.c
 create mode 100644 contrib/mmg3d/build/sources/simu44.c
 create mode 100644 contrib/mmg3d/build/sources/simu56.c
 create mode 100644 contrib/mmg3d/build/sources/simu68.c
 create mode 100644 contrib/mmg3d/build/sources/simu710.c
 create mode 100644 contrib/mmg3d/build/sources/solmap.c
 create mode 100644 contrib/mmg3d/build/sources/spledg.c
 create mode 100644 contrib/mmg3d/build/sources/sproto.h
 create mode 100644 contrib/mmg3d/build/sources/swap23.c
 create mode 100644 contrib/mmg3d/build/sources/swap44.c
 create mode 100644 contrib/mmg3d/build/sources/swap56.c
 create mode 100644 contrib/mmg3d/build/sources/swap68.c
 create mode 100644 contrib/mmg3d/build/sources/swap710.c
 create mode 100644 contrib/mmg3d/build/sources/swapar.c
 create mode 100644 contrib/mmg3d/build/sources/swaptet.c
 create mode 100644 contrib/mmg3d/build/sources/typelt.c
 create mode 100644 contrib/mmg3d/build/sources/zaldy.c

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 744fe3695d..78caf910c3 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 12b07737ea..091f202422 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 d1d4947561..6d68032505 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 0b6e218679..8997d6166b 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 c9588df974..40883c08ef 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 ea727f097b..fad1ca4b32 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 658e241b5b..ae18612bb1 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 7e0a86b73b..4c4606cafc 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 2b03cb029f..c8a0e16942 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 3e5aab3dcc..776a25aa76 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 369d107f27..b81af0c6e9 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 22aeb98b05..3f626aff6c 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 de40cee7b4..b26a705e09 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 609a15a4e7..4da46d9e24 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 f5eb885cf2..d70a5ca0ab 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 0aab515285..0890d9888c 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 0f104fa8f6..4fb32b0633 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 484c31b5e3..9eb2efa6bd 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 2e20470e75..cdd9b581a3 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 0000000000..4b8ae84bcd
--- /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 0000000000..59c50d6c20
--- /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 cc49a2b262..ba4c91c060 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 dff1f8df15..1e90077968 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 d2ba4152d7..c49a17d9d4 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 43a248c0cd..96dd603053 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 0000000000..0700016978
--- /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 0000000000..14d9f7844f
--- /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 0000000000..e587591e14
--- /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 0000000000..c296704020
--- /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 0000000000..1db395f167
--- /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 0000000000..f9e29257ec
--- /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 0000000000..ee4aa1e5bb
--- /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 0000000000..e36ca14134
--- /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 0000000000..138f158f9e
--- /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 0000000000..001bd54e92
--- /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 0000000000..7b8938b8db
--- /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 0000000000..41eab921bb
--- /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 0000000000..3a3921eaaa
--- /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 0000000000..1b492fdb88
--- /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 0000000000..ba4482e177
--- /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 0000000000..2df3774828
--- /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 0000000000..52c23ad3c5
--- /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 0000000000..c351552e47
--- /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 0000000000..54480498fa
--- /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 0000000000..2d71e945a9
--- /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 0000000000..e53a0e6a0c
--- /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 0000000000..8a75bd32b2
--- /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 0000000000..2f2d806a0d
--- /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 0000000000..1fa340f024
--- /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 0000000000..9570ce3502
--- /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 0000000000..09e719fab4
--- /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 0000000000..89304ea9ae
--- /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 0000000000..22c002499c
--- /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 0000000000..67be6768cb
--- /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 0000000000..bacfb4940b
--- /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 0000000000..97639a447c
--- /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 0000000000..c01826d9dc
--- /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 0000000000..d09a8212ee
--- /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 0000000000..9219eb3d56
--- /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 0000000000..dc85346434
--- /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 0000000000..efa8ae9ccf
--- /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 0000000000..b394a38a75
--- /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 0000000000..a71424f863
--- /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 0000000000..67791e2f88
--- /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 0000000000..e691727bf5
--- /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 0000000000..6fc584d764
--- /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 0000000000..b03e3c0ff5
--- /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 0000000000..207afc28f4
--- /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 0000000000..71152ccec5
--- /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 0000000000..c63a74d25f
--- /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 0000000000..6651abd33b
--- /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 0000000000..6a81bbba3a
--- /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 0000000000..ab8b07a26a
--- /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 0000000000..380ed42c2f
--- /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 0000000000..0b0a665067
--- /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 0000000000..eabe29da11
--- /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 0000000000..f1c9a5e138
--- /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 0000000000..7d811c7d8c
--- /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 0000000000..d099405165
--- /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 0000000000..7a78991ac0
--- /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 0000000000..2756bf3bb8
--- /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 0000000000..a975e6da84
--- /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 0000000000..91fc613612
--- /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 0000000000..e9d91c9398
--- /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 0000000000..c8a20c9e49
--- /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 0000000000..06671c0b2f
--- /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 0000000000..f1114219a1
--- /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 0000000000..6fea0e70fe
--- /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 0000000000..16e05cefc3
--- /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 0000000000..de9965df9f
--- /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 0000000000..178623047f
--- /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 0000000000..f51bfef104
--- /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 0000000000..b8d645576d
--- /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 0000000000..a116080e05
--- /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 0000000000..ec7c45dc7e
--- /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 0000000000..b58b84adf2
--- /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 0000000000..043f858142
--- /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 0000000000..c9d75b00ed
--- /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 0000000000..659c8eb033
--- /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 0000000000..6bc7cd271c
--- /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 72eecb2deb..53a185dcd6 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 69b5303dea..1b78bff6a4 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 f977a93fd0..9fa2f013f2 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 2fe01e7ec7..552c92489a 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 37ccb98cfb..7b6963d519 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"
-- 
GitLab