diff --git a/Solver/elasticitySolver.cpp b/Solver/elasticitySolver.cpp
index be544939fc1b15d55efc410c1b388cd398127fe9..ceb4c2d9df1645b0b7db2543f0027e7b502c3151 100644
--- a/Solver/elasticitySolver.cpp
+++ b/Solver/elasticitySolver.cpp
@@ -25,31 +25,29 @@
 #include "PViewData.h"
 #endif
 
+
 /*
-static void printLinearSystem(linearSystemCSRTaucs<double> *lsys)
-{
-  int *startIndex;
-  int *columns;
-  double *values;
-  lsys->getMatrix(startIndex, columns, values);
-  for(int i = 0; i < lsys->getNbUnk(); i++){
-    std::cout<<"a ";
-    for(int j = 0; j < lsys->getNbUnk(); j++){
-      double val = 0.;
-      for(int k = startIndex[i]; k < startIndex[i+1]; k++){
-        if(columns[k] == j) {val = values[k]; break;}
-      }
-      std::cout<< val <<" ";
+static void printLinearSystem(linearSystem<double> *lsys, int size)
+{
+  if(!lsys->isAllocated()){printf("Linear system not allocated\n"); return;}
+  double valeur;
+  printf("K\n");
+  for (int i = 0; i < size; i++){
+    for (int j = 0; j < size; j++ ){
+      lsys->getFromMatrix (i, j, valeur);
+      printf ("%g ", valeur) ;
     }
-    std::cout<<std::endl;
-  }std::cout<<std::endl;
-  for(int i = 0; i < lsys->getNbUnk(); i++) {
-    double val; lsys->getFromRightHandSide(i,val);
-    std::cout<<"b "<<val<<std::endl;
-  }std::cout<<std::endl;
-  for(int i = 0; i < lsys->getNbUnk(); i++) {
-    double val; lsys->getFromSolution(i,val);
-    std::cout<<"x "<<val<<std::endl;
+    printf("\n");
+  }
+  printf("b\n");
+  for (int i = 0; i < size; i++){
+    lsys->getFromRightHandSide(i, valeur);
+    printf("%g\n", valeur);
+  }
+  printf("x\n");
+  for (int i = 0; i < size; i++){
+    lsys->getFromSolution(i, valeur);
+    printf("%g\n", valeur);
   }
 }
 */
@@ -67,7 +65,7 @@ void elasticitySolver::setMesh(const std::string &meshFileName)
                   VectorLagrangeFunctionSpace::VECTOR_Y);
 
   if (LagrangeMultiplierSpace) delete LagrangeMultiplierSpace;
-  LagrangeMultiplierSpace = new ScalarLagrangeFunctionSpace(_tag+1);
+  LagrangeMultiplierSpace = new ScalarLagrangeFunctionSpaceOfElement(_tag+1);
 }
 
 void elasticitySolver::exportKb()
