diff --git a/Geo/GFaceCompound.cpp b/Geo/GFaceCompound.cpp
index a1470c97c72adb8d6ee4547eae23eef39e7108a0..ae5756a6b50ac6584c4a1f9a8928646e967abcb8 100644
--- a/Geo/GFaceCompound.cpp
+++ b/Geo/GFaceCompound.cpp
@@ -505,6 +505,7 @@ bool GFaceCompound::parametrize() const
     fillNeumannBCS();
     bool withoutFolding = parametrize_conformal_spectral() ;
     printStuff();
+    //exit(1);
     if ( withoutFolding == false ){
       Msg::Warning("$$$ Parametrization switched to harmonic map");
       parametrize(ITERU,HARMONIC); 
@@ -530,10 +531,6 @@ bool GFaceCompound::parametrize() const
     buildOct();
   }
 
-
-
-
-
   if (checkAspectRatio() > AR_MAX){
     Msg::Warning("Geometrical aspect ratio too high");
     //exit(1);
@@ -1119,12 +1116,10 @@ bool GFaceCompound::parametrize_conformal_spectral() const
 
   //-------------------------------
   myAssembler.setCurrentMatrix("A");
-
   for(std::set<MVertex *>::iterator itv = allNodes.begin(); itv !=allNodes.end() ; ++itv){
     MVertex *v = *itv;
     myAssembler.numberVertex(v, 0, 1);
     myAssembler.numberVertex(v, 0, 2);
-
   }
 
   simpleFunction<double> ONE(1.0);
@@ -1143,48 +1138,91 @@ bool GFaceCompound::parametrize_conformal_spectral() const
       cross21.addToMatrix(myAssembler, &se);
     }
   }
+  double epsilon = 1.e-6;
+  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,  epsilon);
+        myAssembler.assemble(v, 0, 2, v, 0, 2,  epsilon);
+      }
+  }
 
   //-------------------------------
    myAssembler.setCurrentMatrix("B");
-
    for(std::set<MVertex *>::iterator itv = allNodes.begin(); itv !=allNodes.end() ; ++itv){
      MVertex *v = *itv;
      myAssembler.numberVertex(v, 0, 1);
      myAssembler.numberVertex(v, 0, 2);
    }
-   
-   diagBCTerm diag1(0, 1, &ONE);
-   diagBCTerm diag2(0, 2, &ONE);
-   it = _compound.begin(); 
-   for( ; it != _compound.end() ; ++it){
-     for(unsigned int i = 0; i < (*it)->triangles.size(); ++i){
-       SElement se((*it)->triangles[i]);
-       diag1.addToMatrix(myAssembler, &se);
-       diag2.addToMatrix(myAssembler, &se);
+      
+   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);
      }
    }
+//    int NB = ordered.size();
+//    for(std::vector<MVertex *>::iterator itv1 = ordered.begin(); itv1 !=ordered.end() ; ++itv1){
+//      for(std::vector<MVertex *>::iterator itv2 = ordered.begin(); itv2 !=ordered.end() ; ++itv2){
+//        myAssembler.assemble(*itv1, 0, 1, *itv2, 0, 1,  -1/NB);
+//        myAssembler.assemble(*itv1, 0, 2, *itv2, 0, 2,  -1/NB);
+//      }
+//    }
+
+//    diagBCTerm diag1(0, 1, &ONE);
+//    diagBCTerm diag2(0, 2, &ONE);
+//    it = _compound.begin(); 
+//    for( ; it != _compound.end() ; ++it){
+//      for(unsigned int i = 0; i < (*it)->triangles.size(); ++i){
+//        SElement se((*it)->triangles[i]);
+//        diag1.addToMatrix(myAssembler, &se);
+//        diag2.addToMatrix(myAssembler, &se);
+//      }
+//    }
 
    //-------------------------------
