diff --git a/contrib/hxt/tetMesh/src/hxt_tetDelaunay.c b/contrib/hxt/tetMesh/src/hxt_tetDelaunay.c
index c793c0c4e45fe36026135c3d11a83ca9e732cebf..cf857298416571d579b9549216785b598117084b 100644
--- a/contrib/hxt/tetMesh/src/hxt_tetDelaunay.c
+++ b/contrib/hxt/tetMesh/src/hxt_tetDelaunay.c
@@ -22,7 +22,6 @@
 */
 
 /* compile-time parameters */
-// #define HXT_DELAUNAY_LOW_MEMORY /* doesn't use any buffer (a lot slower, except if you are at the limit of filling the RAM) */
 
 #define SMALLEST_PASS 2048
 
@@ -45,9 +44,7 @@ typedef struct {
 
 
 typedef struct {
-#ifndef HXT_DELAUNAY_LOW_MEMORY
   uint64_t hxtDeclareAligned Map[1024];
-#endif
 
   struct {
     cavityBnd_t* array;
@@ -645,9 +642,6 @@ static HXTStatus isStarShaped(TetLocal* local, HXTMesh* mesh, const uint32_t vta
         return HXT_STATUS_INTERNAL;
       }
     }
-    else {
-      return HXT_ERROR_MSG(HXT_STATUS_ERROR, "ghost vertex in constrained cavity");
-    }
   }
   return HXT_STATUS_OK;
 }
@@ -992,10 +986,9 @@ static inline HXTStatus diggingACavity(HXTMesh* mesh, TetLocal* local, uint64_t
 }
 
 
-/**************************************************************
- * compute adjacencies with a matrix O(1) insertion and search
- **************************************************************/
-#ifndef HXT_DELAUNAY_LOW_MEMORY
+/**********************************************************************
+ * compute adjacencies with a matrix O(1) insertion and search => O(n)
+ **********************************************************************/
 static inline HXTStatus computeAdjacenciesFast(HXTMesh* mesh, TetLocal* local, unsigned char* __restrict__ verticesID, const unsigned char blength){
   cavityBnd_t* __restrict__ bnd = local->ball.array;
 
@@ -1062,63 +1055,57 @@ HXT_ASSERT(((size_t) verticesID)%SIMD_ALIGN==0);
 
   return HXT_STATUS_OK;
 }
-#endif
 
 
 /**************************************************************
- * compute adjacencies with a stack O(n) insertion and search
+ * compute adjacencies by sorting => O(n log n)
  **************************************************************/