@@ -97,7 +95,6 @@ void elasticitySolver::exportKb()
 
 void elasticitySolver::solve()
 {
-
   //linearSystemFull<double> *lsys = new linearSystemFull<double>;
 
 #if defined(HAVE_TAUCS)
@@ -110,13 +107,12 @@ void elasticitySolver::solve()
 #endif
 
   assemble(lsys);
+  //printLinearSystem(lsys,pAssembler->sizeOfR());
   lsys->systemSolve();
   printf("-- done solving!\n");
-  GaussQuadrature Integ_Bulk(GaussQuadrature::GradGrad);
-
-//   printLinearSystem(lsys);
 
   double energ=0;
+  GaussQuadrature Integ_Bulk(GaussQuadrature::GradGrad);
   for (unsigned int i = 0; i < elasticFields.size(); i++){
     SolverField<SVector3> Field(pAssembler, LagSpace);
     IsotropicElasticTerm Eterm(Field,elasticFields[i]._E,elasticFields[i]._nu);
@@ -157,7 +153,8 @@ void elasticitySolver::readInputFile(const std::string &fn)
     }
     if(what[0]=='#'){
       char buffer[1024];
-      fgets(buffer, sizeof(buffer), f);
+      if(fgets(buffer, sizeof(buffer), f) == NULL) 
+        Msg::Error("Cannot read line.");
     }
     else if (!strcmp(what, "ElasticDomain")){
       elasticField field;
@@ -348,6 +345,46 @@ void elasticitySolver::readInputFile(const std::string &fn)
 }
 
 
+void elasticitySolver::cutMesh(gLevelset *ls)
+{
+  pModel = pModel->buildCutGModel(ls);
+  pModel->writeMSH("cutMesh.msh");
+}
+
+void elasticitySolver::setElasticDomain(int phys, double E, double nu)
+{
+  elasticField field;
+  field._E = E;
+  field._nu = nu;
+  field._tag = _tag;
+  field.g = new groupOfElements (_dim, phys);
+  elasticFields.push_back(field);
+}
+
+void elasticitySolver::setLagrangeMultipliers(int phys, double tau, SVector3 d,
+                                              int tag, simpleFunction<double> *f)
+{
+  LagrangeMultiplierField field;
+  field._tau = tau;
+  field._tag = tag;
+  field._f = f;
+  field._d = d;
+  field.g = new groupOfElements (_dim - 1, phys);
+  LagrangeMultiplierFields.push_back(field);
+}
+
+void elasticitySolver::setEdgeDisp(int edge, int comp, simpleFunction<double> *f)
+{
+  dirichletBC diri;
+  diri.g = new groupOfElements (1, edge);
+  diri._f = f;
+  diri._comp = comp;
+  diri._tag = edge;
+  diri.onWhat = BoundaryCondition::ON_EDGE;
+  allDirichlet.push_back(diri);
+}
+
+
 void elasticitySolver::addDirichletBC(int dim, int entityId, int component, double value)
 {
   dirichletBC diri;
@@ -418,7 +455,7 @@ elasticitySolver::elasticitySolver(GModel *model, int tag)
   if (_dim==2) LagSpace=new VectorLagrangeFunctionSpace(_tag,
                 VectorLagrangeFunctionSpace::VECTOR_X,
                 VectorLagrangeFunctionSpace::VECTOR_Y);
-  LagrangeMultiplierSpace = new ScalarLagrangeFunctionSpace(_tag+1);
+  LagrangeMultiplierSpace = new ScalarLagrangeFunctionSpaceOfElement(_tag+1);
 }
 
 void elasticitySolver::assemble(linearSystem<double> *lsys)
@@ -465,18 +502,21 @@ void elasticitySolver::assemble(linearSystem<double> *lsys)
   GaussQuadrature Integ_LagrangeMult(GaussQuadrature::ValVal);
   GaussQuadrature Integ_Laplace(GaussQuadrature::GradGrad);
   for (unsigned int i = 0; i < LagrangeMultiplierFields.size(); i++){
+    printf("Lagrange Mult Lag\n");
     LagrangeMultiplierTerm<SVector3> LagTerm(*LagSpace, *LagrangeMultiplierSpace,
                                              LagrangeMultiplierFields[i]._d);
     Assemble(LagTerm, *LagSpace, *LagrangeMultiplierSpace,
              LagrangeMultiplierFields[i].g->begin(),
              LagrangeMultiplierFields[i].g->end(), Integ_LagrangeMult, *pAssembler);
 
+    printf("Lagrange Mult Lap\n");
     LaplaceTerm<double,double> LapTerm(*LagrangeMultiplierSpace,
                                        LagrangeMultiplierFields[i]._tau);
     Assemble(LapTerm, *LagrangeMultiplierSpace, LagrangeMultiplierFields[i].g->begin(),
              LagrangeMultiplierFields[i].g->end(), Integ_Laplace, *pAssembler);
 
-    LoadTerm<double> Lterm(*LagrangeMultiplierSpace, LagrangeMultiplierFields[i]._f);
+    printf("Lagrange Mult Load\n");
+    LoadTermOnBorder<double> Lterm(*LagrangeMultiplierSpace, LagrangeMultiplierFields[i]._f);
     Assemble(Lterm, *LagrangeMultiplierSpace, LagrangeMultiplierFields[i].g->begin(),
              LagrangeMultiplierFields[i].g->end(), Integ_Boundary, *pAssembler);
   }
@@ -488,15 +528,6 @@ void elasticitySolver::assemble(linearSystem<double> *lsys)
              Integ_Bulk, *pAssembler);
   }
 
