From c292e8e0084dd9524fb7e45889225523c63ec61d Mon Sep 17 00:00:00 2001
From: Emilie Marchandise <emilie.marchandise@uclouvain.be>
Date: Mon, 20 Sep 2010 10:42:36 +0000
Subject: [PATCH] Improved conformal map + first part nonlinear conformal map

---
 Common/DefaultOptions.h |   2 +-
 Geo/GFaceCompound.cpp   | 219 ++++++++++++++++++++--------------------
 Geo/GFaceCompound.h     |   2 +-
 Geo/GModelIO_Mesh.cpp   |   4 -
 Plugin/Distance.cpp     |   1 -
 Solver/crossConfTerm.h  |  32 +++++-
 Solver/eigenSolver.cpp  |  22 ++--
 Solver/laplaceTerm.h    |  32 +++++-
 8 files changed, 176 insertions(+), 138 deletions(-)

diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 1c7470f07e..fee1a8ccb3 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -1253,7 +1253,7 @@ StringXNumber MeshOptions_Number[] = {
   { F|O, "SmoothRatio" , opt_mesh_smooth_ratio , 1.8 ,
     "Ratio between mesh sizes at vertices of a same edeg (used in BAMG)" },
   { F|O, "SubdivisionAlgorithm" , opt_mesh_algo_subdivide , 0 ,
-    "Mesh subdivision algorithm (0=none, 1=all quadrangles, 2=all hexahedra)" }, 
+    "Mesh subdivision algorithm (0=none, 1=all quadrangles, 2=all hexahedra, 3=all quadrangles (Blossom))" }, 
   { F|O, "SurfaceEdges" , opt_mesh_surfaces_edges , 1. , 
     "Display edges of surface mesh?" },
   { F|O, "SurfaceFaces" , opt_mesh_surfaces_faces , 0. , 
diff --git a/Geo/GFaceCompound.cpp b/Geo/GFaceCompound.cpp
index f8b280dc50..7ba5cdc134 100644
--- a/Geo/GFaceCompound.cpp
+++ b/Geo/GFaceCompound.cpp
@@ -512,7 +512,7 @@ bool GFaceCompound::checkOverlap(std::vector<MVertex*> &ordered) const
   }
   
   if ( !has_no_overlap ) {
-    Msg::Warning("$$$ Overlap for compound face %d", this->tag());
+    Msg::Debug("Overlap for compound face %d", this->tag());
   }
 
   return has_no_overlap;
