diff --git a/Geo/GModelIO_Mesh.cpp b/Geo/GModelIO_Mesh.cpp
index 7fb5b4b2809e0e01789505ff2e6e51e3cfabe73c..0e623b4bd5bd6a169c27d9abe1d36e0b25db88d2 100644
--- a/Geo/GModelIO_Mesh.cpp
+++ b/Geo/GModelIO_Mesh.cpp
@@ -833,64 +833,166 @@ int GModel::writeDistanceMSH(const std::string &name, double version, bool binar
   int numnodes = 0;
   for(unsigned int i = 0; i < entities.size()-1; i++)
     numnodes += entities[i]->mesh_vertices.size();
-
   int totNumNodes = numnodes + entities[entities.size()-1]->mesh_vertices.size();
-  std::map<MVertex*,double > distance;
-
-  // EMI: TODO COMPUTE this with EDP distanceTERM instead of ANN write
-  // solution for elements
 
   // CG: Emi -- pourquoi ne pas en faire un plugin, plutot ?
 
-#if defined(HAVE_ANN)
-  Msg::Info("Computing Distance function to the boundaries with ANN");
- 
- // add all points from boundaries into kdtree
-  ANNpointArray kdnodes = annAllocPts(numnodes, 4);
-  int k = 0;
-  for(unsigned int i = 0; i < entities.size()-1; i++)
-    for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++){
-      MVertex *v =  entities[i]->mesh_vertices[j];
-      distance.insert(std::make_pair(v, 0.0));
-      kdnodes[k][0] = v->x();
-      kdnodes[k][1] = v->y();
-      kdnodes[k][2] = v->z();
-      k++;
-    }  
-  ANNkd_tree *kdtree = new ANNkd_tree(kdnodes, numnodes, 3);
-
-  // compute the distances with the kdtree
-  ANNidxArray index = new ANNidx[1];
-  ANNdistArray dist = new ANNdist[1];
-  GEntity* g = entities[entities.size()-1];
-  for(unsigned int j = 0; j < g->mesh_vertices.size(); j++){
-    MVertex *v = g->mesh_vertices[j];
-    double xyz[3] = {v->x(), v->y(), v->z()};
-    kdtree->annkSearch(xyz, 1, index, dist);
-    double d = sqrt(dist[0]);
-    distance.insert(std::make_pair(v, d));
-  }
-  delete [] index;
-  delete [] dist;
-  delete kdtree;
-  annDeallocPts(kdnodes);
-#endif
+  //geometrical distance
+
+  std::map<MVertex*,double* > distance_map; 
+  std::vector<SPoint3> pts;
+  std::vector<double> distances;
+  pts.clear(); 
+  distances.clear();
+  distances.reserve(totNumNodes);
+  pts.reserve(totNumNodes);
+  for (int i = 0; i< totNumNodes; i++)   distances.push_back(1.e22);
 