-  /*for (int i=0;i<pAssembler->sizeOfR();i++){
-    for (int j=0;j<pAssembler->sizeOfR();j++){
-      double d;lsys->getFromMatrix(i,j,d);
-      printf("%12.5E ",d);
-    }
-    double d;lsys->getFromRightHandSide(i,d);
-    printf(" |  %12.5E\n",d);
-  }*/
-
   printf("nDofs=%d\n",pAssembler->sizeOfR());
   printf("nFixed=%d\n",pAssembler->sizeOfF());
 
@@ -606,6 +637,53 @@ void elasticitySolver::computeEffectiveStrain(std::vector<double> strain)
     strain[i] = st[i] / volTot;
 }
 
+double elasticitySolver::computeDisplacementError(int comp, simpleFunction<double> *sol) {
+  std::cout <<  "compute displacement error"<< std::endl;
+  double err = 0.;
+  std::set<MVertex*> v;
+  std::map<MVertex*, MElement*> vCut;
+  for (unsigned int i = 0; i < elasticFields.size(); ++i){
+    if(elasticFields[i]._E == 0.) continue;
+    for (groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin();
+         it != elasticFields[i].g->end(); ++it){
+      MElement *e = *it;
+      if(e->getParent()) {
+        for (int j = 0; j < e->getNumVertices(); ++j) {
+          if(vCut.find(e->getVertex(j)) == vCut.end())
+            vCut[e->getVertex(j)] = e->getParent();
+        }
+      }
+      else {
+        for (int j = 0; j < e->getNumVertices(); ++j)
+          v.insert(e->getVertex(j));
+      }
+    }
+  }
+  SolverField<SVector3> Field(pAssembler, LagSpace);
+  for (std::set<MVertex*>::iterator it = v.begin(); it != v.end(); ++it){
+    SVector3 val;
+    MPoint p(*it);
+    Field.f(&p, 0, 0, 0, val);
+    double diff = (*sol)((*it)->x(), (*it)->y(), (*it)->z()) - val(comp);
+    err += diff * diff;
+  }
+  for (std::map<MVertex*,MElement*>::iterator it = vCut.begin(); it != vCut.end(); ++it){
+    SVector3 val;
+    double uvw[3];
+    double xyz[3] = {it->first->x(), it->first->y(), it->first->z()};
+    it->second->xyz2uvw(xyz, uvw);
+    Field.f(it->second, uvw[0], uvw[1], uvw[2], val);
+    double diff = (*sol)(xyz[0], xyz[1], xyz[2]) - val(comp);
+    err += diff * diff;
+  }
+printf("Displacement Error (comp=%d) = %g\n",comp,sqrt(err));
+  return sqrt(err);
+}
+
+double elasticitySolver::computeLagNorm(int tag, simpleFunction<double> *sol) {
+  return 0;
+}
+
 #if defined(HAVE_POST)
 
 PView* elasticitySolver::buildDisplacementView (const std::string postFileName)
diff --git a/Solver/elasticitySolver.h b/Solver/elasticitySolver.h
index 16d69d3aaa5727987431bb63717544ff54ec12c0..7419c637f1456f32b57d85b1e2ec841518bf7d11 100644
--- a/Solver/elasticitySolver.h
+++ b/Solver/elasticitySolver.h
@@ -16,6 +16,7 @@ template <class scalar> class simpleFunction;
 class GModel;
 class PView;
 class groupOfElements;