-static inline HXTStatus computeAdjacenciesSlow(HXTMesh* mesh, TetLocal* local, const uint64_t start, const uint64_t blength){
+static inline HXTStatus computeAdjacenciesSlow(HXTMesh* mesh, TetLocal* local, const uint64_t start, const uint64_t blength)
+{
+  HXTGroup2* edges;
+
+  HXT_CHECK( askForBall(local, 2 * blength) );
+  edges = (HXTGroup2*) local->ball.array; // recycle array
 
-  uint64_t tlength = 0;
-  const uint64_t middle = blength*3/2; // 3N
+  const uint8_t index[4] = {2,3,1,2};
 
-  // N+2 point on the surface of the cavity
-  // 2N triangle on the surface of the cavity, x3 (4*0.5+1) data = 6N+9 uint64_t
-  // => enough place for the 3N edge x2 data = 6N uint64_t
-  uint64_t* Tmp = (uint64_t*) local->ball.array;
-  const unsigned index[4] = {2,3,1,2};
+  const uint32_t n = mesh->vertices.num + 1;
+  uint64_t maxKey = 0;
 
   for (uint64_t i=0; i<blength; i++)
   {
     uint64_t curTet = local->deleted.array[start+ i];
     const uint32_t* __restrict__ Node = mesh->tetrahedra.node + 4*curTet;
-
-    // pointer to the position of Node[0] in the Tmp array
     for (unsigned j=0; j<3; j++)
     {
-      // define the edge by the minimum vertex and the other
-      uint64_t key = ((uint64_t) Node[index[j]]<<32) + Node[index[j+1]];
+      uint32_t n0 = Node[index[j]] + 1;
+      uint32_t n1 = Node[index[j+1]] + 1;
 
-      // linear searching/pushing into Tmp
-      uint64_t k;
-      for (k=0; k<tlength; k++) // this is the only nested loop... the one that cost it all
-      {
-        if(Tmp[k]==key)
-          break;
-      }
+      if(n0 < n1)
+        edges[3*i + j].v[0] = ((uint64_t) n0 * n) + n1;
+      else
+        edges[3*i + j].v[0] = ((uint64_t) n1 * n) + n0;
 
-      uint64_t curFace = 4*curTet+j+1;
+      if(edges[3*i + j].v[0] > maxKey)
+        maxKey = edges[3*i + j].v[0];
 
-      // we did not found it
-      if(k==tlength){
-        Tmp[tlength] = (key>>32) + (key<<32);
-        Tmp[middle + tlength] = curFace;
-        tlength++;
-      }
-      else{// we found the neighbour !
-        uint64_t pairValue = Tmp[middle+k];
-        mesh->tetrahedra.neigh[curFace] = pairValue;
-        mesh->tetrahedra.neigh[pairValue] = curFace;
-        tlength--;
-        if(k<tlength){// put the last entry in the one we just discovered
-          Tmp[k] = Tmp[tlength];
-          Tmp[middle+k] = Tmp[middle + tlength];
-        }
-      }
+      edges[3*i + j].v[1] = 4*curTet+j+1;
     }
   }
-  HXT_ASSERT_MSG(tlength==0, "Failed to compute adjacencies (s)"); // verify that all neighbor were found
+
+  HXT_CHECK( group2_sort_v0(edges, 3*blength, maxKey) );
+
+  for(int i=0; i<3*blength; i+=2) {
+#ifndef NDEBUG
+    if(edges[i].v[0] != edges[i+1].v[0])
+      return HXT_ERROR_MSG(HXT_STATUS_ERROR, "Failed to compute adjacencies (b)");
+#endif
+    uint64_t f0 = edges[i].v[1];
+    uint64_t f1 = edges[i+1].v[1];
+
+    mesh->tetrahedra.neigh[f0] = f1;
+    mesh->tetrahedra.neigh[f1] = f0;
+  }
   return HXT_STATUS_OK;
 }
 
@@ -1165,7 +1152,6 @@ static inline HXTStatus fillingACavity(HXTMesh* mesh, TetLocal* local, unsigned
     // we recycle neigh to contain newTet (used in computeAdjacencies)
     local->ball.array[i].neigh = 4*newTet;
   }
-#ifndef HXT_DELAUNAY_LOW_MEMORY
   if(blength<=58){ // N+2<=31 => N<=29 => 2N<=58
   #ifndef NDEBUG
     HXT_CHECK( computeAdjacenciesFast(mesh, local, verticesID, blength) );
@@ -1173,14 +1159,8 @@ static inline HXTStatus fillingACavity(HXTMesh* mesh, TetLocal* local, unsigned
     computeAdjacenciesFast(mesh, local, verticesID, blength);
   #endif
   }
-  else
-#endif
-  {
-  #ifndef NDEBUG
+  else {
     HXT_CHECK(computeAdjacenciesSlow(mesh, local, start, blength) );
-  #else
-    computeAdjacenciesSlow(mesh, local, start, blength);
-  #endif
   }
 
 
@@ -1405,11 +1385,7 @@ static HXTStatus parallelDelaunay3D(HXTMesh* mesh,
 
 
   unsigned char*  verticesID;
-#ifdef HXT_DELAUNAY_LOW_MEMORY
-  verticesID = NULL; // we do not need it
-#else
   HXT_CHECK( hxtAlignedMalloc(&verticesID, mesh->vertices.num*sizeof(unsigned char)) );
-#endif
 
   TetLocal* Locals;
   HXT_CHECK( hxtMalloc(&Locals, maxPartitions*sizeof(TetLocal)) );
@@ -1689,8 +1665,8 @@ static HXTStatus parallelDelaunay3D(HXTMesh* mesh,
           ******************************************************/
           for (uint32_t i=0; i<localN; i++)
           {
-            if( i%1000==0)
-              printf("%f %%\n", 100.0*i/localN);
+            // if( i%1000==0)
+            //   printf("%f %%\n", 100.0*i/localN);
             uint32_t passIndex = (localStart+i)%passLength;
             uint32_t vta = nodeInfo[passStart + passIndex].node;
             if(nodeInfo[passStart + passIndex].status==HXT_STATUS_TRYAGAIN){