-  //write distance in msh file
-  Msg::Info("Writing distance.pos");
-  FILE * f = fopen("distance.pos","w");
-  fprintf(f,"View \"distance\"{\n");
-  for(std::map<MVertex*, double>::iterator it = distance.begin(); it != distance.end(); it++) {
-      fprintf(f,"SP(%g,%g,%g){%g};\n",
-	      it->first->x(), it->first->y(), it->first->z(),
-	      it->second);     
+  int k=0;
+  for(unsigned int i = 0; i < entities.size(); i++){
+    GEntity* ge = entities[i]; 
+    for(unsigned int j = 0; j < ge->mesh_vertices.size(); j++){
+      MVertex *v = ge->mesh_vertices[j];
+      pts.push_back(SPoint3(v->x(), v->y(),v->z()));
+      distance_map.insert(std::make_pair(v, &(distances[k])));
+      k++;
+    }
   }
-  fprintf(f,"};\n");
-  fclose(f);
+
+//   GEntity* g2 = entities[entities.size()-2];//faces
+//   for(unsigned int i = 0; i < g2->getNumMeshElements(); i++){ 
+//     std::vector<double> iDistances;
+//     std::vector<SPoint3> iClosePts;
+//     MElement *e = g2->getMeshElement(i);
+//     MVertex *v1 = e->getVertex(0);
+//     MVertex *v2 = e->getVertex(1);
+//     MVertex *v3 = e->getVertex(2);
+//     SPoint3 p1 (v1->x(),v1->y(),v1->z());
+//     SPoint3 p2 (v2->x(),v2->y(),v2->z());
+//     SPoint3 p3 (v3->x(),v3->y(),v3->z());
+//     //signedDistancesPointsTriangle(iDistances, iClosePts, pts, p1,p2,p3);
+//     signedDistancesPointsLine(iDistances, iClosePts, pts, p1,p2);
+//     signedDistancesPointsLine(iDistances, iClosePts, pts, p1,p3);
+//     signedDistancesPointsLine(iDistances, iClosePts, pts, p2,p3);
+//     for (int k = 0; k< pts.size(); k++) {
+//       if (std::abs(iDistances[k]) < distances[k] ) 
+// 	distances[k] = std::abs(iDistances[k]);
+//     }
+//   }
+
+  std::map<int, std::vector<GEntity*> > groups[4];
+  getPhysicalGroups(groups);
+  std::map<int, std::vector<GEntity*> >::const_iterator it = groups[1].find(100);//Physical Line(100)={...}
+  if(it == groups[1].end()) return 0;
+  const std::vector<GEntity *> &physEntities = it->second;
+  for(unsigned int i = 0; i < physEntities.size(); i++){
+    GEntity* g2 = physEntities[i];
+    for(unsigned int i = 0; i < g2->getNumMeshElements(); i++){ 
+      std::vector<double> iDistances;
+      std::vector<SPoint3> iClosePts;
+      MElement *e = g2->getMeshElement(i);
+      MVertex *v1 = e->getVertex(0);
+      MVertex *v2 = e->getVertex(1);
+      SPoint3 p1 (v1->x(),v1->y(),v1->z());
+      SPoint3 p2 (v2->x(),v2->y(),v2->z());
+      signedDistancesPointsLine(iDistances, iClosePts, pts, p1,p2);     
+      for (int k = 0; k< pts.size(); k++) {
+	if (std::abs(iDistances[k]) < distances[k] ) 
+	  distances[k] = std::abs(iDistances[k]);
+      }
+    }
+  }
+
+  Msg::Info("Writing distance-GEOM.pos");
+  FILE * f2 = fopen("distance-GEOM.pos","w");
+  fprintf(f2,"View \"distance GEOM\"{\n");
+  int j = 0;
+  for(std::vector<double>::iterator it = distances.begin(); it != distances.end(); it++) {
+    fprintf(f2,"SP(%g,%g,%g){%g};\n",
+	    pts[j].x(),  pts[j].y(),  pts[j].z(),
+	    *it);  
+    j++;
+  }
+  fprintf(f2,"};\n");
+  fclose(f2);
+
+  Msg::Info("Writing distance-bgm.pos");
+  FILE * f3 = fopen("distance-bgm.pos","w");
+  fprintf(f3,"View \"distance\"{\n");
+  GEntity* ge = entities[entities.size()-1];
+  for(unsigned int i = 0; i < ge->getNumMeshElements(); i++){ 
+    MElement *e = ge->getMeshElement(i);
+    fprintf(f3,"SS(");
+    std::vector<double> dist;
+    for(int j = 0; j < e->getNumVertices(); j++) {
+      MVertex *v =  e->getVertex(j);
+      if(j) fprintf(f3,",%g,%g,%g",v->x(),v->y(), v->z());
+      else fprintf(f3,"%g,%g,%g", v->x(),v->y(), v->z());
+      std::map<MVertex*, double*>::iterator it = distance_map.find(v);
+      printf("dist =%g \n",*(it->second) );
+      dist.push_back(*(it->second));
+    }
+    fprintf(f3,"){");
+    for (int i=0; i<dist.size(); i++){
+      if (i) fprintf(f3,",%g", dist[i]);
+      else fprintf(f3,"%g", dist[i]);
+    }   
+    fprintf(f3,"};\n");
+  }
+  fprintf(f3,"};\n");
+  fclose(f3);
+      
+// #if defined(HAVE_ANN)
+//   Msg::Info("Computing Distance function to the boundaries with ANN");
+//   std::map<MVertex*,double > distance; 
+
+//  // add all points from boundaries into kdtree
+//   ANNpointArray kdnodes = annAllocPts(numnodes, 4);
+//   k = 0;
+//   for(unsigned int i = 0; i < entities.size()-1; i++)
+//     for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++){
+//       MVertex *v =  entities[i]->mesh_vertices[j];
+//       distance.insert(std::make_pair(v, 0.0));
+//       kdnodes[k][0] = v->x();
+//       kdnodes[k][1] = v->y();
+//       kdnodes[k][2] = v->z();
+//       k++;
+//     }  
+//   ANNkd_tree *kdtree = new ANNkd_tree(kdnodes, numnodes, 3);
+
+//   // compute the distances with the kdtree
+//   ANNidxArray index = new ANNidx[1];
+//   ANNdistArray dist = new ANNdist[1];
+//   GEntity* ga = entities[entities.size()-1];
+//   for(unsigned int j = 0; j < ga->mesh_vertices.size(); j++){
+//     MVertex *v = ga->mesh_vertices[j];
+//     double xyz[3] = {v->x(), v->y(), v->z()};
+//     kdtree->annkSearch(xyz, 1, index, dist);
+//     double d = sqrt(dist[0]);
+//     distance.insert(std::make_pair(v, d));
+//   }
+//   delete [] index;
+//   delete [] dist;
+//   delete kdtree;
+//   annDeallocPts(kdnodes);
+
+//   //write distance in msh file
+//   Msg::Info("Writing distance-ANN.pos");
+//   FILE * f = fopen("distance-ANN.pos","w");
+//   fprintf(f,"View \"distance ANN\"{\n");
+//   for(std::map<MVertex*, double>::iterator it = distance.begin(); it != distance.end(); it++) {
+//     fprintf(f,"SP(%g,%g,%g){%g};\n",
+// 	    it->first->x(), it->first->y(), it->first->z(),
+// 	    it->second);     
+//   }
+//   fprintf(f,"};\n");
+//   fclose(f);
+
+// #endif
 
 //   Msg::Info("Writing distance-bgm.pos");
 //   FILE * f2 = fopen("distance-bgm.pos","w");
-//   fprintf(f,"View \"distance\"{\n");
+//   fprintf(f2,"View \"distance\"{\n");
 //   GEntity* ge = entities[entities.size()-1];
 //   for(unsigned int i = 0; i < ge->getNumMeshElements(); i++){ 
 //     MElement *e = ge->getMeshElement(i);
@@ -910,10 +1012,12 @@ int GModel::writeDistanceMSH(const std::string &name, double version, bool binar
 //     }   
 //     fprintf(f2,"};\n");
 //   }
-//   fprintf(f,"};\n");
+//   fprintf(f2,"};\n");
 //   fclose(f2);
-   
+
+
   return 1;
+
 }
 
 int GModel::writePOS(const std::string &name, bool printElementary, 
diff --git a/Numeric/Numeric.cpp b/Numeric/Numeric.cpp
index 3ead5be996847ebd2a1e863192da613571cffea6..f60a0e713b93b5dfe0ab3828da036c5d6d64fbae 100644
--- a/Numeric/Numeric.cpp
+++ b/Numeric/Numeric.cpp
@@ -723,6 +723,7 @@ distance to segment
 */
 
 void signedDistancesPointsTriangle(std::vector<double>&distances,
+				   std::vector<SPoint3>&closePts,
                                    const std::vector<SPoint3> &pts,
                                    const SPoint3 &p1,
                                    const SPoint3 &p2,
@@ -742,6 +743,8 @@ void signedDistancesPointsTriangle(std::vector<double>&distances,
   
   distances.clear();
   distances.resize(pts.size());
+  closePts.clear();
+  closePts.resize(pts.size());
 
   for (unsigned int i = 0; i < pts.size(); i++)
     distances[i] = 1.e22;
@@ -763,6 +766,7 @@ void signedDistancesPointsTriangle(std::vector<double>&distances,
     if (d == 0) sign = 1.e10;
     if (u >= 0 && v >= 0 && 1.-u-v >= 0.0){
       distances[i] = d;
+      closePts[i] = SPoint3(0.,0.,0.);//TO DO
     }
     else {
       const double t12 = dot(pp1, t1) / n2t1;
@@ -771,21 +775,80 @@ void signedDistancesPointsTriangle(std::vector<double>&distances,
       const double t23 = dot(pp2, t3) / n2t3;
       d = 1.e10;
       bool found = false;
+      SPoint3 closePt;
       if (t12 >= 0 && t12 <= 1.){
-	d = sign * std::min(fabs(d), p.distance(p1 + (p2 - p1) * t12));            
+	d = sign * std::min(fabs(d), p.distance(p1 + (p2 - p1) * t12));  
+        closePt = p1 + (p2 - p1) * t12;
 	found = true;
       }
       if (t13 >= 0 && t13 <= 1.){
+	if (p.distance(p1 + (p3 - p1) * t13) < fabs(d))	  closePt = p1 + (p3 - p1) * t13;
 	d = sign * std::min(fabs(d), p.distance(p1 + (p3 - p1) * t13));      
 	found = true;
       }      
       if (t23 >= 0 && t23 <= 1.){
+	if (p.distance(p2 + (p3 - p2) * t23) < fabs(d))	  closePt = p2 + (p3 - p2) * t23;
 	d = sign * std::min(fabs(d), p.distance(p2 + (p3 - p2) * t23));      
 	found = true;
       }
-      d = sign * std::min(fabs(d), std::min(std::min(p.distance(p1), p.distance(p2)),
-                                            p.distance(p3)));
+      if (p.distance(p1) < fabs(d)){
+	closePt = p1;
+	d = sign * std::min(fabs(d), p.distance(p1));
+       }
+      if (p.distance(p2) < fabs(d)){
+	closePt = p2;
+	d = sign * std::min(fabs(d), p.distance(p2));
+       }
+      if (p.distance(p3) < fabs(d)){
+	closePt = p3;
+	d = sign * std::min(fabs(d), p.distance(p3));
+      }
+      //d = sign * std::min(fabs(d), std::min(std::min(p.distance(p1), p.distance(p2)),p.distance(p3)));
       distances[i] = d;
+      closePts[i] = closePt;
     }
   }					   
 }
+
+void signedDistancesPointsLine (std::vector<double>&distances,
+				std::vector<SPoint3>&closePts,
+				const std::vector<SPoint3> &pts,
+				const SPoint3 &p1,
+				const SPoint3 &p2){
+
+  SVector3 t1 = p2 - p1;
+  const double n2t1 = dot(t1, t1);
+  
+  distances.clear();
+  distances.resize(pts.size());
+  closePts.clear();
+  closePts.resize(pts.size());
+
+  double d;
+  for (unsigned int i = 0; i < pts.size();i++){
+    const SPoint3 &p = pts[i];
+    SVector3 pp1 = p - p1;
+    const double t12 = dot(pp1, t1) / n2t1;
+    d = 1.e10;
+    bool found = false;
+    SPoint3 closePt;
+    if (t12 >= 0 && t12 <= 1.){
+      d =  std::min(fabs(d), p.distance(p1 + (p2 - p1) * t12));  
+      closePt = p1 + (p2 - p1) * t12;
+      found = true;
+    }
+
+    if (p.distance(p1) < fabs(d)){
+      closePt = p1;
+      d =  std::min(fabs(d), p.distance(p1));
+    }
+    if (p.distance(p2) < fabs(d)){
+      closePt = p2;
+      d =  std::min(fabs(d), p.distance(p2));
+    }
+    
+    distances[i] = d;
+    closePts[i] = closePt;
+  }
+
+}
diff --git a/Numeric/Numeric.h b/Numeric/Numeric.h
index 9678825457fccf2761f8591f74e6865389ffd83e..726f9c6ed526977ed39e112d765776930482d89b 100644
--- a/Numeric/Numeric.h
+++ b/Numeric/Numeric.h
@@ -78,8 +78,14 @@ bool newton_fd(void (*func)(fullVector<double> &, fullVector<double> &, void *),
 double minimize_grad_fd(double (*func)(fullVector<double> &, void *),
                         fullVector<double> &x, void *data);
 void signedDistancesPointsTriangle (std::vector<double>&distances,
+				    std::vector<SPoint3>&closePts,
 				    const std::vector<SPoint3> &pts,
 				    const SPoint3 &p1,
 				    const SPoint3 &p2,
 				    const SPoint3 &p3);
+void signedDistancesPointsLine (std::vector<double>&distances,
+				std::vector<SPoint3>&closePts,
+				const std::vector<SPoint3> &pts,
+				const SPoint3 &p1,
+				const SPoint3 &p2);
 #endif
diff --git a/Solver/multiscaleLaplace.cpp b/Solver/multiscaleLaplace.cpp
index 58e7d028e54e138229c567f795040eb21c5b1b96..6d0f639489ee27a43f010bb4a4470ba2bb4a998d 100644
--- a/Solver/multiscaleLaplace.cpp
+++ b/Solver/multiscaleLaplace.cpp
@@ -215,8 +215,6 @@ static void recur_compute_centers_ (double R, double a1, double a2,
 
   SPoint2 PL (R*cos(a1),R*sin(a1));
   SPoint2 PR (R*cos(a2),R*sin(a2));
-  printf("R=%g a1=%g PL=%g %g \n", R, a1*180/M_PI, PL.x(), PL.y());
-  printf("R=%g a2=%g PR=%g %g \n", R, a2*180/M_PI, PR.x(), PR.y());
   centers.push_back(std::make_pair(PL,zero));  
   centers.push_back(std::make_pair(PR,zero));  
   for (int i=0;i<root->children.size();i++){