+class gLevelset;
 
 struct LagrangeMultiplierField {
   int _tag;
@@ -95,6 +96,10 @@ class elasticitySolver
   void readInputFile(const std::string &meshFileName);
   void read(const std::string s) {readInputFile(s.c_str());}
   virtual void setMesh(const std::string &meshFileName);
+  void cutMesh(gLevelset *ls);
+  void setElasticDomain(int phys, double E, double nu);
+  void setLagrangeMultipliers(int phys, double tau, SVector3 d, int tag, simpleFunction<double> *f);
+  void setEdgeDisp(int edge, int comp, simpleFunction<double> *f);
   void solve();
   void postSolve();
   void exportKb();
@@ -107,6 +112,8 @@ class elasticitySolver
   virtual PView *buildElasticEnergyView(const std::string postFileName);
   virtual PView *buildVonMisesView(const std::string postFileName);
   virtual PView *buildVolumeView(const std::string postFileName);
+  double computeDisplacementError(int comp, simpleFunction<double> *f);
+  double computeLagNorm(int tag, simpleFunction<double> *f);
   // std::pair<PView *, PView*> buildErrorEstimateView
   //   (const std::string &errorFileName, double, int);
   // std::pair<PView *, PView*> buildErrorEstimateView
diff --git a/Solver/thermicSolver.cpp b/Solver/thermicSolver.cpp
index d4240179187fba0cfa1c390522910ef7154cb06a..d2b8672cec6d8412de8eb6863d764bbc8542df99 100644
--- a/Solver/thermicSolver.cpp
+++ b/Solver/thermicSolver.cpp
@@ -68,6 +68,15 @@ void thermicSolver::setThermicDomain(int phys, double k)
   thermicFields.push_back(field);
 }
 
+void thermicSolver::changeLMTau(int tag, double tau)
+{
+  for(unsigned int i = 0; i < LagrangeMultiplierFields.size(); i++){
+    if(LagrangeMultiplierFields[i]._tag == tag){
+      LagrangeMultiplierFields[i]._tau = tau;
+    }
+  }
+}
+
 void thermicSolver::setLagrangeMultipliers(int phys, double tau, int tag, simpleFunction<double> *f)
 {
   LagrangeMultiplierFieldT field;
@@ -88,6 +97,16 @@ void thermicSolver::setEdgeTemp(int edge, simpleFunction<double> *f)
   allDirichlet.push_back(diri);
 }
 