@@ -559,7 +559,7 @@ bool GFaceCompound::checkOrientation(int iter) const
 
   int iterMax = 15;
   if(!oriented && iter < iterMax){
-    if (iter == 0) Msg::Info("--- Parametrization is flipping : applying cavity checks.");
+    if (iter == 0) Msg::Warning("--- Parametrization is flipping : applying cavity checks.");
     Msg::Debug("--- Cavity Check - iter %d -",iter);
     one2OneMap();
     return checkOrientation(iter+1);
@@ -652,13 +652,17 @@ bool GFaceCompound::parametrize() const
     Msg::Debug("Parametrizing surface %d with 'conformal map'", tag());
     fillNeumannBCS();
     bool noOverlap = parametrize_conformal_spectral() ;
-    if (!noOverlap) noOverlap = parametrize_conformal();
+    if (!noOverlap){
+      Msg::Warning("!!! Overlap: parametrization switched to 'FE conformal' map");
+      noOverlap = parametrize_conformal();
+    }
     // if (!noOverlap) {
-    //    noOverlap = parametrize_conformal_nonLinear() ;
-    //    exit(1);
+    //   Msg::Warning("!!! Overlap: parametrization switched to 'nonLIN conformal' map");
+    //   noOverlap = parametrize_conformal_nonLinear() ;
+    //   exit(1);
     // }
     if ( !noOverlap || !checkOrientation(0) ){
-      Msg::Warning("$$$ Parametrization switched to harmonic map");
+      Msg::Warning("$$$ Overlap: parametrization switched to 'harmonic' map");
       parametrize(ITERU,HARMONIC); 
       parametrize(ITERV,HARMONIC);
     }
@@ -667,7 +671,7 @@ bool GFaceCompound::parametrize() const
   buildOct();  
 
   if (!checkOrientation(0)){
-    Msg::Info("### Parametrization switched to convex combination map");
+    Msg::Info("### Flipping: parametrization switched to convex combination map");
     coordinates.clear(); 
     Octree_Delete(oct);
     fillNeumannBCS();
@@ -1059,11 +1063,12 @@ SPoint2 GFaceCompound::getCoordinates(MVertex *v) const
   return SPoint2(0, 0);
 }
 
-void GFaceCompound::parametrize(iterationStep step, typeOfMapping tom, double alpha) const
+void GFaceCompound::parametrize(iterationStep step, typeOfMapping tom) const
 {  
   
   dofManager<double> myAssembler(_lsys);
 
+
   if(_type == UNITCIRCLE){
     // maps the boundary onto a circle
     std::vector<MVertex*> ordered;
@@ -1175,21 +1180,13 @@ void GFaceCompound::parametrize(iterationStep step, typeOfMapping tom, double al
     double value;
     myAssembler.getDofValue(v, 0, 1, value);
     std::map<MVertex*,SPoint3>::iterator itf = coordinates.find(v);
-
-    //combination convex and harmonic
-    double valNEW ;
-    if (alpha != 0.0)
-      valNEW = alpha*itf->second[step] + (1-alpha)*value ;
-    else
-      valNEW = value;
-
     if(itf == coordinates.end()){
       SPoint3 p(0, 0, 0);
-      p[step] = valNEW;
+      p[step] = value;
       coordinates[v] = p;
     }
     else{
-      itf->second[step]= valNEW; 
+      itf->second[step]= value; 
     }
   }
 
@@ -1199,11 +1196,11 @@ void GFaceCompound::parametrize(iterationStep step, typeOfMapping tom, double al
 bool GFaceCompound::parametrize_conformal_nonLinear() const
 {
 
-  Msg::Info("Conformal parametrization of type: nonLinear");
   buildOct(); //use this to print conformal map that is overlapping
+  //exit(1);
 
+  //--create dofManager
   dofManager<double> myAssembler(_lsys);
-  _lsys->clear();
 
   //--- first compute mapping harmonic
   parametrize(ITERU,HARMONIC); 
@@ -1222,12 +1219,12 @@ bool GFaceCompound::parametrize_conformal_nonLinear() const
   int nb = ordered.size();
 
   //--fix vertex
-  MVertex *v1  = ordered[0];
-  MVertex *v2  = ordered[(int)ceil((double)ordered.size()/2.)];
-  myAssembler.fixVertex(v1, 0, 1, 1.);
-  myAssembler.fixVertex(v1, 0, 2, 0.);
-  myAssembler.fixVertex(v2, 0, 1, -1.);
-  myAssembler.fixVertex(v2, 0, 2, 0.);
+  // MVertex *v1  = ordered[0];
+  // MVertex *v2  = ordered[(int)ceil((double)ordered.size()/2.)];
+  // myAssembler.fixVertex(v1, 0, 1, 1.);
+  // myAssembler.fixVertex(v1, 0, 2, 0.);
+  // myAssembler.fixVertex(v2, 0, 1, -1.);
+  // myAssembler.fixVertex(v2, 0, 2, 0.);
 
   //--Assemble linear system 
   for(std::set<MVertex *>::iterator itv = allNodes.begin(); itv !=allNodes.end() ; ++itv){
@@ -1240,46 +1237,48 @@ bool GFaceCompound::parametrize_conformal_nonLinear() const
     myAssembler.numberVertex(v, 0, 1);
     myAssembler.numberVertex(v, 0, 2);
   }
-  //ghost vertex for lagrange multiplier
   MVertex *lag = new MVertex(0.,0.,0.);
-  myAssembler.numberVertex(lag, 0, 3);
+  myAssembler.numberVertex(lag, 0, 3);//ghost vertex for lagrange multiplier
   
-  std::vector<MElement *> allElems;
-  laplaceTerm laplace1(model(), 1, ONE, &myAssembler);
-  laplaceTerm laplace2(model(), 2, ONE, &myAssembler);
-  crossConfTerm cross12(model(), 1, 2, ONE, &myAssembler);
-  crossConfTerm cross21(model(), 2, 1, MONE, &myAssembler);
-  std::list<GFace*>::const_iterator it = _compound.begin(); 
-  for( ; it != _compound.end() ; ++it){
-    for(unsigned int i = 0; i < (*it)->triangles.size(); ++i){
-      SElement se((*it)->triangles[i]);
-      laplace1.addToMatrix(myAssembler, &se);
-      laplace2.addToMatrix(myAssembler, &se);
-      cross12.addToMatrix(myAssembler, &se);
-      cross21.addToMatrix(myAssembler, &se);
-      allElems.push_back((MElement*)((*it)->triangles[i]));
-    }
-  }
-  for (std::list<MTriangle*>::iterator it2 = fillTris.begin(); it2 !=fillTris.end(); it2++ ){
-    SElement se((*it2));
-    laplace1.addToMatrix(myAssembler, &se);
-    laplace2.addToMatrix(myAssembler, &se);
-    cross12.addToMatrix(myAssembler, &se);
-    cross21.addToMatrix(myAssembler, &se);
-    allElems.push_back((MElement*)(*it2));
-  }
-  
-  groupOfElements gr(allElems);
-  laplace1.addToRightHandSide(myAssembler, gr);
-  laplace2.addToRightHandSide(myAssembler, gr);
-  cross12.addToRightHandSide(myAssembler, gr);
-  cross21.addToRightHandSide(myAssembler, gr);
 
   //--- newton Loop
   int nbNewton = 1;
-  double lam  = 0.1;
+  double lambda  = 1.e-3;
   for (int iNewton = 0; iNewton < nbNewton; iNewton++){
 
+    //-- assemble conformal matrix
+    std::vector<MElement *> allElems;
+    laplaceTerm laplace1(model(), 1, ONE, &coordinates);
+    laplaceTerm laplace2(model(), 2, ONE, &coordinates);
+    crossConfTerm cross12(model(), 1, 2, ONE, &coordinates);
+    crossConfTerm cross21(model(), 2, 1, MONE, &coordinates);
+    std::list<GFace*>::const_iterator it = _compound.begin(); 
+    for( ; it != _compound.end() ; ++it){
+      for(unsigned int i = 0; i < (*it)->triangles.size(); ++i){
+	SElement se((*it)->triangles[i]);
+	laplace1.addToMatrix(myAssembler, &se);
+	laplace2.addToMatrix(myAssembler, &se);
+	cross12.addToMatrix(myAssembler, &se);
+	cross21.addToMatrix(myAssembler, &se);
+	allElems.push_back((MElement*)((*it)->triangles[i]));
+      }
+    }
+    for (std::list<MTriangle*>::iterator it2 = fillTris.begin(); it2 !=fillTris.end(); it2++ ){
+      SElement se((*it2));
+      laplace1.addToMatrix(myAssembler, &se);
+      laplace2.addToMatrix(myAssembler, &se);
+      cross12.addToMatrix(myAssembler, &se);
+      cross21.addToMatrix(myAssembler, &se);
+      allElems.push_back((MElement*)(*it2));
+    }
+    
+    groupOfElements gr(allElems);
+    laplace1.addToRightHandSide(myAssembler, gr);
+    laplace2.addToRightHandSide(myAssembler, gr);
+    cross12.addToRightHandSide(myAssembler, gr);
+    cross21.addToRightHandSide(myAssembler, gr);
+    
+    //-- compute all boundary angles
     double sumTheta = 0.0;
     for (int i=0; i< nb; i++){
       MVertex *prev = (i!=0) ? ordered[i-1] : ordered[nb-1];
@@ -1297,14 +1296,14 @@ bool GFaceCompound::parametrize_conformal_nonLinear() const
       double a = norm(va), b=norm(vb), c=norm(vc);
       SVector3 n = crossprod(va, vb);
 
-      //--- compute theta
+      //- compute theta
       double theta = acos((a*a+b*b-c*c)/(2*a*b)); //in rad
       double sign = 1.;
       if (n.z() < 0.0) {sign = -1.; theta = 2*M_PI-theta;}
       //printf("theta in deg =%g \n", theta*180./M_PI);
       sumTheta +=theta;
 
-      //--- compute grad_uv theta
+      //- compute grad_uv theta
       //dTheta/du1 sign*acos((a^2+b^2 -c^2)/(2*a*b)) 
       //a=sqrt((u2-u1)^2+(v2-v1)^2))
       //b=sqrt((u3-u2)^2+(v3-v2)^2))
@@ -1319,34 +1318,34 @@ bool GFaceCompound::parametrize_conformal_nonLinear() const
       double dTdu3=sign*((u1 + u2 - 2*u3)/(sqrt(SQU(u1 - u2) + SQU(v1 - v2))*sqrt(SQU(u2 - u3) + SQU(v2 - v3))) - ((2*u2 - 2*u3)*(SQU(u1 - u2) + SQU(u1 - u3) + SQU(u2 - u3) + SQU(v1 - v2) + SQU(v1 - v3) + SQU(v2 - v3)))/(4*sqrt(SQU(u1 - u2) + SQU(v1 - v2))*pow((SQU(u2 - u3) + SQU(v2 - v3)),3/2)))/sqrt(1 - SQU(SQU(u1 - u2) + SQU(u1 - u3) + SQU(u2 - u3) + SQU(v1 - v2) + SQU(v1 - v3) + SQU(v2 - v3))/(4*(SQU(u1 - u2) + SQU(v1 - v2))*(SQU(u2 - u3) + SQU(v2 - v3))));
       double dTdv3=((v1 + v2 - 2*v3)/(sqrt(SQU(u1 - u2) + SQU(v1 - v2))*sqrt(SQU(u2 - u3) + SQU(v2 - v3))) - ((2*v2 - 2*v3)*(SQU(u1 - u2) + SQU(u1 - u3) + SQU(u2 - u3) + SQU(v1 - v2) + SQU(v1 - v3) + SQU(v2 - v3)))/(4*sqrt(SQU(u1 - u2) + SQU(v1 - v2))*pow((SQU(u2 - u3) + SQU(v2 - v3)),3/2)))/sqrt(1 - SQU(SQU(u1 - u2) + SQU(u1 - u3) + SQU(u2 - u3) + SQU(v1 - v2) + SQU(v1 - v3) + SQU(v2 - v3))/(4*(SQU(u1 - u2) + SQU(v1 - v2))*(SQU(u2 - u3) + SQU(v2 - v3))));
       
-      //---assemble constraint terms
-      // myAssembler.assemble(lag, 0, 3, prev, 0, 1,  dTdu1);
-      // myAssembler.assemble(lag, 0, 3, prev, 0, 2,  dTdv1);
-      // myAssembler.assemble(lag, 0, 3, curr, 0, 1,  dTdu2);
-      // myAssembler.assemble(lag, 0, 3, curr, 0, 2,  dTdv2);
-      // myAssembler.assemble(lag, 0, 3, next, 0, 1,  dTdu3);
-      // myAssembler.assemble(lag, 0, 3, next, 0, 2,  dTdv3);
-
-      // myAssembler.assemble(prev, 0, 1, lag, 0, 3,  dTdu1);
-      // myAssembler.assemble(prev, 0, 2, lag, 0, 3,  dTdv1);
-      // myAssembler.assemble(curr, 0, 1, lag, 0, 3,  dTdu2);
-      // myAssembler.assemble(curr, 0, 2, lag, 0, 3,  dTdv2);
-      // myAssembler.assemble(next, 0, 1, lag, 0, 3,  dTdu3);
-      // myAssembler.assemble(next, 0, 2, lag, 0, 3,  dTdv3);
-
-      // myAssembler.assemble(prev, 0, 1,  -dTdu1);
-      // myAssembler.assemble(prev, 0, 2,  -dTdv1);
-      // myAssembler.assemble(curr, 0, 1,  -dTdu2);
-      // myAssembler.assemble(curr, 0, 2,  -dTdv2);
-      // myAssembler.assemble(next, 0, 1,  -dTdu3);
-      // myAssembler.assemble(next, 0, 2,  -dTdv3);
+      //- assemble constraint terms
+      myAssembler.assemble(lag, 0, 3, prev, 0, 1,  lambda*dTdu1);
+      myAssembler.assemble(lag, 0, 3, prev, 0, 2,  lambda*dTdv1);
+      myAssembler.assemble(lag, 0, 3, curr, 0, 1,  lambda*dTdu2);
+      myAssembler.assemble(lag, 0, 3, curr, 0, 2,  lambda*dTdv2);
+      myAssembler.assemble(lag, 0, 3, next, 0, 1,  lambda*dTdu3);
+      myAssembler.assemble(lag, 0, 3, next, 0, 2,  lambda*dTdv3);
+
+      myAssembler.assemble(prev, 0, 1, lag, 0, 3,  lambda*dTdu1);
+      myAssembler.assemble(prev, 0, 2, lag, 0, 3,  lambda*dTdv1);
+      myAssembler.assemble(curr, 0, 1, lag, 0, 3,  lambda*dTdu2);
+      myAssembler.assemble(curr, 0, 2, lag, 0, 3,  lambda*dTdv2);
+      myAssembler.assemble(next, 0, 1, lag, 0, 3,  lambda*dTdu3);
+      myAssembler.assemble(next, 0, 2, lag, 0, 3,  lambda*dTdv3);
+
+      myAssembler.assemble(prev, 0, 1,  lambda*dTdu1);
+      myAssembler.assemble(prev, 0, 2,  lambda*dTdv1);
+      myAssembler.assemble(curr, 0, 1,  lambda*dTdu2);
+      myAssembler.assemble(curr, 0, 2,  lambda*dTdv2);
+      myAssembler.assemble(next, 0, 1,  lambda*dTdu3);
+      myAssembler.assemble(next, 0, 2,  lambda*dTdv3);
 
     }
 
     //--- compute constraint
     double G = fabs(sumTheta - (nb-2)*M_PI);
-    printf("constraint G = %g \n", G);
-    myAssembler.assemble(lag, 0, 3, lag, 0, 3,  1.0);//change this
+    printf("Sum of angles G = %g \n", G);
+    myAssembler.assemble(lag, 0, 3, lag, 0, 3,  0.0);//change this
 
     //--- assemble rhs of linear system
     myAssembler.assemble(lag, 0, 3, G);
@@ -1364,11 +1363,24 @@ bool GFaceCompound::parametrize_conformal_nonLinear() const
       myAssembler.getDofValue(v, 0, 2, value2);
       coordinates[v] = SPoint3(value1,value2,0.0);
     }
-    double lambda;
-    myAssembler.getDofValue(lag, 0, 3, lambda);
-    printf("lambda=%g \n", lambda);
+    //-- update newton
+    //U=U+DU
+    //lambda = lambda +dLambda
+    for(std::set<MVertex *>::iterator itv = allNodes.begin(); itv !=allNodes.end() ; ++itv){
+      MVertex *v = *itv;
+      double du,dv; 
+      myAssembler.getDofValue(v, 0, 1, du);
+      myAssembler.getDofValue(v, 0, 2, dv);
+      SPoint3 old = coordinates[v];
+      coordinates[v] = SPoint3(old.x()+du,old.y()+dv,0.0);
+    }
+    double dLambda;
+    myAssembler.getDofValue(lag, 0, 3, dLambda);
+    lambda = lambda+dLambda;
+    printf("dLambda=%g \n", dLambda);
 
-    //update newton
+    _lsys->zeroMatrix();
+    _lsys->zeroRightHandSide();
 
   }//end Newton
 
@@ -1378,7 +1390,7 @@ bool GFaceCompound::parametrize_conformal_nonLinear() const
 
 bool GFaceCompound::parametrize_conformal_spectral() const
 {
-  Msg::Info("Conformal parametrization of type: spectral");
+
 #if !defined(HAVE_PETSC) && !defined(HAVE_SLEPC)
   {
 
@@ -1463,36 +1475,20 @@ bool GFaceCompound::parametrize_conformal_spectral() const
     //-------------------------------
     myAssembler.setCurrentMatrix("B");
 
-    double small = 0.0;
-    for(std::set<MVertex *>::iterator itv = allNodes.begin(); itv !=allNodes.end() ; ++itv){
-      MVertex *v = *itv;
-      if (std::find(ordered.begin(), ordered.end(), v) == ordered.end() ){
-	myAssembler.assemble(v, 0, 1, v, 0, 1,  small);
-	myAssembler.assemble(v, 0, 2, v, 0, 2,  small);
-      }
-      else{
-	myAssembler.assemble(v, 0, 1, v, 0, 1,  1.0);
-	myAssembler.assemble(v, 0, 2, v, 0, 2,  1.0);
-      }
-    } 
-    for(std::set<MVertex *>::iterator itv = fillNodes.begin(); itv !=fillNodes.end() ; ++itv){
-      MVertex *v = *itv;
-      myAssembler.assemble(v, 0, 1, v, 0, 1,  small);
-      myAssembler.assemble(v, 0, 2, v, 0, 2,  small);
-    }
-
     //mettre max NC contraintes par bord
     int NB = ordered.size();
-    int NC = std::min(200,NB);
+    int NC = std::min(50,NB);
     int jump = (int) NB/NC;
     int nbLoop = (int) NB/jump ;
     //printf("nb bound nodes=%d jump =%d \n", NB, jump);
     for (int i = 0; i< nbLoop; i++){
       MVertex *v1 = ordered[i*jump];
+      myAssembler.assemble(v1, 0, 1, v1, 0, 1,  1.0);
+      myAssembler.assemble(v1, 0, 2, v1, 0, 2,  1.0);
       for (int j = 0; j< nbLoop; j++){
 	MVertex *v2 = ordered[j*jump];
-	myAssembler.assemble(v1, 0, 1, v2, 0, 1,  -1./NB);
-	myAssembler.assemble(v1, 0, 2, v2, 0, 2,  -1./NB);
+	myAssembler.assemble(v1, 0, 1, v2, 0, 1,  -1./NC);
+	myAssembler.assemble(v1, 0, 2, v2, 0, 2,  -1./NC);
       }
     }
 
@@ -1533,8 +1529,7 @@ bool GFaceCompound::parametrize_conformal_spectral() const
 }
 bool GFaceCompound::parametrize_conformal() const
 {
-  Msg::Info("Conformal parametrization of type: finite element");
-
+ 
   dofManager<double> myAssembler(_lsys);
 
   std::vector<MVertex*> ordered;
diff --git a/Geo/GFaceCompound.h b/Geo/GFaceCompound.h
index 2d190ef295..26f77b6f58 100644
--- a/Geo/GFaceCompound.h
+++ b/Geo/GFaceCompound.h
@@ -76,7 +76,7 @@ class GFaceCompound : public GFace {
   mutable std::set<MVertex*> fillNodes;
   void buildOct() const ;
   void buildAllNodes() const; 
-  void parametrize(iterationStep, typeOfMapping, double alpha=0.) const;
+  void parametrize(iterationStep, typeOfMapping) const;
   bool parametrize_conformal() const;
   bool parametrize_conformal_spectral() const;
   bool parametrize_conformal_nonLinear() const;
diff --git a/Geo/GModelIO_Mesh.cpp b/Geo/GModelIO_Mesh.cpp
index fdc739c452..ec8584a60f 100644
--- a/Geo/GModelIO_Mesh.cpp
+++ b/Geo/GModelIO_Mesh.cpp
@@ -2601,7 +2601,6 @@ int GModel::readVTK(const std::string &name, bool bigEndian)
     Msg::Warning("VTK reader only accepts float or double datasets");
     return 0;
   }
-  printf("POINTS=%d \n", numVertices);
   Msg::Info("Reading %d points", numVertices);
   std::vector<MVertex*> vertices(numVertices);
   for(int i = 0 ; i < numVertices; i++){
@@ -2621,7 +2620,6 @@ int GModel::readVTK(const std::string &name, bool bigEndian)
     else{
       if(fscanf(fp, "%lf %lf %lf", &xyz[0], &xyz[1], &xyz[2]) != 3) return 0;
     }
-    printf("Point(%d)={%g, %g, %g}; \n", i+1, xyz[0], xyz[1], xyz[2]);
     vertices[i] = new MVertex(xyz[0], xyz[1], xyz[2]);
   }
 
@@ -2721,7 +2719,6 @@ int GModel::readVTK(const std::string &name, bool bigEndian)
       int iLine = 1;
       int num = 0;
       for (int k= 0; k < numElements; k++){
-	printf("*** new line =%d \n", iLine);
 	physicals[1][iLine][1] = "centerline";
 	fgets(line, sizeof(line), fp);
 	v0=(int)strtol(line, &pEnd, 10);//ignore firt line
@@ -2730,7 +2727,6 @@ int GModel::readVTK(const std::string &name, bool bigEndian)
 	while(1){
 	  v1 = strtol(p, &pEnd, 10);
 	  if (p == pEnd )  break;
-	  printf("Line()={%d,%d};\n", vertices[v0]->getNum(),vertices[v1]->getNum());
 	  elements[1][iLine].push_back(new MLine(vertices[v0],vertices[v1])); 
 	  p=pEnd;
 	  v0=v1;
diff --git a/Plugin/Distance.cpp b/Plugin/Distance.cpp
index 392b40e8c6..507dda91b2 100644
--- a/Plugin/Distance.cpp
+++ b/Plugin/Distance.cpp
@@ -185,7 +185,6 @@ PView *GMSH_DistancePlugin::execute(PView *v)
   for(unsigned int i = 0; i < _entities.size()-1; i++)
     numnodes += _entities[i]->mesh_vertices.size();
   int totNodes=numnodes + _entities[_entities.size()-1]->mesh_vertices.size();
-  printf("%d\n",totNodes);
   int order=ge->getMeshElement(0)->getPolynomialOrder();
   int totNumNodes = totNodes+ge->getNumMeshElements()*integrationPointTetra[order-1];
 
diff --git a/Solver/crossConfTerm.h b/Solver/crossConfTerm.h
index dfbae205a4..011e5306fd 100644
--- a/Solver/crossConfTerm.h
+++ b/Solver/crossConfTerm.h
@@ -19,11 +19,13 @@ class crossConfTerm : public femTerm<double> {
   const simpleFunction<double> *_diffusivity;
   const int _iFieldR;
   int _iFieldC;
+  std::map<MVertex*, SPoint3> *_coordView;
  public:
   crossConfTerm(GModel *gm, int iFieldR, int iFieldC, 
-                simpleFunction<double> *diffusivity, dofManager<double> *dofView=NULL)
+                simpleFunction<double> *diffusivity, 
+		std::map<MVertex*, SPoint3> *coord=NULL)
     : femTerm<double>(gm), _diffusivity(diffusivity), _iFieldR(iFieldR), 
-      _iFieldC(iFieldC) {}
+    _iFieldC(iFieldC), _coordView(coord) {}
 
   virtual int sizeOfR(SElement *se) const 
   {
@@ -89,8 +91,30 @@ class crossConfTerm : public femTerm<double> {
   }
  void elementVector(SElement *se, fullVector<double> &m) const
   {
-    //adding here rhs
-    printf("implment  rhs cross term here\n");
+   
+    MElement *e = se->getMeshElement();
+    int nbNodes = e->getNumVertices(); 
+
+    fullMatrix<double> *mat;
+    mat = new fullMatrix<double>(nbNodes,nbNodes);
+    elementMatrix(se, *mat);
+
+    fullVector<double> val(nbNodes);
+    val.scale(0.);
+    for (int i = 0; i < nbNodes; i++){
+      std::map<MVertex*, SPoint3>::iterator it = _coordView->find(e->getVertex(i));
+      SPoint3 UV = it->second;
+      if (_iFieldC == 1)  val(i) = UV.x();
+      else if (_iFieldC == 2)  val(i) = UV.y();
+    }
+
+    m.scale(0.);
+    for (int i = 0; i < nbNodes; i++)
+      for (int j = 0; j < nbNodes; j++)
+    	m(i)  +=  -(*mat)(i,j)*val(j);
+
+
+
   }
 };
 
diff --git a/Solver/eigenSolver.cpp b/Solver/eigenSolver.cpp
index dac0349778..8c8f08564a 100644
--- a/Solver/eigenSolver.cpp
+++ b/Solver/eigenSolver.cpp
@@ -75,15 +75,15 @@ bool eigenSolver::solve(int numEigenValues, std::string which)
   // print info
   const EPSType type;
   _try(EPSGetType(eps, &type));
-  Msg::Info("SLEPc solution method: %s", type);
+  Msg::Debug("SLEPc solution method: %s", type);
 
   PetscInt nev;
   _try(EPSGetDimensions(eps, &nev, PETSC_NULL, PETSC_NULL));
-  Msg::Info("SLEPc number of requested eigenvalues: %d", nev);
+  Msg::Debug("SLEPc number of requested eigenvalues: %d", nev);
   PetscReal tol;
   PetscInt maxit;
   _try(EPSGetTolerances(eps, &tol, &maxit));
-  Msg::Info("SLEPc stopping condition: tol=%g, maxit=%d", tol, maxit);
+  Msg::Debug("SLEPc stopping condition: tol=%g, maxit=%d", tol, maxit);
 
   // solve
   Msg::Info("SLEPc solving...");
@@ -97,7 +97,7 @@ bool eigenSolver::solve(int numEigenValues, std::string which)
   _try(EPSGetConvergedReason(eps, &reason));
   if(reason == EPS_CONVERGED_TOL){
     double t2 = Cpu();
-    Msg::Info("SLEPc converged in %d iterations (%g s)", its, t2-t1);
+    Msg::Debug("SLEPc converged in %d iterations (%g s)", its, t2-t1);
   }
   else if(reason == EPS_DIVERGED_ITS)
     Msg::Error("SLEPc diverged after %d iterations", its);
@@ -109,7 +109,7 @@ bool eigenSolver::solve(int numEigenValues, std::string which)
   // get number of converged approximate eigenpairs
   PetscInt nconv;
   _try(EPSGetConverged(eps, &nconv));
-  Msg::Info("SLEPc number of converged eigenpairs: %d", nconv);
+  Msg::Debug("SLEPc number of converged eigenpairs: %d", nconv);
 
   // ignore additional eigenvalues if we get more than what we asked
   if(nconv > nev) nconv = nev;
@@ -118,8 +118,8 @@ bool eigenSolver::solve(int numEigenValues, std::string which)
     Vec xr, xi;
     _try(MatGetVecs(A, PETSC_NULL, &xr));
     _try(MatGetVecs(A, PETSC_NULL, &xi));
-    Msg::Info("         Re[EigenValue]          Im[EigenValue]"
-              "          Relative error");
+    Msg::Debug("         Re[EigenValue]          Im[EigenValue]"
+	       "          Relative error");
     for (int i = 0; i < nconv; i++){
       PetscScalar kr, ki;
       _try(EPSGetEigenpair(eps, i, &kr, &ki, xr, xi));
@@ -132,8 +132,8 @@ bool eigenSolver::solve(int numEigenValues, std::string which)
       PetscReal re = kr;
       PetscReal im = ki;
 #endif
-      Msg::Info("EIG %03d %s%.16e %s%.16e  %3.6e",
-                i, (re < 0) ? "" : " ", re, (im < 0) ? "" : " ", im, error);
+      Msg::Debug("EIG %03d %s%.16e %s%.16e  %3.6e",
+		 i, (re < 0) ? "" : " ", re, (im < 0) ? "" : " ", im, error);
 
       // store eigenvalues and eigenvectors
       _eigenValues.push_back(std::complex<double>(re, im));
@@ -158,11 +158,11 @@ bool eigenSolver::solve(int numEigenValues, std::string which)
   _try(SlepcFinalize());
 
   if(reason == EPS_CONVERGED_TOL){
-    Msg::Info("SLEPc done");
+    Msg::Debug("SLEPc done");
     return true;
   }
   else{
-    Msg::Info("SLEPc failed");
+    Msg::Warning("SLEPc failed");
     return false;
   }
 
diff --git a/Solver/laplaceTerm.h b/Solver/laplaceTerm.h
index e7a1ceeeb1..7c8f29430b 100644
--- a/Solver/laplaceTerm.h
+++ b/Solver/laplaceTerm.h
@@ -10,13 +10,37 @@
 
 // \nabla \cdot k \nabla U 
 class laplaceTerm : public helmholtzTerm<double> {
+ protected:
+ std::map<MVertex*, SPoint3> *_coordView;
+  const int _iField;
  public:
- laplaceTerm(GModel *gm, int iField, simpleFunction<double> *k, dofManager<double> *dofView=NULL)
-    : helmholtzTerm<double>(gm, iField, iField, k, 0) {}
+ laplaceTerm(GModel *gm, int iField, simpleFunction<double> *k,  
+	     std::map<MVertex*, SPoint3> *coord=NULL)
+   : helmholtzTerm<double>(gm, iField, iField, k, 0), _iField(iField), _coordView(coord) {}
  void elementVector(SElement *se, fullVector<double> &m) const
   {
-    //adding here rhs
-    printf("implment  rhs laplace term here\n");
+
+    MElement *e = se->getMeshElement();
+    int nbNodes = e->getNumVertices(); 
+
+    fullMatrix<double> *mat;
+    mat = new fullMatrix<double>(nbNodes,nbNodes);
+    elementMatrix(se, *mat);
+
+    fullVector<double> val(nbNodes);
+    val.scale(0.);
+    for (int i = 0; i < nbNodes; i++){
+      std::map<MVertex*, SPoint3>::iterator it = _coordView->find(e->getVertex(i));
+      SPoint3 UV = it->second;
+      if (_iField == 1)  val(i) = UV.x();
+      else if (_iField == 2)  val(i) = UV.y();
+    }
+
+    m.scale(0.);
+    for (int i = 0; i < nbNodes; i++)
+      for (int j = 0; j < nbNodes; j++)
+    	m(i)  +=  -(*mat)(i,j)*val(j);
+      
   }
 };
 
-- 
GitLab