-   eigenSolver eig(&myAssembler, "A" ); //, "B");
-   //eig.solve(1, "largest");
-   eig.solve(1, "smallestReal");
-   //printf("num eigenvalues =%d \n", eig.getNumEigenValues());
-   
-   int k = 0;
-   std::vector<std::complex<double> > &ev = eig.getEigenVector(0); 
-   for(std::set<MVertex *>::iterator itv = allNodes.begin(); itv !=allNodes.end() ; ++itv){
-     MVertex *v = *itv;
-     double paramu = ev[k].real();
-     double paramv = ev[k+1].real();
-     coordinates[v] = SPoint3(paramu,paramv,0.0);
-     k = k+2;
+   eigenSolver eig(&myAssembler, "B" , "A", true);
+   bool converged = eig.solve(2, "largest");
+     
+   if(converged) {
+     int k = 0;
+     std::vector<std::complex<double> > &ev = eig.getEigenVector(0); 
+     for(std::set<MVertex *>::iterator itv = allNodes.begin(); itv !=allNodes.end() ; ++itv){
+       MVertex *v = *itv;
+       double paramu = ev[k].real();
+       double paramv = ev[k+1].real();
+       coordinates[v] = SPoint3(paramu,paramv,0.0);
+       k = k+2;
+     }
+     
+     //if folding take second sallest eigenvalue
+     bool noFolding = checkFolding(ordered);
+     if (!noFolding ){
+       coordinates.clear();
+       int k = 0;
+       std::vector<std::complex<double> > &ev = eig.getEigenVector(1); 
+       for(std::set<MVertex *>::iterator itv = allNodes.begin(); itv !=allNodes.end() ; ++itv){
+	 MVertex *v = *itv;
+	 double paramu = ev[k].real();
+	 double paramv = ev[k+1].real();
+	 coordinates[v] = SPoint3(paramu,paramv,0.0);
+	 k = k+2;
+       }
+     }
+
+     lsysA->clear();
+     lsysB->clear();
+
+     return checkFolding(ordered);
+
    }
-  
-   lsysA->clear();
-   lsysB->clear();
-   
-   //check for folding
-   return checkFolding(ordered);
+   else return false;
 
 #else
    return false;
diff --git a/Solver/eigenSolver.cpp b/Solver/eigenSolver.cpp
index d87b8d97621f68aa77d2783d6c24ee6a4ab363aa..9a582c7e564f905a55ad4c4292498b203481ae4c 100644
--- a/Solver/eigenSolver.cpp
+++ b/Solver/eigenSolver.cpp
@@ -4,13 +4,14 @@
 // bugs and problems to <gmsh@geuz.org>.
 
 #include "eigenSolver.h"
+#include "OS.h"
 
 #if defined(HAVE_SLEPC)
 
 #include <slepceps.h>
 
 eigenSolver::eigenSolver(dofManager<double> *manager, std::string A, 
-                         std::string B) : _A(0), _B(0)
+                         std::string B, bool hermitian) : _A(0), _B(0),_hermitian(hermitian)
 {
   if(A.size()){
     _A = dynamic_cast<linearSystemPETSc<double>*>(manager->getLinearSystem(A));
@@ -20,11 +21,13 @@ eigenSolver::eigenSolver(dofManager<double> *manager, std::string A,
     _B = dynamic_cast<linearSystemPETSc<double>*>(manager->getLinearSystem(B));
     if(!_B) Msg::Error("Could not find PETSc system '%s'", B.c_str());
   }
+
 }
 
-void eigenSolver::solve(int numEigenValues, std::string which)
+bool eigenSolver::solve(int numEigenValues, std::string which)
 {
-  if(!_A) return;
+
+  if(!_A) return false;
   Mat A = _A->getMatrix();
   Mat B = _B ? _B->getMatrix() : PETSC_NULL;
    
@@ -44,26 +47,17 @@ void eigenSolver::solve(int numEigenValues, std::string which)
   EPS eps;
   _try(EPSCreate(PETSC_COMM_WORLD, &eps));
   _try(EPSSetOperators(eps, A, B));
-  bool hermitian = false; // FIXME
-  if(hermitian)
+  if(_hermitian)
     _try(EPSSetProblemType(eps, _B ? EPS_GHEP : EPS_HEP));
   else
     _try(EPSSetProblemType(eps, _B ? EPS_GNHEP : EPS_NHEP));
 
-//   EPSSetProblemType(eps, EPS_GNHEP);
-//   ST st;
-//   EPSGetST(eps,&st);
-//   KSP ksp;
-//   PC pc;
-//   STGetKSP(st,&ksp); 
-//   KSPGetPC(ksp, &pc);
-//   PCSetType(pc, PCJACOBI);
-//   PCFactorSetMatOrderingType(pc, MATORDERING_RCM);
-//   STSetType(st,STSINV);
-//   STSetShift(st,0.0);
-
   // set some default options
-  _try(EPSSetDimensions(eps, 5, PETSC_DECIDE, PETSC_DECIDE));
+  _try(EPSSetDimensions(eps, numEigenValues, PETSC_DECIDE, PETSC_DECIDE));
+  _try(EPSSetTolerances(eps,1.e-7,100));
+  _try(EPSSetType(eps,EPSARNOLDI)); //EPSKRYLOVSCHUR is default
+  //_try(EPSSetType(eps,EPSARPACK)); 
+  //_try(EPSSetType(eps,EPSPOWER));
 
   // override these options at runtime, petsc-style
   _try(EPSSetFromOptions(eps));
@@ -93,15 +87,18 @@ void eigenSolver::solve(int numEigenValues, std::string which)
 
   // solve
   Msg::Info("SLEPc solving...");
+  double t1 = Cpu();
   _try(EPSSolve(eps));
-
+ 
   // check convergence
   int its;
   _try(EPSGetIterationNumber(eps, &its));
   EPSConvergedReason reason;
   _try(EPSGetConvergedReason(eps, &reason));
-  if(reason == EPS_CONVERGED_TOL)
-    Msg::Info("SLEPc converged in %d iterations", its);
+  if(reason == EPS_CONVERGED_TOL){
+    double t2 = Cpu();
+    Msg::Info("SLEPc converged in %d iterations (%g s)", its, t2-t1);
+  }
   else if(reason == EPS_DIVERGED_ITS)
     Msg::Error("SLEPc diverged after %d iterations", its);
   else if(reason == EPS_DIVERGED_BREAKDOWN)
@@ -110,55 +107,70 @@ void eigenSolver::solve(int numEigenValues, std::string which)
     Msg::Error("The operator is nonsymmetric");
   
   // get number of converged approximate eigenpairs
-  PetscInt nconv;
-  _try(EPSGetConverged(eps, &nconv));
-  Msg::Info("SLEPc number of converged eigenpairs: %d", nconv);
-
-  // ignore additional eigenvalues if we get more than what we asked
-  if(nconv > nev) nconv = nev;
-
-  Vec xr, xi;
-  _try(MatGetVecs(A, PETSC_NULL, &xr));
-  _try(MatGetVecs(A, PETSC_NULL, &xi));
-  Msg::Info("         Re[EigenValue]          Im[EigenValue]"
-            "          Relative error");
-  for (int i = 0; i < nconv; i++){
-    PetscScalar kr, ki;
-    _try(EPSGetEigenpair(eps, i, &kr, &ki, xr, xi));
-    PetscReal error;
-    _try(EPSComputeRelativeError(eps, i, &error));
+    PetscInt nconv;
+    _try(EPSGetConverged(eps, &nconv));
+    Msg::Info("SLEPc number of converged eigenpairs: %d", nconv);
+    
+    if (nconv>0) {
+
+    // ignore additional eigenvalues if we get more than what we asked
+    if(nconv > nev) nconv = nev;
+    
+    Vec xr, xi;
+    _try(MatGetVecs(A, PETSC_NULL, &xr));
+    _try(MatGetVecs(A, PETSC_NULL, &xi));
+    Msg::Info("         Re[EigenValue]          Im[EigenValue]"
+	      "          Relative error");
+    for (int i = 0; i < nconv; i++){
+      PetscScalar kr, ki;
+      _try(EPSGetEigenpair(eps, i, &kr, &ki, xr, xi));
+      PetscReal error;
+      _try(EPSComputeRelativeError(eps, i, &error));
 #if defined(PETSC_USE_COMPLEX)
-    PetscReal re = PetscRealPart(kr);
-    PetscReal im = PetscImaginaryPart(kr);
+      PetscReal re = PetscRealPart(kr);
+      PetscReal im = PetscImaginaryPart(kr);
 #else
-    PetscReal re = kr;
-    PetscReal im = ki;
+      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);
-
-    // store eigenvalues and eigenvectors
-    _eigenValues.push_back(std::complex<double>(re, im));
-    PetscScalar *tmpr, *tmpi;
-    _try(VecGetArray(xr, &tmpr));
-    _try(VecGetArray(xi, &tmpi));
-    std::vector<std::complex<double> > ev(N);
-    for(int i = 0; i < N; i++){
+      Msg::Info("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));
+      PetscScalar *tmpr, *tmpi;
+      _try(VecGetArray(xr, &tmpr));
+      _try(VecGetArray(xi, &tmpi));
+      std::vector<std::complex<double> > ev(N);
+      for(int i = 0; i < N; i++){
 #if defined(PETSC_USE_COMPLEX)
-      ev[i] = tmpr[i];
+	ev[i] = tmpr[i];
 #else
-      ev[i] = std::complex<double>(tmpr[i], tmpi[i]);
+	ev[i] = std::complex<double>(tmpr[i], tmpi[i]);
 #endif
+      }
+      _eigenVectors.push_back(ev);
     }
-    _eigenVectors.push_back(ev);
+    
+    // cleanup
+    _try(EPSDestroy(eps));
+    _try(VecDestroy(xr));
+    _try(VecDestroy(xi));
+    _try(SlepcFinalize());
+
   }
+
+
   
-  // cleanup
-  _try(EPSDestroy(eps));
-  _try(VecDestroy(xr));
-  _try(VecDestroy(xi));
-  _try(SlepcFinalize());
-  Msg::Info("SLEPc done");
+  if(reason == EPS_CONVERGED_TOL){
+    Msg::Info("SLEPc done");
+    return true;
+  }
+  else{
+    Msg::Info("SLEPc failed");
+    return false;
+  }
+
 }
 
 #endif
diff --git a/Solver/eigenSolver.h b/Solver/eigenSolver.h
index a0ddcd0b9b8fb46af2a477a7729d64fc38475bf9..d4c9394d81111199c364b12c2d0db27cc28dec4f 100644
--- a/Solver/eigenSolver.h
+++ b/Solver/eigenSolver.h
@@ -20,13 +20,14 @@
 class eigenSolver{
  private:
   linearSystemPETSc<double> *_A, *_B;
+  bool _hermitian;
   std::vector<std::complex<double> > _eigenValues;
   std::vector<std::vector<std::complex<double> > > _eigenVectors;
   void _try(int ierr) const { CHKERRABORT(PETSC_COMM_WORLD, ierr); }
  public:
   eigenSolver(dofManager<double> *manager, std::string A, 
-              std::string B="");
-  void solve(int numEigenValues=0, std::string which="");
+              std::string B="", bool hermitian=false);
+  bool solve(int numEigenValues=0, std::string which="");
   int getNumEigenValues(){ return _eigenValues.size(); }
   std::complex<double> getEigenValue(int num){ return _eigenValues[num]; }
   std::vector<std::complex<double> > &getEigenVector(int num){ return _eigenVectors[num]; }
@@ -39,7 +40,7 @@ class eigenSolver{
   std::vector<std::complex<double> > _dummy;
  public:
   eigenSolver(dofManager<double> *manager, std::string A, 
-              std::string B=""){}
+              std::string B="", bool hermitian=false){}
   void solve(int numEigenValues=0, std::string which="")
   {
     Msg::Error("Eigen solver requires SLEPc");