+void thermicSolver::setFaceTemp(int face, simpleFunction<double> *f)
+{
+  dirichletBCT diri;
+  diri.g = new groupOfElements (2, face);
+  diri._f = f;
+  diri._tag = face;
+  diri.onWhat = BoundaryConditionT::ON_FACE;
+  allDirichlet.push_back(diri);
+}
+
 void thermicSolver::assemble(linearSystem<double> *lsys)
 {
   if (pAssembler) delete pAssembler;
@@ -201,7 +220,7 @@ double thermicSolver::computeLagNorm(int tag, simpleFunction<double> *sol) {
     for(groupOfElements::elementContainer::const_iterator it = LagrangeMultiplierFields[i].g->begin();
         it != LagrangeMultiplierFields[i].g->end(); ++it){
       MElement *e = *it;
-printf("element (%g,%g) (%g,%g)\n",e->getVertex(0)->x(),e->getVertex(0)->y(),e->getVertex(1)->x(),e->getVertex(1)->y());
+//printf("element (%g,%g) (%g,%g)\n",e->getVertex(0)->x(),e->getVertex(0)->y(),e->getVertex(1)->x(),e->getVertex(1)->y());
       int npts;
       IntPt *GP;
       double jac[3][3];
@@ -220,7 +239,7 @@ printf("element (%g,%g) (%g,%g)\n",e->getVertex(0)->x(),e->getVertex(0)->y(),e->
         double diff = (*sol)(p.x(), p.y(), p.z()) - FEMVALUE;
         val += diff * diff * detJ * weight;
         val2 += (*sol)(p.x(), p.y(), p.z()) * (*sol)(p.x(), p.y(), p.z()) * detJ * weight;
-printf("(%g %g) : u,v=(%g,%g) detJ=%g we=%g FV=%g sol=%g diff=%g\n",p.x(),p.y(),u,v,detJ,weight,FEMVALUE,(*sol)(p.x(), p.y(), p.z()),diff);
+//printf("(%g %g) : u,v=(%g,%g) detJ=%g we=%g FV=%g sol=%g diff=%g\n",p.x(),p.y(),u,v,detJ,weight,FEMVALUE,(*sol)(p.x(), p.y(), p.z()),diff);
       }
     }
   }
@@ -298,6 +317,45 @@ PView* thermicSolver::buildLagrangeMultiplierView (const std::string postFileNam
   return pv;
 }
 
+PView* thermicSolver::buildErrorEstimateView(const std::string errorFileName,
+                                             simpleFunction<double> *sol)
+{
+  std::cout <<  "build Error View"<< std::endl;
+  std::map<int, std::vector<double> > data;
+
+  SolverField<double> solField(pAssembler, LagSpace);
+  for (unsigned int i = 0; i < thermicFields.size(); ++i){
+    for (groupOfElements::elementContainer::const_iterator it = thermicFields[i].g->begin(); it != thermicFields[i].g->end(); ++it){
+      MElement *e = *it;
+      int npts;
+      IntPt *GP;
+      double jac[3][3];
+      int integrationOrder = 2 * (e->getPolynomialOrder()+5);
+      e->getIntegrationPoints(integrationOrder, &npts, &GP);
+      double val = 0.0;
+      for (int j = 0; j < npts; j++){
+        double u = GP[j].pt[0];
+        double v = GP[j].pt[1];
+        double w = GP[j].pt[2];
+        double weight = GP[j].weight;
+        double detJ = fabs(e->getJacobian (u, v, w, jac));
+        SPoint3 p;
+        e->pnt(u, v, w, p);
+	double FEMVALUE;
+	solField.f(e, u, v, w, FEMVALUE);
+        double diff = (*sol)(p.x(), p.y(), p.z()) - FEMVALUE;
+        val += diff * diff * detJ * weight;
+      }
+      std::vector<double> vec;
+      vec.push_back(sqrt(val));
+      data[e->getNum()] = vec;
+    }
+  }
+
+  PView *pv = new PView (errorFileName, "ElementData", pModel, data, 0.0, 1);
+  return pv;
+}
+
 #else
 PView* thermicSolver::buildTemperatureView(const std::string postFileName)
 {
@@ -310,6 +368,12 @@ PView* thermicSolver::buildLagrangeMultiplierView (const std::string postFileNam
   Msg::Error("Post-pro module not available");
   return 0;
 }
+
+PView* thermicSolver::buildErrorEstimateView(const std::string errorFileName)
+{
+  Msg::Error("Post-pro module not available");
+  return 0;
+}
 #endif
 
 
diff --git a/Solver/thermicSolver.h b/Solver/thermicSolver.h
index 2f715c9149f085b3e520fa33e983ce82a5fceed3..d884c6f5140334f01db0a316c583eb1070403776 100644
--- a/Solver/thermicSolver.h
+++ b/Solver/thermicSolver.h
@@ -85,14 +85,16 @@ class thermicSolver
   void cutMesh(gLevelset *ls);
   void setThermicDomain(int phys, double k);
   void setLagrangeMultipliers(int phys, double tau, int tag, simpleFunction<double> *f);
+  void changeLMTau(int tag, double tau);
   void setEdgeTemp(int edge, simpleFunction<double> *f);
+  void setFaceTemp(int face, simpleFunction<double> *f);
   void solve();
   virtual PView *buildTemperatureView(const std::string postFileName);
-  virtual PView *buildLagrangeMultiplierView(const std::string posFileName);
+  virtual PView *buildLagrangeMultiplierView(const std::string postFileName);
   double computeL2Norm(simpleFunction<double> *f);
   double computeLagNorm(int tag, simpleFunction<double> *f);
-  // std::pair<PView *, PView*> buildErrorEstimateView
-  //   (const std::string &errorFileName, double, int);
+  PView* buildErrorEstimateView(const std::string errorFileName,
+                                simpleFunction<double> *sol);
   // std::pair<PView *, PView*> buildErrorEstimateView
   //   (const std::string &errorFileName, const elasticityData &ref, double, int);
 };