From a9629f47c9c920b8924e29d9a59c6de9f28b2ba4 Mon Sep 17 00:00:00 2001
From: Gauthier Becker <gauthierbecker@gmail.com>
Date: Thu, 24 Mar 2011 15:58:02 +0000
Subject: [PATCH] NonLinearSolver beta dgshell v 1.0 lua --> python

---
 CMakeLists.txt                                |   11 +
 Common/gmshpy.i                               |    1 -
 Mesh/BoundaryLayers.cpp                       |   30 +-
 Mesh/meshGFaceOptimize.cpp                    |  352 ++--
 .../BoundaryConditions/CMakeLists.txt         |   10 +
 .../BoundaryConditions/nonLinearBC.cpp        |   11 +
 .../BoundaryConditions/nonLinearBC.h          |  134 ++
 NonLinearSolver/CMakeLists.txt                |   16 +-
 NonLinearSolver/Domain/CMakeLists.txt         |   11 +
 NonLinearSolver/Domain/partDomain.cpp         |   83 +
 NonLinearSolver/Domain/partDomain.h           |  220 ++
 NonLinearSolver/Interface/CMakeLists.txt      |   15 +
 NonLinearSolver/Interface/IEdge.cpp           |   12 +
 NonLinearSolver/Interface/IEdge.h             |   32 +
 NonLinearSolver/Interface/IElement.cpp        |   12 +
 NonLinearSolver/Interface/IElement.h          |   38 +
 .../Interface/InterfaceBuilder.cpp            |   66 +
 NonLinearSolver/Interface/InterfaceBuilder.h  |   66 +
 .../Interface/MInterfaceElement.cpp           |   49 +
 NonLinearSolver/Interface/MInterfaceElement.h |   31 +
 NonLinearSolver/Interface/MInterfaceLine.cpp  |  111 +
 NonLinearSolver/Interface/MInterfaceLine.h    |   58 +
 NonLinearSolver/contact/CMakeLists.txt        |   16 +
 NonLinearSolver/contact/contactDomain.cpp     |  115 +
 NonLinearSolver/contact/contactDomain.h       |  108 +
 .../contact/contactFunctionSpace.h            |   85 +
 NonLinearSolver/contact/contactTerms.cpp      |   51 +
 NonLinearSolver/contact/contactTerms.h        |   80 +
 .../contact/nodeStiffnessContact.h            |   62 +
 .../contact/rigidCylinderContactTerms.cpp     |  188 ++
 .../contact/rigidCylinderContactTerms.h       |  113 +
 NonLinearSolver/field/CMakeLists.txt          |   12 +
 NonLinearSolver/field/elementField.cpp        |  130 ++
 NonLinearSolver/field/elementField.h          |   51 +
 NonLinearSolver/field/energyField.cpp         |  173 ++
 NonLinearSolver/field/energyField.h           |   89 +
 NonLinearSolver/internalPoints/CMakeLists.txt |    3 +
 NonLinearSolver/internalPoints/ipField.cpp    |  293 +++
 NonLinearSolver/internalPoints/ipField.h      |  237 +++
 NonLinearSolver/internalPoints/ipstate.cpp    |  124 ++
 NonLinearSolver/internalPoints/ipstate.h      |   74 +
 NonLinearSolver/internalPoints/ipvariable.h   |   93 +
 NonLinearSolver/materialLaw/CMakeLists.txt    |   11 +
 NonLinearSolver/materialLaw/mlaw.cpp          |   26 +
 NonLinearSolver/materialLaw/mlaw.h            |   94 +
 NonLinearSolver/nlTerms/CMakeLists.txt        |   11 +
 NonLinearSolver/nlTerms/nlTerms.cpp           |  130 ++
 NonLinearSolver/nlTerms/nlTerms.h             |  109 +
 NonLinearSolver/nlsolver/CMakeLists.txt       |   21 +
 NonLinearSolver/nlsolver/Dof3IntType.h        |   32 +
 NonLinearSolver/nlsolver/explicitDofManager.h |  304 +++
 .../nlsolver/explicitHulbertChung.h           |  399 ++++
 NonLinearSolver/nlsolver/nlsolAlgorithms.h    |  228 ++
 .../nlsolver/nonLinearMechSolver.cpp          | 1852 +++++++++++++++++
 .../nlsolver/nonLinearMechSolver.h            |  254 +++
 NonLinearSolver/nlsolver/staticDofManager.h   |  157 ++
 NonLinearSolver/nlsolver/timeFunction.h       |   83 +
 .../nlsolver/unknownDynamicField.cpp          |  179 ++
 .../nlsolver/unknownDynamicField.h            |   51 +
 NonLinearSolver/nlsolver/unknownField.cpp     |  106 +
 NonLinearSolver/nlsolver/unknownField.h       |   64 +
 .../nlsolver/unknownStaticField.cpp           |  298 +++
 NonLinearSolver/nlsolver/unknownStaticField.h |   53 +
 NonLinearSolver/space/CMakeLists.txt          |   11 +
 NonLinearSolver/space/functionSpaceType.h     |   22 +
 Numeric/simpleFunction.h                      |    1 +
 Solver/quadratureRules.h                      |   13 +-
 Solver/terms.h                                |    4 +-
 68 files changed, 7782 insertions(+), 197 deletions(-)
 create mode 100644 NonLinearSolver/BoundaryConditions/CMakeLists.txt
 create mode 100644 NonLinearSolver/BoundaryConditions/nonLinearBC.cpp
 create mode 100644 NonLinearSolver/BoundaryConditions/nonLinearBC.h
 create mode 100644 NonLinearSolver/Domain/CMakeLists.txt
 create mode 100644 NonLinearSolver/Domain/partDomain.cpp
 create mode 100644 NonLinearSolver/Domain/partDomain.h
 create mode 100644 NonLinearSolver/Interface/CMakeLists.txt
 create mode 100644 NonLinearSolver/Interface/IEdge.cpp
 create mode 100644 NonLinearSolver/Interface/IEdge.h
 create mode 100644 NonLinearSolver/Interface/IElement.cpp
 create mode 100644 NonLinearSolver/Interface/IElement.h
 create mode 100644 NonLinearSolver/Interface/InterfaceBuilder.cpp
 create mode 100644 NonLinearSolver/Interface/InterfaceBuilder.h
 create mode 100644 NonLinearSolver/Interface/MInterfaceElement.cpp
 create mode 100644 NonLinearSolver/Interface/MInterfaceElement.h
 create mode 100644 NonLinearSolver/Interface/MInterfaceLine.cpp
 create mode 100644 NonLinearSolver/Interface/MInterfaceLine.h
 create mode 100644 NonLinearSolver/contact/CMakeLists.txt
 create mode 100644 NonLinearSolver/contact/contactDomain.cpp
 create mode 100644 NonLinearSolver/contact/contactDomain.h
 create mode 100644 NonLinearSolver/contact/contactFunctionSpace.h
 create mode 100644 NonLinearSolver/contact/contactTerms.cpp
 create mode 100644 NonLinearSolver/contact/contactTerms.h
 create mode 100644 NonLinearSolver/contact/nodeStiffnessContact.h
 create mode 100644 NonLinearSolver/contact/rigidCylinderContactTerms.cpp
 create mode 100644 NonLinearSolver/contact/rigidCylinderContactTerms.h
 create mode 100644 NonLinearSolver/field/CMakeLists.txt
 create mode 100644 NonLinearSolver/field/elementField.cpp
 create mode 100644 NonLinearSolver/field/elementField.h
 create mode 100644 NonLinearSolver/field/energyField.cpp
 create mode 100644 NonLinearSolver/field/energyField.h
 create mode 100644 NonLinearSolver/internalPoints/ipField.cpp
 create mode 100644 NonLinearSolver/internalPoints/ipField.h
 create mode 100644 NonLinearSolver/internalPoints/ipvariable.h
 create mode 100644 NonLinearSolver/materialLaw/CMakeLists.txt
 create mode 100644 NonLinearSolver/materialLaw/mlaw.cpp
 create mode 100644 NonLinearSolver/materialLaw/mlaw.h
 create mode 100644 NonLinearSolver/nlTerms/CMakeLists.txt
 create mode 100644 NonLinearSolver/nlTerms/nlTerms.cpp
 create mode 100644 NonLinearSolver/nlTerms/nlTerms.h
 create mode 100644 NonLinearSolver/nlsolver/CMakeLists.txt
 create mode 100644 NonLinearSolver/nlsolver/Dof3IntType.h
 create mode 100644 NonLinearSolver/nlsolver/explicitDofManager.h
 create mode 100644 NonLinearSolver/nlsolver/explicitHulbertChung.h
 create mode 100644 NonLinearSolver/nlsolver/nlsolAlgorithms.h
 create mode 100644 NonLinearSolver/nlsolver/nonLinearMechSolver.cpp
 create mode 100644 NonLinearSolver/nlsolver/nonLinearMechSolver.h
 create mode 100644 NonLinearSolver/nlsolver/staticDofManager.h
 create mode 100644 NonLinearSolver/nlsolver/timeFunction.h
 create mode 100644 NonLinearSolver/nlsolver/unknownDynamicField.cpp
 create mode 100644 NonLinearSolver/nlsolver/unknownDynamicField.h
 create mode 100644 NonLinearSolver/nlsolver/unknownField.cpp
 create mode 100644 NonLinearSolver/nlsolver/unknownField.h
 create mode 100644 NonLinearSolver/nlsolver/unknownStaticField.cpp
 create mode 100644 NonLinearSolver/nlsolver/unknownStaticField.h
 create mode 100644 NonLinearSolver/space/CMakeLists.txt
 create mode 100644 NonLinearSolver/space/functionSpaceType.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6ef9cf8feb..7c8312dfab 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -281,6 +281,17 @@ add_subdirectory(Geo)
 
 if(ENABLE_NON_LINEAR_SOLVER)
   add_subdirectory(NonLinearSolver)
+  include_directories(NonLinearSolver/nlsolver)
+  include_directories(NonLinearSolver/BoundaryConditions)
+  include_directories(NonLinearSolver/contact)
+  include_directories(NonLinearSolver/Domain)
+  include_directories(NonLinearSolver/field)
+  include_directories(NonLinearSolver/Interface)
+  include_directories(NonLinearSolver/internalPoints)
+  include_directories(NonLinearSolver/materialLaw)
+  include_directories(NonLinearSolver/nlTerms)
+  include_directories(NonLinearSolver/space)
+  set_config_option(HAVE_NLMECHSOL "NlMechSol")
 endif(ENABLE_NON_LINEAR_SOLVER)
 
 if(ENABLE_MESH)
diff --git a/Common/gmshpy.i b/Common/gmshpy.i
index c225e6672e..a2b6afdd6e 100644
--- a/Common/gmshpy.i
+++ b/Common/gmshpy.i
@@ -128,4 +128,3 @@ namespace std {
 %include "functionPython.h"
 %include "meshGFaceLloyd.h"
 %include "DefaultOptions.h"
-
diff --git a/Mesh/BoundaryLayers.cpp b/Mesh/BoundaryLayers.cpp
index 2863ab8a7b..05b58eeb66 100644
--- a/Mesh/BoundaryLayers.cpp
+++ b/Mesh/BoundaryLayers.cpp
@@ -22,14 +22,14 @@ class OctreePost{ int dummy; };
 #endif
 
 template<class T>
-static void addExtrudeNormals(std::vector<T*> &elements, int invert, 
+static void addExtrudeNormals(std::vector<T*> &elements, int invert,
                               OctreePost *octree, bool gouraud, int index)
 {
   if(index < 0 || index > 1){
     Msg::Error("Boundary layer index should be 0 or 1");
     return;
   }
-  
+
   if(octree && !gouraud){ // get extrusion direction from post-processing view
     std::set<MVertex*> verts;
     for(unsigned int i = 0; i < elements.size(); i++)
@@ -65,7 +65,7 @@ static void addExtrudeNormals(std::vector<T*> &elements, int invert,
 typedef std::set<std::pair<bool, std::pair<int, int> > > infoset;
 
 template<class T>
-static void addExtrudeNormals(std::set<T*> &entities, 
+static void addExtrudeNormals(std::set<T*> &entities,
                               std::map<int, infoset> &infos)
 {
   bool normalize = true, special3dbox = false;
@@ -80,8 +80,8 @@ static void addExtrudeNormals(std::set<T*> &entities,
       int view = it2->second.second;
       bool gouraud = true;
       OctreePost *octree = 0;
-      if(view != -1){
 #if defined(HAVE_POST)
+      if(view != -1){
         if(view >= 0 && view < PView::list.size()){
           octree = new OctreePost(PView::list[view]);
           if(PView::list[view]->getData()->getNumVectors())
@@ -124,7 +124,7 @@ static void addExtrudeNormals(std::set<T*> &entities,
     for(int i = 0; i < 2; i++){
       ExtrudeParams::normals[i]->normalize();
       if(special3dbox){ // force normals for 3d "box" along x,y,z
-        for(smooth_data::iter it = ExtrudeParams::normals[i]->begin(); 
+        for(smooth_data::iter it = ExtrudeParams::normals[i]->begin();
             it != ExtrudeParams::normals[i]->end(); it++){
           for(int j = 0; j < 3; j++){
             if(it->vals[j] < -0.1) it->vals[j] = -1.;
@@ -135,7 +135,7 @@ static void addExtrudeNormals(std::set<T*> &entities,
       }
 #if defined(HAVE_POST)
       if(octrees.size()){ // scale normals by scalar views
-        for(smooth_data::iter it = ExtrudeParams::normals[i]->begin(); 
+        for(smooth_data::iter it = ExtrudeParams::normals[i]->begin();
             it != ExtrudeParams::normals[i]->end(); it++){
           for(unsigned int j = 0; j < octrees.size(); j++){
             double d;
@@ -177,7 +177,7 @@ int Mesh2DWithBoundaryLayers(GModel *m)
   // 2D boundary layers
   for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++){
     GEdge *ge = *it;
-    if(ge->getNativeType() == GEntity::GmshModel && 
+    if(ge->getNativeType() == GEntity::GmshModel &&
        ge->geomType() == GEntity::BoundaryLayerCurve){
       ExtrudeParams *ep = ge->meshAttributes.extrude;
       if(ep && ep->mesh.ExtrudeMesh && ep->geo.Mode == COPIED_ENTITY){
@@ -198,7 +198,7 @@ int Mesh2DWithBoundaryLayers(GModel *m)
   // 3D boundary layers
   for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++){
     GFace *gf = *it;
-    if(gf->getNativeType() == GEntity::GmshModel && 
+    if(gf->getNativeType() == GEntity::GmshModel &&
        gf->geomType() == GEntity::BoundaryLayerSurface){
       ExtrudeParams *ep = gf->meshAttributes.extrude;
       if(ep && ep->mesh.ExtrudeMesh && ep->geo.Mode == COPIED_ENTITY){
@@ -238,14 +238,14 @@ int Mesh2DWithBoundaryLayers(GModel *m)
     if(sourceEdges.find(*it) == sourceEdges.end()) otherEdges.insert(*it);
   for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++)
     if(sourceFaces.find(*it) == sourceFaces.end() &&
-       sourceFacesDependencies.find(*it) == sourceFacesDependencies.end()) 
+       sourceFacesDependencies.find(*it) == sourceFacesDependencies.end())
       otherFaces.insert(*it);
 
   // mesh source surfaces (and dependencies)
   for(int i = 0; i < 10; i++) // FIXME: should check PENDING status instead!
-    std::for_each(sourceFacesDependencies.begin(), sourceFacesDependencies.end(), 
-                  meshGFace());  
-  std::for_each(sourceFaces.begin(), sourceFaces.end(), meshGFace());  
+    std::for_each(sourceFacesDependencies.begin(), sourceFacesDependencies.end(),
+                  meshGFace());
+  std::for_each(sourceFaces.begin(), sourceFaces.end(), meshGFace());
 
   // make sure the source surfaces for the boundary layers are
   // oriented correctly (normally we do this only after the 3D mesh is
@@ -264,7 +264,7 @@ int Mesh2DWithBoundaryLayers(GModel *m)
     addExtrudeNormals(sourceFaces, sourceFaceInfo);
 
   // set the position of boundary layer points using the smooth normal
-  // field 
+  // field
   for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++){
     GEdge *ge = *it;
     if(ge->geomType() == GEntity::BoundaryLayerCurve){
@@ -286,7 +286,7 @@ int Mesh2DWithBoundaryLayers(GModel *m)
       }
     }
   }
-  
+
   // remesh non-source edges (since they might have been modified by
   // the change in boundary layer points)
   std::for_each(otherFaces.begin(), otherFaces.end(), deMeshGFace());
@@ -312,7 +312,7 @@ int Mesh2DWithBoundaryLayers(GModel *m)
   }
 
   // mesh non-source surfaces
-  std::for_each(otherFaces.begin(), otherFaces.end(), meshGFace());  
+  std::for_each(otherFaces.begin(), otherFaces.end(), meshGFace());
 
   // mesh the surfaces bounding the boundary layers by extrusion using
   // the smooth normal field
diff --git a/Mesh/meshGFaceOptimize.cpp b/Mesh/meshGFaceOptimize.cpp
index 1b5c8942fe..abf7b9439f 100644
--- a/Mesh/meshGFaceOptimize.cpp
+++ b/Mesh/meshGFaceOptimize.cpp
@@ -27,12 +27,12 @@
 #ifdef HAVE_MATCH
 extern "C" int FAILED_NODE;
 extern "C" struct CCdatagroup;
-extern "C" int perfect_match 
-(int ncount, CCdatagroup *dat, int ecount,       
- int **elist, int **elen, char *blo_filename,                
- char *mat_filename, int just_fractional, int no_fractional, 
- int use_all_trees, int partialprice,          
- double *totalzeit) ; 
+extern "C" int perfect_match
+(int ncount, CCdatagroup *dat, int ecount,
+ int **elist, int **elen, char *blo_filename,
+ char *mat_filename, int just_fractional, int no_fractional,
+ int use_all_trees, int partialprice,
+ double *totalzeit) ;
 #endif
 
 edge_angle::edge_angle(MVertex *_v1, MVertex *_v2, MElement *t1, MElement *t2)
@@ -94,15 +94,15 @@ static void setLcs(MTriangle *t, std::map<MVertex*, double> &vSizes)
       double dy = vi->y() - vj->y();
       double dz = vi->z() - vj->z();
       double l = sqrt(dx * dx + dy * dy + dz * dz);
-      std::map<MVertex*,double>::iterator iti = vSizes.find(vi);          
-      std::map<MVertex*,double>::iterator itj = vSizes.find(vj);          
+      std::map<MVertex*,double>::iterator iti = vSizes.find(vi);
+      std::map<MVertex*,double>::iterator itj = vSizes.find(vj);
       if(iti->second < 0 || iti->second > l) iti->second = l;
       if(itj->second < 0 || itj->second > l) itj->second = l;
     }
   }
 }
 
-void buildMeshGenerationDataStructures(GFace *gf, 
+void buildMeshGenerationDataStructures(GFace *gf,
                                        std::set<MTri3*, compareTri3Ptr> &AllTris,
                                        std::vector<double> &vSizes,
                                        std::vector<double> &vSizesBGM,
@@ -125,7 +125,7 @@ void buildMeshGenerationDataStructures(GFace *gf,
     std::list<GVertex*>::iterator itvx = emb_vertx.begin();
     while(itvx != emb_vertx.end()){
       MVertex *v = *((*itvx)->mesh_vertices.begin());
-      vSizesMap[v] = std::min(vSizesMap[v], (*itvx)->prescribedMeshSizeAtVertex());      
+      vSizesMap[v] = std::min(vSizesMap[v], (*itvx)->prescribedMeshSizeAtVertex());
       ++itvx;
     }
   }
@@ -166,7 +166,7 @@ void transferDataStructure(GFace *gf, std::set<MTri3*, compareTri3Ptr> &AllTris,
     else
       gf->triangles.push_back(worst->tri());
     delete worst;
-    AllTris.erase(AllTris.begin());      
+    AllTris.erase(AllTris.begin());
   }
 
   // make sure all the triangles are oriented in the same way in
@@ -236,12 +236,12 @@ void buildListOfEdgeAngle(e2t_cont adj, std::vector<edge_angle> &edges_detected,
   e2t_cont::iterator it = adj.begin();
   for(; it != adj.end(); ++it){
     if(it->second.second)
-      edges_detected.push_back(edge_angle(it->first.getVertex(0), 
-                                          it->first.getVertex(1), 
+      edges_detected.push_back(edge_angle(it->first.getVertex(0),
+                                          it->first.getVertex(1),
                                           it->second.first, it->second.second));
-    else 
+    else
       edges_lonly.push_back(edge_angle(it->first.getVertex(0),
-                                       it->first.getVertex(1), 
+                                       it->first.getVertex(1),
                                        it->second.first, it->second.second));
   }
   std::sort(edges_detected.begin(), edges_detected.end());
@@ -269,7 +269,7 @@ double surfaceFaceUV(MElement *t,GFace *gf){
            0.5*fabs((u[3]-u[2])*(v[0]-v[2])-(u[0]-u[2])*(v[3]-v[2])) ;
 }
 
-double surfaceTriangleUV(MVertex *v1, MVertex *v2, MVertex *v3,           
+double surfaceTriangleUV(MVertex *v1, MVertex *v2, MVertex *v3,
                          const std::vector<double> &Us,
                          const std::vector<double> &Vs)
 {
@@ -327,7 +327,7 @@ int _removeFourTrianglesNodes(GFace *gf,bool replace_by_quads)
           }
         }
       }
-      if(edges[0][1] == edges[1][0] && edges[1][1] == edges[2][0] && 
+      if(edges[0][1] == edges[1][0] && edges[1][1] == edges[2][0] &&
          edges[2][1] == edges[3][0] && edges[3][1] == edges[0][0]) {
         if(replace_by_quads){
           gf->quadrangles.push_back(new MQuadrangle(edges[0][0], edges[1][0],
@@ -341,16 +341,16 @@ int _removeFourTrianglesNodes(GFace *gf,bool replace_by_quads)
             surf[i] = surfaceFaceUV(newt[i],gf);
             qual[i] = qmTriangle(newt[i],QMTRI_RHO);
           }
-          double q02=(fabs((surf[0]+surf[2]-surfaceRef)/surfaceRef)<1e-8) ? 
+          double q02=(fabs((surf[0]+surf[2]-surfaceRef)/surfaceRef)<1e-8) ?
             std::min(qual[0],qual[2]) : -1;
-          double q13=(fabs((surf[1]+surf[3]-surfaceRef)/surfaceRef)<1e-8) ? 
+          double q13=(fabs((surf[1]+surf[3]-surfaceRef)/surfaceRef)<1e-8) ?
             std::min(qual[1],qual[3]) : -1;
           if(q02>q13 && q02 >0) {
             delete newt[1];
             delete newt[3];
             gf->triangles.push_back(newt[0]);
             gf->triangles.push_back(newt[2]);
-          } 
+          }
           else if (q13 >0) {
             delete newt[0];
             delete newt[2];
@@ -377,8 +377,8 @@ int _removeFourTrianglesNodes(GFace *gf,bool replace_by_quads)
     }
     else {
       delete gf->triangles[i];
-    }    
-  } 
+    }
+  }
   gf->triangles = triangles2;
   Msg::Debug("%i four-triangles vertices removed",n);
   return n;
@@ -416,8 +416,8 @@ static int _removeTwoQuadsNodes(GFace *gf)
       const std::vector<MElement*> &lt = it->second;
       MElement *q1 = it->second[0];
       MElement *q2 = it->second[1];
-      if (q1->getNumVertices() == 4 && 
-	  q2->getNumVertices() == 4 && 
+      if (q1->getNumVertices() == 4 &&
+	  q2->getNumVertices() == 4 &&
 	  touched.find(q1) == touched.end() && touched.find(q2) == touched.end()){
 	touched.insert(q1);
 	touched.insert(q2);
@@ -433,7 +433,7 @@ static int _removeTwoQuadsNodes(GFace *gf)
 	MVertex *v3 = q1->getVertex((comm+3)%4);
 	MVertex *v4 = 0;
 	for (int i=0;i<4;i++){
-	  if (q2->getVertex(i) != v1 && q2->getVertex(i) != v2 && 
+	  if (q2->getVertex(i) != v1 && q2->getVertex(i) != v2 &&
 	      q2->getVertex(i) != v3 && q2->getVertex(i) != it->first){
 	    v4 = q2->getVertex(i);
 	    break;
@@ -452,8 +452,8 @@ static int _removeTwoQuadsNodes(GFace *gf)
     }
     else {
       delete gf->quadrangles[i];
-    }    
-  } 
+    }
+  }
   gf->quadrangles = quadrangles2;
 
   std::vector<MVertex*> mesh_vertices2;
@@ -463,8 +463,8 @@ static int _removeTwoQuadsNodes(GFace *gf)
     }
     else {
       delete gf->mesh_vertices[i];
-    }    
-  } 
+    }
+  }
   gf->mesh_vertices = mesh_vertices2;
 
   return vtouched.size();
@@ -483,19 +483,19 @@ int removeTwoQuadsNodes(GFace *gf){
 
 
 static bool _isItAGoodIdeaToCollapseThatVertex (GFace *gf,
-						std::vector<MElement*> &e1,					 
-						std::vector<MElement*> &e2,					 
-						MElement *q, 
-						MVertex *v1, 
+						std::vector<MElement*> &e1,
+						std::vector<MElement*> &e2,
+						MElement *q,
+						MVertex *v1,
 						MVertex *v2,
-						MVertex *v, 
+						MVertex *v,
 						double FACT){
 
   double surface_old = surfaceFaceUV(q,gf);
   double surface_new = 0;
   //  double worst_quality_old = q->etaShapeMeasure();
   //  double worst_quality_new = 1.0;
-  
+
   double x = v->x();
   double y = v->y();
   double z = v->z();
@@ -515,13 +515,13 @@ static bool _isItAGoodIdeaToCollapseThatVertex (GFace *gf,
     //    worst_quality_old = std::min(worst_quality_old,e1[j]-> etaShapeMeasure());
     for (int k=0;k<e1[j]->getNumVertices();k++){
       if (e1[j]->getVertex(k) == v1 && e1[j] != q)
-	e1[j]->setVertex(k,v);      
+	e1[j]->setVertex(k,v);
     }
     surface_new += surfaceFaceUV(e1[j],gf);
     //    worst_quality_new = std::min(worst_quality_new,e1[j]-> etaShapeMeasure());
     for (int k=0;k<e1[j]->getNumVertices();k++){
       if (e1[j]->getVertex(k) == v && e1[j] != q)
-	e1[j]->setVertex(k,v1);      
+	e1[j]->setVertex(k,v1);
     }
   }
 
@@ -536,10 +536,10 @@ static bool _isItAGoodIdeaToCollapseThatVertex (GFace *gf,
     //    worst_quality_new = std::min(worst_quality_new,e2[j]-> etaShapeMeasure());
     for (int k=0;k<e2[j]->getNumVertices();k++){
       if (e2[j]->getVertex(k) == v && e2[j] != q)
-	e2[j]->setVertex(k,v2);      
+	e2[j]->setVertex(k,v2);
     }
   }
-  
+
   if ( fabs (surface_old - surface_new ) > 1.e-10 * surface_old) {
     //    ||       FACT*worst_quality_new <  worst_quality_old ) {
 
@@ -550,16 +550,16 @@ static bool _isItAGoodIdeaToCollapseThatVertex (GFace *gf,
   }
 
   return true;
-  
+
 }
 
 
 static bool _isItAGoodIdeaToMoveThatVertex (GFace *gf,
-					    const std::vector<MElement*> &e1,					 
-					    MVertex *v1, 
-					    const SPoint2 &before, 
+					    const std::vector<MElement*> &e1,
+					    MVertex *v1,
+					    const SPoint2 &before,
 					    const SPoint2 &after){
-  
+
   double surface_old = 0;
   double surface_new = 0;
 
@@ -598,7 +598,7 @@ static bool _isItAGoodIdeaToMoveThatVertex (GFace *gf,
   int nBetter=0,nWorse=0;
   int nReallyBadOld=0,nReallyBadNew=0;
   for (unsigned int j=0;j<e1.size();++j){
-    if (qualityNew[j] >= qualityOld[j])nBetter++; 
+    if (qualityNew[j] >= qualityOld[j])nBetter++;
     else {
       nWorse++;
     }
@@ -610,19 +610,19 @@ static bool _isItAGoodIdeaToMoveThatVertex (GFace *gf,
   if (nReallyBadOld < nReallyBadNew)return false;
 
   return (nBetter >= nWorse);
-  
+
 }
 
 
 static int _quadWithOneVertexOnBoundary (GFace *gf,
 					 std::set<MVertex*> &touched,
 					 std::set<MElement*> &diamonds,
-					 std::set<MVertex*> &deleted,					 
-					 std::vector<MElement*> &e2,					 
-					 std::vector<MElement*> &e4,					 
-					 std::vector<MElement*> &e1,					 
+					 std::set<MVertex*> &deleted,
+					 std::vector<MElement*> &e2,
+					 std::vector<MElement*> &e4,
+					 std::vector<MElement*> &e1,
 					 MQuadrangle *q,
-					 MVertex *v1, 
+					 MVertex *v1,
 					 MVertex *v2,
 					 MVertex *v3,
 					 MVertex *v4){
@@ -631,9 +631,9 @@ static int _quadWithOneVertexOnBoundary (GFace *gf,
       v2->onWhat()->dim() == 2 &&
       v3->onWhat()->dim() == 2 &&
       v4->onWhat()->dim() == 2 &&
-      e2.size() < 5 && 
-      e4.size() < 5 && 
-       _isItAGoodIdeaToCollapseThatVertex (gf, e2, e4, q, v2, v4, v4,12.0) 
+      e2.size() < 5 &&
+      e4.size() < 5 &&
+       _isItAGoodIdeaToCollapseThatVertex (gf, e2, e4, q, v2, v4, v4,12.0)
 	/* || _isItAGoodIdeaToCollapseThatVertex (gf, e2, e4, q, v2, v4, v2,12.0))*/){
     touched.insert(v1);
     touched.insert(v2);
@@ -655,7 +655,7 @@ static int _quadWithOneVertexOnBoundary (GFace *gf,
 	//	printf("coucou %g\n",angle3Vertices(line[0],v1,line[1])*180./M_PI);
 	return 0;
       }
-    } 
+    }
     */
     //    if (line.size() == 2)printf("caca\n");
     //    else printf("hohcozbucof\n");
@@ -664,13 +664,13 @@ static int _quadWithOneVertexOnBoundary (GFace *gf,
 	if (e2[j]->getVertex(k) == v2 && e2[j] != q)
 	  e2[j]->setVertex(k,v4);
       }
-    }    	
+    }
     diamonds.insert(q);
     deleted.insert(v2);
     return 1;
   }
   return 0;
-}   
+}
 
 static int  _countCommon(std::vector<MElement*> &a, std::vector<MElement*> &b) {
   int count = 0;
@@ -698,7 +698,7 @@ static int _removeDiamonds(GFace *gf)
     touched.insert(gf->triangles[i]->getVertex(1));
     touched.insert(gf->triangles[i]->getVertex(2));
   }
-  
+
 
   for(unsigned int i = 0; i < gf->quadrangles.size(); i++){
     MQuadrangle *q = gf->quadrangles[i];
@@ -710,19 +710,19 @@ static int _removeDiamonds(GFace *gf)
     v2t_cont::iterator it2 = adj.find(v2);
     v2t_cont::iterator it3 = adj.find(v3);
     v2t_cont::iterator it4 = adj.find(v4);
-    if (touched.find(v1) == touched.end() && 
+    if (touched.find(v1) == touched.end() &&
 	touched.find(v2) == touched.end() &&
 	touched.find(v3) == touched.end() &&
 	touched.find(v4) == touched.end() ) {
       if (_quadWithOneVertexOnBoundary      (gf,touched,diamonds,deleted,it2->second,it4->second,it1->second,q,v1,v2,v3,v4)){}
       else if (_quadWithOneVertexOnBoundary (gf,touched,diamonds,deleted,it3->second,it1->second,it2->second,q,v2,v3,v4,v1)){}
       else if (_quadWithOneVertexOnBoundary (gf,touched,diamonds,deleted,it4->second,it2->second,it3->second,q,v3,v4,v1,v2)){}
-      else if (_quadWithOneVertexOnBoundary (gf,touched,diamonds,deleted,it1->second,it3->second,it4->second,q,v4,v1,v2,v3)){}      
-      else if (v2->onWhat()->dim() == 2 && 
-	       v4->onWhat()->dim() == 2 && 
-	       v1->onWhat()->dim() == 2 && 
-	       v3->onWhat()->dim() == 2 && 
-	       it1->second.size() ==3 &&  it3->second.size() == 3 && 
+      else if (_quadWithOneVertexOnBoundary (gf,touched,diamonds,deleted,it1->second,it3->second,it4->second,q,v4,v1,v2,v3)){}
+      else if (v2->onWhat()->dim() == 2 &&
+	       v4->onWhat()->dim() == 2 &&
+	       v1->onWhat()->dim() == 2 &&
+	       v3->onWhat()->dim() == 2 &&
+	       it1->second.size() ==3 &&  it3->second.size() == 3 &&
 	       _isItAGoodIdeaToCollapseThatVertex (gf, it1->second, it3->second, q, v1, v3, v3,10.)){
 	touched.insert(v1);
 	touched.insert(v2);
@@ -733,15 +733,15 @@ static int _removeDiamonds(GFace *gf)
 	    if (it1->second[j]->getVertex(k) == v1 && it1->second[j] != q)
 	      it1->second[j]->setVertex(k,v3);
 	  }
-	}	
+	}
 	deleted.insert(v1);
 	diamonds.insert(q);
-      } 
-      else if (v2->onWhat()->dim() == 2 && 
-	       v4->onWhat()->dim() == 2 && 
-	       v1->onWhat()->dim() == 2 && 
-	       v3->onWhat()->dim() == 2 && 
-	       it1->second.size() ==3 &&  it3->second.size() == 3 && 
+      }
+      else if (v2->onWhat()->dim() == 2 &&
+	       v4->onWhat()->dim() == 2 &&
+	       v1->onWhat()->dim() == 2 &&
+	       v3->onWhat()->dim() == 2 &&
+	       it1->second.size() ==3 &&  it3->second.size() == 3 &&
 	       _isItAGoodIdeaToCollapseThatVertex (gf, it1->second, it3->second, q, v1, v3, v1,10.)){
 	touched.insert(v1);
 	touched.insert(v2);
@@ -752,14 +752,14 @@ static int _removeDiamonds(GFace *gf)
 	    if (it3->second[j]->getVertex(k) == v3 && it3->second[j] != q)
 	      it3->second[j]->setVertex(k,v1);
 	  }
-	}	
+	}
 	deleted.insert(v3);
 	diamonds.insert(q);
-      } 
-      else if (v1->onWhat()->dim() == 2 && 
-	       v3->onWhat()->dim() == 2 && 
-	       v2->onWhat()->dim() == 2 && 
-	       v4->onWhat()->dim() == 2 && 
+      }
+      else if (v1->onWhat()->dim() == 2 &&
+	       v3->onWhat()->dim() == 2 &&
+	       v2->onWhat()->dim() == 2 &&
+	       v4->onWhat()->dim() == 2 &&
 	       it2->second.size() == 3 && it4->second.size() == 3 &&
 	       _isItAGoodIdeaToCollapseThatVertex (gf, it2->second, it4->second, q, v2, v4, v4,10.)){
 	touched.insert(v1);
@@ -775,10 +775,10 @@ static int _removeDiamonds(GFace *gf)
 	deleted.insert(v2);
 	diamonds.insert(q);
       }
-      else if (v1->onWhat()->dim() == 2 && 
-	       v3->onWhat()->dim() == 2 && 
-	       v2->onWhat()->dim() == 2 && 
-	       v4->onWhat()->dim() == 2 && 
+      else if (v1->onWhat()->dim() == 2 &&
+	       v3->onWhat()->dim() == 2 &&
+	       v2->onWhat()->dim() == 2 &&
+	       v4->onWhat()->dim() == 2 &&
 	       it2->second.size() == 3 && it4->second.size() == 3 &&
 	       _isItAGoodIdeaToCollapseThatVertex (gf, it2->second, it4->second, q, v2, v4, v2,10.)){
 	touched.insert(v1);
@@ -810,8 +810,8 @@ static int _removeDiamonds(GFace *gf)
     }
     else {
       delete gf->mesh_vertices[i];
-    }    
-  } 
+    }
+  }
   gf->mesh_vertices = mesh_vertices2;
 
   return diamonds.size();
@@ -831,8 +831,8 @@ int removeDiamonds(GFace *gf){
 struct p1p2p3 {
   MVertex *p1,*p2;
 };
-static void _relocateVertexConstrained (GFace *gf, 
-					MVertex *ver, 
+static void _relocateVertexConstrained (GFace *gf,
+					MVertex *ver,
 					const std::vector<MElement*> &lt){
   if( ver->onWhat()->dim() == 2){
 
@@ -906,12 +906,12 @@ static void _relocateVertexConstrained (GFace *gf,
 	ver->y() = pt.y();
 	ver->z() = pt.z();
       }
-    }    
+    }
   }
 }
 
-static void _relocateVertex (GFace *gf, 
-			     MVertex *ver, 
+static void _relocateVertex (GFace *gf,
+			     MVertex *ver,
 			     const std::vector<MElement*> &lt){
   double R; SPoint3 c; bool isSphere = gf->isSphere(R,c);
   if( ver->onWhat()->dim() == 2){
@@ -935,7 +935,7 @@ static void _relocateVertex (GFace *gf,
 	XX += lt[i]->getVertex(3)->x();
 	YY += lt[i]->getVertex(3)->y();
 	ZZ += lt[i]->getVertex(3)->z();
-      }         
+      }
       fact += lt[i]->getNumVertices();
     }
     if(fact != 0.0){
@@ -967,7 +967,7 @@ static void _relocateVertex (GFace *gf,
     }
   }
 }
-  
+
 void laplaceSmoothing(GFace *gf, int niter)
 {
   v2t_cont adj;
@@ -978,7 +978,7 @@ void laplaceSmoothing(GFace *gf, int niter)
     while (it != adj.end()){
       _relocateVertex(gf,it->first,it->second);
       ++it;
-    }  
+    }
   }
 }
 
@@ -992,7 +992,7 @@ void laplaceSmoothingConstrained(GFace *gf)
     while (it != adj.end()){
       _relocateVertexConstrained(gf,it->first,it->second);
       ++it;
-    }  
+    }
   }
 }
 
@@ -1002,15 +1002,15 @@ int  _edgeSwapQuadsForBetterQuality ( GFace *gf ) {
   e2t_cont adj;
   //  buildEdgeToElement(gf->triangles, adj);
   buildEdgeToElement(gf->quadrangles, adj);
-  
+
   std::vector<MQuadrangle*>created;
   std::set<MElement*>deleted;
 
   int COUNT = 0;
 
   for(e2t_cont::iterator it = adj.begin(); it!= adj.end(); ++it){
-    if(it->second.second && 
-       it->second.first->getNumVertices() == 4 &&  
+    if(it->second.second &&
+       it->second.first->getNumVertices() == 4 &&
        it->second.second->getNumVertices() == 4){
       MVertex *v1 = it->first.getVertex(0);
       MVertex *v2 = it->first.getVertex(1);
@@ -1019,7 +1019,7 @@ int  _edgeSwapQuadsForBetterQuality ( GFace *gf ) {
 
       double worst_quality_old = std::min(e1->etaShapeMeasure(),e2->etaShapeMeasure());
 
-      if (worst_quality_old < .1 && ( 
+      if (worst_quality_old < .1 && (
 	  deleted.find(e1) == deleted.end() ||
 	  deleted.find(e2) == deleted.end())){
 	MVertex *v12,*v11,*v22,*v21;
@@ -1034,7 +1034,7 @@ int  _edgeSwapQuadsForBetterQuality ( GFace *gf ) {
 	  if (ed.getVertex(1) == v1 && ed.getVertex(0) != v2)v21 = ed.getVertex(0);
 	  if (ed.getVertex(0) == v2 && ed.getVertex(1) != v1)v22 = ed.getVertex(1);
 	  if (ed.getVertex(1) == v2 && ed.getVertex(0) != v1)v22 = ed.getVertex(0);
-	}	
+	}
 
 	MQuadrangle *q1A = new MQuadrangle (v11,v22,v2,v12);
 	MQuadrangle *q2A = new MQuadrangle (v22,v11,v1,v21);
@@ -1081,8 +1081,8 @@ int  _edgeSwapQuadsForBetterQuality ( GFace *gf ) {
     }
     else {
       delete gf->quadrangles[i];
-    }    
-  } 
+    }
+  }
   gf->quadrangles = created;
   return COUNT;
 }
@@ -1122,7 +1122,7 @@ int postProcessExtraEdges (GFace *gf, std::vector<std::pair<MElement*,MElement*>
       }
     }
     if (common){
-      
+
       deleted.insert(t1);
       deleted.insert(t2);
       v2t_cont :: iterator it = adj.find(common);
@@ -1165,7 +1165,7 @@ int postProcessExtraEdges (GFace *gf, std::vector<std::pair<MElement*,MElement*>
 			       t2->getVertex((start2+1)%3),
 			       t2->getVertex(start2));
 
-	
+
 	MQuadrangle *q2 = new MQuadrangle();
 	std::vector<MElement*> newAdj;
 	newAdj.push_back(q1);
@@ -1175,12 +1175,12 @@ int postProcessExtraEdges (GFace *gf, std::vector<std::pair<MElement*,MElement*>
 	    newAdj.push_back(it->second[k]);
 	}
 	gf->quadrangles.insert(q1);
-	gf->quadrangles.insert(q2);	
+	gf->quadrangles.insert(q2);
 	_relocateVertex(gf,newVertex,newAdj);
       }
     }
   }
-  
+
   std::vector<MTriangle*>remained;
   for(unsigned int i = 0; i < gf->triangles.size(); i++){
     if(deleted.find(gf->triangles[i]) == deleted.end()){
@@ -1188,15 +1188,15 @@ int postProcessExtraEdges (GFace *gf, std::vector<std::pair<MElement*,MElement*>
     }
     else {
       delete gf->triangles[i];
-    }    
-  } 
+    }
+  }
   gf->triangles = remained;
   */
 	return 0;
 }
 
 bool edgeSwap(std::set<swapquad> &configs, MTri3 *t1, GFace *gf, int iLocalEdge,
-              std::vector<MTri3*> &newTris, const swapCriterion &cr,               
+              std::vector<MTri3*> &newTris, const swapCriterion &cr,
               const std::vector<double> &Us, const std::vector<double> &Vs,
               const std::vector<double> &vSizes, const std::vector<double> &vSizesBGM)
 {
@@ -1210,27 +1210,27 @@ bool edgeSwap(std::set<swapquad> &configs, MTri3 *t1, GFace *gf, int iLocalEdge,
   for(int i = 0; i < 3; i++)
     if(t2->tri()->getVertex(i) != v1 && t2->tri()->getVertex(i) != v2)
       v4 = t2->tri()->getVertex(i);
-  
+
   swapquad sq (v1, v2, v3, v4);
   if(configs.find(sq) != configs.end()) return false;
   configs.insert(sq);
 
-  const double volumeRef = surfaceTriangleUV(v1, v2, v3, Us, Vs) + 
+  const double volumeRef = surfaceTriangleUV(v1, v2, v3, Us, Vs) +
     surfaceTriangleUV(v1, v2, v4, Us, Vs);
 
-  MTriangle *t1b = new MTriangle(v2, v3, v4);  
-  MTriangle *t2b = new MTriangle(v4, v3, v1); 
+  MTriangle *t1b = new MTriangle(v2, v3, v4);
+  MTriangle *t2b = new MTriangle(v4, v3, v1);
   const double v1b = surfaceTriangleUV(v2, v3, v4, Us, Vs);
   const double v2b = surfaceTriangleUV(v4, v3, v1, Us, Vs);
   const double volume = v1b + v2b;
-  if(fabs(volume - volumeRef) > 1.e-10 * (volume + volumeRef) || 
+  if(fabs(volume - volumeRef) > 1.e-10 * (volume + volumeRef) ||
       v1b < 1.e-8 * (volume + volumeRef) ||
       v2b < 1.e-8 * (volume + volumeRef)){
     delete t1b;
     delete t2b;
     return false;
   }
-  
+
   switch(cr){
   case SWCR_QUAL:
     {
@@ -1247,9 +1247,9 @@ bool edgeSwap(std::set<swapquad> &configs, MTri3 *t1, GFace *gf, int iLocalEdge,
     }
   case SWCR_DEL:
     {
-      double edgeCenter[2] ={(Us[v1->getIndex()] + Us[v2->getIndex()] + Us[v3->getIndex()] + 
+      double edgeCenter[2] ={(Us[v1->getIndex()] + Us[v2->getIndex()] + Us[v3->getIndex()] +
                               Us[v4->getIndex()]) * .25,
-                             (Vs[v1->getIndex()] + Vs[v2->getIndex()] + Vs[v3->getIndex()] + 
+                             (Vs[v1->getIndex()] + Vs[v2->getIndex()] + Vs[v3->getIndex()] +
                               Vs[v4->getIndex()]) * .25};
       double uv4[2] ={Us[v4->getIndex()], Vs[v4->getIndex()]};
       double metric[3];
@@ -1258,7 +1258,7 @@ bool edgeSwap(std::set<swapquad> &configs, MTri3 *t1, GFace *gf, int iLocalEdge,
         delete t1b;
         delete t2b;
         return false;
-      }      
+      }
     }
     break;
   case SWCR_CLOSE:
@@ -1267,12 +1267,12 @@ bool edgeSwap(std::set<swapquad> &configs, MTri3 *t1, GFace *gf, int iLocalEdge,
                         (v1->z() + v2->z()) *.5};
       double avg2[3] = {(v3->x() + v4->x()) *.5,(v3->y() + v4->y()) *.5,
                         (v3->z() + v4->z()) *.5};
-      
+
       GPoint gp1 = gf->point(SPoint2((Us[v1->getIndex()] + Us[v2->getIndex()]) * .5,
                                      (Vs[v1->getIndex()] + Vs[v2->getIndex()]) * .5));
       GPoint gp2 = gf->point(SPoint2((Us[v3->getIndex()] + Us[v4->getIndex()]) * .5,
                                      (Vs[v3->getIndex()] + Vs[v4->getIndex()]) * .5));
-      double d1 = (avg1[0] - gp1.x()) * (avg1[0] - gp1.x()) + (avg1[1] - gp1.y()) * 
+      double d1 = (avg1[0] - gp1.x()) * (avg1[0] - gp1.x()) + (avg1[1] - gp1.y()) *
         (avg1[1]-gp1.y()) + (avg1[2] - gp1.z()) * (avg1[2] - gp1.z());
       double d2 = (avg2[0] - gp2.x()) * (avg2[0] - gp2.x()) + (avg2[1] - gp2.y()) *
         (avg2[1] - gp2.y()) + (avg2[2] - gp2.z()) * (avg2[2] - gp2.z());
@@ -1280,7 +1280,7 @@ bool edgeSwap(std::set<swapquad> &configs, MTri3 *t1, GFace *gf, int iLocalEdge,
         delete t1b;
         delete t2b;
         return false;
-      }      
+      }
     }
     break;
   default :
@@ -1289,8 +1289,8 @@ bool edgeSwap(std::set<swapquad> &configs, MTri3 *t1, GFace *gf, int iLocalEdge,
   }
 
   std::list<MTri3*> cavity;
-  for(int i = 0; i < 3; i++){    
-    if(t1->getNeigh(i) && t1->getNeigh(i) != t2){      
+  for(int i = 0; i < 3; i++){
+    if(t1->getNeigh(i) && t1->getNeigh(i) != t2){
       bool found = false;
       for(std::list<MTri3*>::iterator it = cavity.begin(); it != cavity.end(); it++){
         if(*it == t1->getNeigh(i)) found = true;
@@ -1298,8 +1298,8 @@ bool edgeSwap(std::set<swapquad> &configs, MTri3 *t1, GFace *gf, int iLocalEdge,
       if(!found)cavity.push_back(t1->getNeigh(i));
     }
   }
-  for(int i = 0; i < 3; i++){    
-    if(t2->getNeigh(i) && t2->getNeigh(i) != t1){      
+  for(int i = 0; i < 3; i++){
+    if(t2->getNeigh(i) && t2->getNeigh(i) != t1){
       bool found = false;
       for(std::list<MTri3*>::iterator it = cavity.begin(); it != cavity.end(); it++){
         if(*it == t2->getNeigh(i)) found = true;
@@ -1319,7 +1319,7 @@ bool edgeSwap(std::set<swapquad> &configs, MTri3 *t1, GFace *gf, int iLocalEdge,
   double lcBGM2 = 0.3333333333 * (vSizesBGM[t2b->getVertex(0)->getIndex()] +
                                   vSizesBGM[t2b->getVertex(1)->getIndex()] +
                                   vSizesBGM[t2b->getVertex(2)->getIndex()]);
-  MTri3 *t1b3 = new MTri3(t1b, Extend1dMeshIn2dSurfaces() ? 
+  MTri3 *t1b3 = new MTri3(t1b, Extend1dMeshIn2dSurfaces() ?
                           std::min(lc1, lcBGM1) : lcBGM1);
   MTri3 *t2b3 = new MTri3(t2b, Extend1dMeshIn2dSurfaces() ?
                           std::min(lc2, lcBGM2) : lcBGM2);
@@ -1367,7 +1367,7 @@ int edgeSwapPass(GFace *gf, std::set<MTri3*, compareTri3Ptr> &allTris,
     allTris.insert(newTris.begin(), newTris.end());
     nbSwapTot += nbSwap;
     if(nbSwap == 0) break;
-  }  
+  }
   return nbSwapTot;
 }
 
@@ -1378,11 +1378,11 @@ inline double computeEdgeAdimLength(MVertex *v1, MVertex *v2, GFace *f,
                                     const std::vector<double> &Vs,
                                     const std::vector<double> &vSizes ,
                                     const std::vector<double> &vSizesBGM)
-{  
+{
   const double edgeCenter[2] ={(Us[v1->getIndex()] + Us[v2->getIndex()]) * .5,
                                (Vs[v1->getIndex()] + Vs[v2->getIndex()]) * .5};
   GPoint GP = f->point (edgeCenter[0], edgeCenter[1]);
-  
+
   const double dx1 = v1->x() - GP.x();
   const double dy1 = v1->y() - GP.y();
   const double dz1 = v1->z() - GP.z();
@@ -1425,7 +1425,7 @@ void computeNeighboringTrisOfACavity(const std::vector<MTri3*> &cavity,
     }
   }
 }
-        
+
 bool buildVertexCavity(MTri3 *t, int iLocalVertex, MVertex **v1,
                        std::vector<MTri3*> &cavity, std::vector<MTri3*> &outside,
                        std::vector<MVertex*> &ring)
@@ -1453,10 +1453,10 @@ bool buildVertexCavity(MTri3 *t, int iLocalVertex, MVertex **v1,
           return true;
         }
         if(!t) return false;
-        if(t->isDeleted()){ 
+        if(t->isDeleted()){
           Msg::Error("Impossible to build vertex cavity");
           return false;
-        }  
+        }
         cavity.push_back(t);
         for(int j = 0; j < 3; j++){
           if(t->tri()->getVertex(j) !=lastinring && t->tri()->getVertex(j) != *v1){
@@ -1478,7 +1478,7 @@ bool buildVertexCavity(MTri3 *t, int iLocalVertex, MVertex **v1,
 
 
 // split one triangle into 3 triangles then apply edge swop (or not)
-// will do better (faster) soon, just to test 
+// will do better (faster) soon, just to test
 void _triangleSplit (GFace *gf, MElement *t, bool swop = false) {
   MVertex *v1 = t->getVertex(0);
   MVertex *v2 = t->getVertex(1);
@@ -1487,19 +1487,19 @@ void _triangleSplit (GFace *gf, MElement *t, bool swop = false) {
 
   reparamMeshEdgeOnFace(v1, v2, gf, p1,p2);
   reparamMeshEdgeOnFace(v1, v3, gf, p1,p3);
-  
+
   SPoint2 np = (p1+p2+p3)*(1./3.0);
 
   GPoint gp = gf->point(np);
 
   MFaceVertex *fv = new MFaceVertex(gp.x(),gp.y(),gp.z(),
-				    gf,np.x(),np.y()); 
+				    gf,np.x(),np.y());
   std::vector<MTriangle*> triangles2;
   for(unsigned int i = 0; i < gf->triangles.size(); i++){
     if(gf->triangles[i] != t){
       triangles2.push_back(gf->triangles[i]);
     }
-  } 
+  }
   delete t;
   MTriangle *t1 = new MTriangle(v1,v2,fv);
   MTriangle *t2 = new MTriangle(v2,v3,fv);
@@ -1525,7 +1525,7 @@ struct RecombineTriangle
   {
     n1 = me.getVertex(0);
     n2 = me.getVertex(1);
-    
+
     if(t1->getVertex(0) != n1 && t1->getVertex(0) != n2) n3 = t1->getVertex(0);
     else if(t1->getVertex(1) != n1 && t1->getVertex(1) != n2) n3 = t1->getVertex(1);
     else if(t1->getVertex(2) != n1 && t1->getVertex(2) != n2) n3 = t1->getVertex(2);
@@ -1600,23 +1600,23 @@ static int _recombineIntoQuads(GFace *gf, int recur_level, bool cubicGraph = 1)
   std::vector<RecombineTriangle> pairs;
   int nbValidPairs = 0;
   for(e2t_cont::iterator it = adj.begin(); it!= adj.end(); ++it){
-    if(it->second.second && 
-        it->second.first->getNumVertices() == 3 &&  
+    if(it->second.second &&
+        it->second.first->getNumVertices() == 3 &&
         it->second.second->getNumVertices() == 3 &&
         (emb_edgeverts.find(it->first.getVertex(0)) == emb_edgeverts.end() ||
          emb_edgeverts.find(it->first.getVertex(1)) == emb_edgeverts.end())){
-      
+
       pairs.push_back(RecombineTriangle(it->first,
                                      it->second.first,
                                      it->second.second));
     }
-    else if (!it->second.second && 
+    else if (!it->second.second &&
 	     it->second.first->getNumVertices() == 3){
       for (int i=0;i<2;i++){
 	MVertex *v = it->first.getVertex(i);
 	std::map<MVertex*,std::pair<MElement*,MElement*> > :: iterator itv = makeGraphPeriodic.find(v);
 	if (itv == makeGraphPeriodic.end()){
-	  makeGraphPeriodic[v] = std::make_pair(it->second.first,(MElement*)0);	 
+	  makeGraphPeriodic[v] = std::make_pair(it->second.first,(MElement*)0);
 	}
 	else{
 	  if ( itv->second.first !=  it->second.first)
@@ -1631,7 +1631,7 @@ static int _recombineIntoQuads(GFace *gf, int recur_level, bool cubicGraph = 1)
   std::sort(pairs.begin(),pairs.end());
   std::set<MElement*> touched;
 
-  
+
   if(CTX::instance()->mesh.algoRecombine == 1){
 #ifdef HAVE_MATCH
     int ncount = gf->triangles.size();
@@ -1645,7 +1645,7 @@ static int _recombineIntoQuads(GFace *gf, int recur_level, bool cubicGraph = 1)
       for (unsigned int i=0;i<gf->triangles.size();++i){
 	t2n[gf->triangles[i]] = i;
 	n2t[i] = gf->triangles[i];
-      }      
+      }
 
       int *elist = new int [2*ecount];
       int *elen  = new int [ecount];
@@ -1666,7 +1666,7 @@ static int _recombineIntoQuads(GFace *gf, int recur_level, bool cubicGraph = 1)
 	  if (angle > M_PI/2) angle -= M_PI/2;
 	}
 	//elen [i] =  (int) 180. * fabs(angle-M_PI/4)/M_PI;
-	
+
 	int NB = 0;
 	if (pairs[i].n1->onWhat()->dim() < 2)NB++;
 	if (pairs[i].n2->onWhat()->dim() < 2)NB++;
@@ -1674,7 +1674,7 @@ static int _recombineIntoQuads(GFace *gf, int recur_level, bool cubicGraph = 1)
 	if (pairs[i].n4->onWhat()->dim() < 2)NB++;
 	if (elen[i] > 60 && NB > 2) {elen[i] = 1000;}
       }
-      
+
       if (cubicGraph){
 	std::map<MVertex*,std::pair<MElement*,MElement*> > :: iterator itv = makeGraphPeriodic.begin();
 	int CC = pairs.size();
@@ -1706,11 +1706,11 @@ static int _recombineIntoQuads(GFace *gf, int recur_level, bool cubicGraph = 1)
 	  std::vector<MTriangle*> triangles2;
 	  for (unsigned int i=0;i<pairs.size();++i){
 	    RecombineTriangle &rt = pairs[i];
-	    if ((rt.n1->onWhat()->dim() < 2 && 
+	    if ((rt.n1->onWhat()->dim() < 2 &&
 		 rt.n2->onWhat()->dim() < 2) ||
 		(recur_level > 10 && i < 10)
 		){
-	      if (removed.find(rt.t1) == removed.end() && 
+	      if (removed.find(rt.t1) == removed.end() &&
 		  removed.find(rt.t2) == removed.end() ){
 		removed.insert(rt.t1);
 		removed.insert(rt.t2);
@@ -1719,7 +1719,7 @@ static int _recombineIntoQuads(GFace *gf, int recur_level, bool cubicGraph = 1)
 		SPoint2 np = (p1+p2)*(1./2.0);
 		GPoint gp = gf->point(np);
 		MFaceVertex *newv = new MFaceVertex(gp.x(),gp.y(),gp.z(),
-						    gf,np.x(),np.y()); 
+						    gf,np.x(),np.y());
 		MTriangle *t1 = new MTriangle(rt.n1,rt.n4,newv);
 		MTriangle *t2 = new MTriangle(rt.n4,rt.n2,newv);
 		MTriangle *t3 = new MTriangle(rt.n2,rt.n3,newv);
@@ -1743,7 +1743,7 @@ static int _recombineIntoQuads(GFace *gf, int recur_level, bool cubicGraph = 1)
 	  //	for (int i=0;i<tos.size();i++)_triangleSplit (gf,tos[i]);
 	  //	  gf->model()->writeMSH("chplit.msh");
 	  free(elist);
-	  return _recombineIntoQuads(gf, recur_level+1);	
+	  return _recombineIntoQuads(gf, recur_level+1);
 	}
 	else {
 	  Msg::Error("Perfect Match Finally Failed in Quadrangulation, Try Something Else");
@@ -1755,7 +1755,7 @@ static int _recombineIntoQuads(GFace *gf, int recur_level, bool cubicGraph = 1)
 	// TEST
 	std::vector<std::pair<MElement*,MElement*> > toProcess;
 	for (int k=0;k<elist[0];k++){
-	  int i1 = elist[1+3*k],i2 = elist[1+3*k+1],an=elist[1+3*k+2];	  
+	  int i1 = elist[1+3*k],i2 = elist[1+3*k+1],an=elist[1+3*k+2];
 	  // FIXME !!
 	  if (an == 100000){// || an == 1000){
 	    toProcess.push_back(std::make_pair(n2t[i1],n2t[i2]));
@@ -1774,7 +1774,7 @@ static int _recombineIntoQuads(GFace *gf, int recur_level, bool cubicGraph = 1)
 		  t1->getVertex(2) != t2->getVertex(i)){
 		other = t2->getVertex(i);
 		break;
-	      }	      
+	      }
 	    }
 	    int start;
 	    for(int i = 0; i < 3; i++) {
@@ -1783,7 +1783,7 @@ static int _recombineIntoQuads(GFace *gf, int recur_level, bool cubicGraph = 1)
 		  t2->getVertex(2) != t1->getVertex(i)){
 		start=i;
 		break;
-	      }	      
+	      }
 	    }
 	    MQuadrangle *q = new MQuadrangle(t1->getVertex(start),
 					     t1->getVertex((start+1)%3),
@@ -1796,9 +1796,9 @@ static int _recombineIntoQuads(GFace *gf, int recur_level, bool cubicGraph = 1)
 	free(elist);
 	pairs.clear();
 	if (recur_level == 0)
-	  Msg::Debug("Perfect Match Succeeded in Quadrangulation (%g sec)",matzeit);            
+	  Msg::Debug("Perfect Match Succeeded in Quadrangulation (%g sec)",matzeit);
 	else
-	  Msg::Info(" :-) Perfect Match Succeeded in Quadrangulation after Splits (%g sec)",matzeit);            
+	  Msg::Info(" :-) Perfect Match Succeeded in Quadrangulation after Splits (%g sec)",matzeit);
       }
     }
 #else
@@ -1846,13 +1846,13 @@ static int _recombineIntoQuads(GFace *gf, int recur_level, bool cubicGraph = 1)
     }
     else {
       delete gf->triangles[i];
-    }    
-  } 
+    }
+  }
   gf->triangles = triangles2;
   return success;
 }
 
-void recombineIntoQuads(GFace *gf, 
+void recombineIntoQuads(GFace *gf,
 			bool topologicalOpti,
 			bool nodeRepositioning)
 {
@@ -1871,11 +1871,11 @@ void recombineIntoQuads(GFace *gf,
   // gf->addLayersOfQuads(1, 0);
 
   gf->model()->writeMSH("raw.msh");
-  if(haveParam && nodeRepositioning)  
+  if(haveParam && nodeRepositioning)
     laplaceSmoothing(gf, CTX::instance()->mesh.nbSmoothing);
 
   // blossom-quad algo
-  if(success && CTX::instance()->mesh.algoRecombine == 1){    
+  if(success && CTX::instance()->mesh.algoRecombine == 1){
     if(topologicalOpti){
       if(haveParam){
         gf->model()->writeMSH("smoothed.msh");
@@ -1913,7 +1913,7 @@ void recombineIntoQuads(GFace *gf,
   Msg::Info("Simple recombination algorithm completed (%g s)", t2 - t1);
 }
 
-// give it a try : add one quad layer on the 
+// give it a try : add one quad layer on the
   /*
 void addOneLayerOnContour(GFace *gf, GVertex *gv){
 , int nbLayers, double hplus, double factor){
@@ -1928,14 +1928,14 @@ void addOneLayerOnContour(GFace *gf, GVertex *gv){
     std::list<GEdge*> ed;
     for (GEdgeLoop::iter it2 = it->begin(); it2 != it->end(); ++it2){
       if (it2->ge->getBeginVertex() == gv || it2->ge->getEndVertex() == gv) {
-	found = true;	
+	found = true;
       }
       ed.push_back(it2->ge);
     }
     // we found an edge loop with the GVertex that was specified
     if (found){
       // compute model vertices that will produce fans
-      for (GEdgeLoop::iter it2 = it->begin(); it2 != it->end(); ++it2){	
+      for (GEdgeLoop::iter it2 = it->begin(); it2 != it->end(); ++it2){
 	GEdgeLoop::iter it3 = it2; ++it3;
 	GVertex *gv = it2->getEndVertex();
 	GEdgeSigned *before,*after = *it2;
@@ -1944,8 +1944,8 @@ void addOneLayerOnContour(GFace *gf, GVertex *gv){
 	}
 	else{
 	  before = *it2;
-	}	
-      }      
+	}
+      }
 
       for (std::list<GEdge*>::iterator it = ed.begin(); it != ed.end(); ++it){
 	GEdge *ge = *it;
@@ -1961,7 +1961,7 @@ void addOneLayerOnContour(GFace *gf, GVertex *gv){
 	      duplicates[v] = vd[j];
 	      gf->mesh_vertices.push_back(vd[j]);
 	    }
-	    else 
+	    else
 	      vd[j] = itv->second;
 	  }
 	  newQuads.push_back(new MQuadrangle(ge->lines[i]->getVertex(0), ge->lines[i]->getVertex(1),vd[1],vd[0]));
@@ -1999,7 +1999,7 @@ void addOneLayerOnContour(GFace *gf, GVertex *gv){
 	newTris.push_back(new MTriangle(vs[0],vs[1],vs[2]));
 	delete t;
       }
-  
+
       gf->triangles = newTris;
       gf->quadrangles = newQuads;
     }
@@ -2017,8 +2017,8 @@ void quadsToTriangles(GFace *gf, double minqual = -10000.)
       MTriangle *t12 = new MTriangle (q->getVertex(2),q->getVertex(3),q->getVertex(0));
       MTriangle *t21 = new MTriangle (q->getVertex(1),q->getVertex(2),q->getVertex(3));
       MTriangle *t22 = new MTriangle (q->getVertex(3),q->getVertex(0),q->getVertex(1));
-      double qual1 = std::min(t11->gammaShapeMeasure(),t12->gammaShapeMeasure()); 
-      double qual2 = std::min(t21->gammaShapeMeasure(),t22->gammaShapeMeasure()); 
+      double qual1 = std::min(t11->gammaShapeMeasure(),t12->gammaShapeMeasure());
+      double qual2 = std::min(t21->gammaShapeMeasure(),t22->gammaShapeMeasure());
 
       double surf1 = surfaceFaceUV(t11,gf) + surfaceFaceUV(t12,gf);
       double surf2 = surfaceFaceUV(t21,gf) + surfaceFaceUV(t22,gf);
@@ -2044,26 +2044,26 @@ void quadsToTriangles(GFace *gf, double minqual = -10000.)
     }
   }
   gf->quadrangles = qds;
-}    
+}
 
 void recombineIntoQuadsIterative(GFace *gf)
 {
   recombineIntoQuads(gf);
-  quadsToTriangles(gf,0.03);    
+  quadsToTriangles(gf,0.03);
   return;
   int COUNT = 0;
   while (1){
-    quadsToTriangles(gf);    
+    quadsToTriangles(gf);
     {char NAME[245];sprintf(NAME,"iterT%d.msh",COUNT); gf->model()->writeMSH(NAME);}
     std::set<MTri3*,compareTri3Ptr> AllTris;
     std::vector<double> vSizes, vSizesBGM, Us, Vs;
     std::vector<SMetric3> vMetricsBGM;
     //    buildMeshGenerationDataStructures
-    //      (gf, AllTris, vSizes, vSizesBGM, vMetricsBGM, Us, Vs);    
+    //      (gf, AllTris, vSizes, vSizesBGM, vMetricsBGM, Us, Vs);
     //    int nbSwaps = edgeSwapPass(gf, AllTris, SWCR_DEL, Us, Vs, vSizes, vSizesBGM);
-    //    transferDataStructure(gf, AllTris, Us, Vs); 
+    //    transferDataStructure(gf, AllTris, Us, Vs);
     {char NAME[245];sprintf(NAME,"iterTD%d.msh",COUNT); gf->model()->writeMSH(NAME);}
-    recombineIntoQuads(gf,false,true);       
+    recombineIntoQuads(gf,false,true);
     {char NAME[245];sprintf(NAME,"iter%d.msh",COUNT++); gf->model()->writeMSH(NAME);}
     if (COUNT == 5)break;
   }
@@ -2174,7 +2174,7 @@ double Temporary::compute_alignment(const MEdge&_edge, MElement*element1, MEleme
   scalar_productA = fabs(dot(gradient,edge));
   scalar_productB = fabs(dot(other_vector,edge));
   alignment = std::max(scalar_productA,scalar_productB) - sqrt(2.0)/2.0;
-  alignment = alignment/(1.0-sqrt(2.0)/2.0);	
+  alignment = alignment/(1.0-sqrt(2.0)/2.0);
   return alignment;
 }
 
@@ -2183,7 +2183,7 @@ void Temporary::read_data(std::string file_name){
   double x,y,z;
   MElement*element;
   PView*view;
-  PViewData*data;	
+  PViewData*data;
   PView::readMSH(file_name,-1);
   std::vector<PView*> list = PView::list;
   data = list[0]->getData();
@@ -2229,5 +2229,5 @@ void Temporary::registerBindings(binding *b){
   cm->setDescription("This function creates the quad mesh.");
   cm->setArgNames("file_name","w1","w2","w3",NULL);
 }
-	
+
 
diff --git a/NonLinearSolver/BoundaryConditions/CMakeLists.txt b/NonLinearSolver/BoundaryConditions/CMakeLists.txt
new file mode 100644
index 0000000000..65a1b09c13
--- /dev/null
+++ b/NonLinearSolver/BoundaryConditions/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Gmsh - Copyright (C) 1997-2010 C. Geuzaine, J.-F. Remacle
+#
+# See the LICENSE.txt file for license information. Please report all
+# bugs and problems to <gmsh@geuz.org>.
+set(SRC
+  nonLinearBC.cpp
+)
+
+file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) 
+append_gmsh_src(NonLinearSolver/BoundaryConditions "${SRC};${HDR}")
diff --git a/NonLinearSolver/BoundaryConditions/nonLinearBC.cpp b/NonLinearSolver/BoundaryConditions/nonLinearBC.cpp
new file mode 100644
index 0000000000..3ad2307300
--- /dev/null
+++ b/NonLinearSolver/BoundaryConditions/nonLinearBC.cpp
@@ -0,0 +1,11 @@
+//
+//
+// Description: Class to set Boundary Conditions
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "nonLinearBC.h"
diff --git a/NonLinearSolver/BoundaryConditions/nonLinearBC.h b/NonLinearSolver/BoundaryConditions/nonLinearBC.h
new file mode 100644
index 0000000000..835cdd359f
--- /dev/null
+++ b/NonLinearSolver/BoundaryConditions/nonLinearBC.h
@@ -0,0 +1,134 @@
+//
+//
+// Description: Class to set Boundary Conditions
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+// Has to be regroup with BoundaryCondition defined in elasticitySolver.h These BC have to be defined in a separated file
+// I add nonLinear above to avoid ambiguities
+#ifndef NONLINEARBC_H_
+#define NONLINEARBC_H_
+#ifndef SWIG
+#include "groupOfElements.h"
+#include "simpleFunction.h"
+#include "SVector3.h"
+#include "quadratureRules.h"
+#include "timeFunction.h"
+#include "contactFunctionSpace.h"
+#include "solverAlgorithms.h" // change this
+class nonLinearBoundaryCondition
+{
+ public:
+  enum location{UNDEF,ON_VERTEX,ON_EDGE,ON_FACE,ON_VOLUME,PRESSURE,RIGIDCONTACT};
+  location onWhat; // on vertices or elements
+  int _tag; // tag for the dofManager
+  groupOfElements *g; // support for this BC
+  nonLinearBoundaryCondition() : g(0),_tag(0),onWhat(UNDEF) {};
+  nonLinearBoundaryCondition(const nonLinearBoundaryCondition &source){
+    this->onWhat = source.onWhat;
+    this->_tag = source._tag;
+    this->g = source.g;
+  }
+};
+
+class nonLinearDirichletBC : public nonLinearBoundaryCondition
+{
+ public:
+  int _comp; // component
+  simpleFunctionTime<double> _f;
+  FilterDof *_filter;
+  FunctionSpaceBase *_space;
+  nonLinearDirichletBC() : nonLinearBoundaryCondition(),_comp(0),_f(0), _space(NULL), _filter(NULL){}
+  nonLinearDirichletBC(const nonLinearDirichletBC &source) : nonLinearBoundaryCondition(source){
+    this->_comp = source._comp;
+    this->_f = source._f;
+    this->_space = source._space;
+    this->_filter = source._filter;
+  }
+};
+
+// group will be not used but allow to store in same vector
+// tag == Master physical number
+class rigidContactBC : public nonLinearBoundaryCondition
+{
+ public:
+  rigidContactSpace *space;
+  int _comp; // component
+  simpleFunctionTime<double> _f;
+  rigidContactBC(const int physMaster) : nonLinearBoundaryCondition(){
+    _tag = physMaster;
+    onWhat = RIGIDCONTACT;
+  }
+  rigidContactBC(const rigidContactBC &source) : nonLinearBoundaryCondition(source)
+  {
+    _comp = source._comp;
+    space = source.space;
+    _f = source._f;
+  }
+  ~rigidContactBC(){}
+  void setSpace(rigidContactSpace *sp){space = sp;}
+};
+#endif
+class nonLinearNeumannBC  : public nonLinearBoundaryCondition
+{
+ public:
+  simpleFunction<double> *_f;
+  QuadratureBase* integ; // given by partDomain
+  FunctionSpaceBase *_space; // given by partDomain
+  LinearTermBase<double> *_term; // given by partDomain
+  int _comp; // component x, y or z to create function space
+  nonLinearNeumannBC () : nonLinearBoundaryCondition(),_f(NULL), integ(NULL), _space(NULL), _term(NULL) {}
+  nonLinearNeumannBC (const int tag, const int ow, simpleFunction<double>* f): nonLinearBoundaryCondition(), _f(f),
+                                                                                   integ(NULL), _space(NULL), _term(NULL),
+                                                                                   _comp(0)
+  {
+    _tag = tag;
+    switch(ow){
+     case 0:
+      this->onWhat = nonLinearBoundaryCondition::UNDEF;
+      break;
+     case 1:
+      this->onWhat = nonLinearBoundaryCondition::ON_VERTEX;
+      g = new groupOfElements(0,tag);
+      break;
+     case 2:
+      onWhat = nonLinearBoundaryCondition::ON_EDGE;
+      g = new groupOfElements(1,tag);
+      break;
+     case 3:
+      onWhat = nonLinearBoundaryCondition::ON_FACE;
+      g = new groupOfElements(2,tag);
+      break;
+     case 4:
+      onWhat = nonLinearBoundaryCondition::ON_VOLUME;
+      g = new groupOfElements(3,tag);
+      break;
+     case 5:
+      onWhat = nonLinearBoundaryCondition::PRESSURE;
+      g = new groupOfElements(2,tag);
+      break;
+    }
+  }
+  nonLinearNeumannBC(const nonLinearNeumannBC &source) : _f(source._f), nonLinearBoundaryCondition(source),
+                                                          integ(source.integ), _space(source._space), _term(source._term),
+                                                          _comp(source._comp){}
+};
+#ifndef SWIG
+class initialCondition : public nonLinearDirichletBC {
+ public:
+  enum whichCondition{position=0, velocity=1, acceleration=2};
+  double _value;
+  whichCondition _wc;
+  initialCondition(double val, int comp, whichCondition wc) : nonLinearDirichletBC(), _value(val), _wc(wc){_comp=comp;}
+  ~initialCondition(){}
+  initialCondition(const initialCondition &source) : nonLinearDirichletBC(source){
+    _value = source._value;
+    _wc = source._wc;
+  }
+};
+#endif
+#endif // non linear Boundary Conditions
diff --git a/NonLinearSolver/CMakeLists.txt b/NonLinearSolver/CMakeLists.txt
index 3e9576d382..98fcf560fa 100644
--- a/NonLinearSolver/CMakeLists.txt
+++ b/NonLinearSolver/CMakeLists.txt
@@ -3,11 +3,25 @@
 # See the LICENSE.txt file for license information. Please report all
 # bugs and problems to <gmsh@geuz.org>.
 
+
+add_subdirectory(BoundaryConditions)
+add_subdirectory(contact)
+add_subdirectory(Domain)
+add_subdirectory(field)
+add_subdirectory(Interface)
 add_subdirectory(internalPoints)
-include_directories(internalPoints)
+add_subdirectory(materialLaw)
+add_subdirectory(nlTerms)
+add_subdirectory(nlsolver)
+add_subdirectory(space)
+
 append_gmsh_src(NonLinearSolver "${SRC};${HDR}")
 set(GMSH_DIRS ${GMSH_DIRS};NonLinearSolver PARENT_SCOPE)
 
+#   add pragma to compile nlmechsolpy.i in gmshpy.i
+# no if because here it is sure to used NonLinearSolver
+set(MAKE_C_FLAGS " ${CMAKE_C_FLAGS} -D_HAVE_NLMECHSOL")
+set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -D_HAVE_NLMECHSOL")
 
 
 
diff --git a/NonLinearSolver/Domain/CMakeLists.txt b/NonLinearSolver/Domain/CMakeLists.txt
new file mode 100644
index 0000000000..cf481ee811
--- /dev/null
+++ b/NonLinearSolver/Domain/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Gmsh - Copyright (C) 1997-2010 C. Geuzaine, J.-F. Remacle
+#
+# See the LICENSE.txt file for license information. Please report all
+# bugs and problems to <gmsh@geuz.org>.
+
+set(SRC
+  partDomain.cpp
+)
+
+file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) 
+append_gmsh_src(NonLinearSolver/Domain "${SRC};${HDR}")
diff --git a/NonLinearSolver/Domain/partDomain.cpp b/NonLinearSolver/Domain/partDomain.cpp
new file mode 100644
index 0000000000..4db73cdf4c
--- /dev/null
+++ b/NonLinearSolver/Domain/partDomain.cpp
@@ -0,0 +1,83 @@
+//
+// C++ Interface: partDomain
+//
+// Description: Interface class to used solver. Your term ha to be store in a domain
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "partDomain.h"
+partDomain::partDomain(const partDomain &source){
+  _tag = source._tag;
+  _phys = source._phys;
+  _fullDg = source._fullDg;
+  btermBulk = source.btermBulk;
+  massterm = source.massterm;
+  ltermBulk = source.ltermBulk;
+  integBulk = source.integBulk;
+  g = source.g;
+  allDirichlet = source.allDirichlet;
+  allNeumann = source.allNeumann;
+  allInitial = source.allInitial;
+  _bmbp = source._bmbp;
+  _eps= source._eps;
+  _wsp = source._wsp;
+  setmaterial = source.setmaterial;
+}
+
+partDomain& partDomain::operator=(const partDomain &source)
+{
+  _tag = source._tag;
+  _phys = source._phys;
+  _fullDg = source._fullDg;
+  btermBulk = source.btermBulk;
+  massterm = source.massterm;
+  ltermBulk = source.ltermBulk;
+  integBulk = source.integBulk;
+  g = source.g;
+  allDirichlet = source.allDirichlet;
+  allNeumann = source.allNeumann;
+  allInitial = source.allInitial;
+  _wsp = source._wsp;
+  _bmbp = source._bmbp;
+  _eps = source._eps;
+  setmaterial = source.setmaterial;
+  return *this;
+}
+
+dgPartDomain::dgPartDomain(const dgPartDomain &source) : partDomain(source){
+  btermBound = source.btermBound;
+  ltermBound = source.ltermBound;
+  btermVirtBound = source.btermVirtBound;
+  ltermVirtBound = source.ltermVirtBound;
+  integBound = source.integBound;
+  gi = source.gi;
+  gib = source.gib;
+  giv = source.giv;
+  _interByPert = source._interByPert;
+  _virtByPert = source._virtByPert;
+}
+
+dgPartDomain& dgPartDomain::operator=(dgPartDomain &source)
+{
+  this->partDomain::operator=(source);
+  btermBound = source.btermBound;
+  ltermBound = source.ltermBound;
+  btermVirtBound = source.btermVirtBound;
+  ltermVirtBound = source.ltermVirtBound;
+  integBound = source.integBound;
+  gi = source.gi;
+  gib = source.gib;
+  giv = source.giv;
+  _interByPert = source._interByPert;
+  _virtByPert = source._virtByPert;
+  return *this;
+}
+
+void partDomain::setBulkMatrixByPerturbation(const int i, const double eps)
+{
+  i == 0 ? _bmbp = false : _bmbp = true;
+  _eps = eps;
+}
diff --git a/NonLinearSolver/Domain/partDomain.h b/NonLinearSolver/Domain/partDomain.h
new file mode 100644
index 0000000000..a703dd02de
--- /dev/null
+++ b/NonLinearSolver/Domain/partDomain.h
@@ -0,0 +1,220 @@
+//
+// C++ Interface: partDomain
+//
+// Description: Interface class to used solver. Your term ha to be store in a domain
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef PARTDOMAIN_H_
+#define PARTDOMAIN_H_
+#ifndef SWIG
+#include "mlaw.h"
+#include "SVector3.h"
+#include "MInterfaceElement.h"
+#include "groupOfElements.h"
+#include "timeFunction.h"
+#include "functionSpaceType.h"
+#include "nonLinearBC.h"
+#include "nlTerms.h"
+#include "unknownField.h"
+#include "InterfaceBuilder.h"
+// class for a domain (pure virtual class)
+#endif
+class partDomain{
+ public :
+  typedef std::set<nonLinearDirichletBC*> diriContainer;
+  typedef std::set<nonLinearNeumannBC*> neuContainer;
+  typedef std::set<initialCondition*> initContainer;
+
+ protected :
+  int _tag; // tag for the dofManager
+  int _phys; // physical of interface group I don't know how to retrieve it from *g
+  bool _fullDg; // To know which formulation Cg/Dg or FullDg is used for this part
+  functionSpaceType::whichSpace _wsp;
+  BilinearTermBase* btermBulk;
+  BilinearTermBase* massterm;
+  LinearTermBase<double>* ltermBulk;
+  QuadratureBase* integBulk;
+  // for matrix by perturbation
+  bool _bmbp;
+  double _eps;
+  virtual void setBulkMatrixByPerturbation(const int i, const double eps=1e-8);
+  // To know if law is already set
+  bool setmaterial;
+  // BC are put in domain to be sure to use the good function space
+  // neumann BC
+  neuContainer allNeumann;
+  // dirichlet BC
+  diriContainer allDirichlet;
+  // initial Condition
+  initContainer allInitial;
+
+ public :
+  // Todo protect this variable
+  groupOfElements *g; // support for this field
+
+#ifndef SWIG
+  // Constructors
+  partDomain(const int tag, const int phys,
+             const int ws = 0,const bool fdg=false) : g(0), _tag(tag), _phys(phys),
+                                                         _bmbp(false), _eps(1e-8), _fullDg(fdg), setmaterial(false)
+  {
+    switch(ws){
+     case 0:
+      _wsp = functionSpaceType::Lagrange;
+      break;
+     case 10000: // Allow to set space later (used for interface domain)
+      _wsp = functionSpaceType::Inter;
+      break;
+     default:
+      Msg::Error("Function space type is unknown for partDomain %d. So Lagrange by default");
+      _wsp = functionSpaceType::Lagrange;
+    }
+  }
+  partDomain(const partDomain &source);
+  partDomain& operator=(const partDomain &source);
+//  ~partDomain(){delete btermBulk; delete ltermBulk; delete integBulk;}
+  BilinearTermBase* getBilinearBulkTerm() const{return btermBulk;}
+  BilinearTermBase* getBilinearMassTerm() const{return massterm;}
+  LinearTermBase<double>* getLinearBulkTerm() const{return ltermBulk;}
+  QuadratureBase* getBulkGaussIntegrationRule() const{return integBulk;}
+  // Dimension of domain
+  virtual int getDim() const=0;
+  int getTag()const{return _tag;}
+  int getPhysical() const{return _phys;}
+  virtual void initializeTerms(unknownField *uf,IPField *ip)=0;
+  // true is domain has interface terms
+  virtual bool IsInterfaceTerms() const=0;
+  functionSpaceType::whichSpace getFunctionSpaceType() const{return _wsp;}
+  // can be return const FunctionSpaceBase if the function of this class are declarated const
+  virtual FunctionSpaceBase* getFunctionSpace() const=0;
+// some data of BC have to be set by domain
+  virtual void addDirichletBC(nonLinearDirichletBC *diri)=0; // space and filterDof
+  virtual void addNeumannBC(nonLinearNeumannBC *neu)=0; // space, integration rule and term
+  virtual void addInitialCondition(initialCondition *initC)=0; // idem as dirichlet
+  void setTimeBC(const double curtime){
+    for(neuContainer::iterator it=neuBegin(); it!=neuEnd(); ++it){
+      nonLinearNeumannBC *neu = *it;
+      simpleFunctionTime<double> *ft = dynamic_cast<simpleFunctionTime<double>*>(neu->_f);
+      ft->setTime(curtime);
+    }
+
+    for(diriContainer::iterator it=diriBegin(); it!=diriEnd(); ++it){
+      nonLinearDirichletBC *diri = *it;
+      diri->_f.setTime(curtime);
+    }
+  }
+  diriContainer::iterator diriBegin(){return allDirichlet.begin();}
+  diriContainer::iterator diriEnd(){return allDirichlet.end();}
+  neuContainer::iterator neuBegin(){return allNeumann.begin();}
+  neuContainer::iterator neuEnd(){return allNeumann.end();}
+  initContainer::iterator initCBegin(){return allInitial.begin();}
+  initContainer::iterator initCEnd(){return allInitial.end();}
+
+//  static void registerBindings(binding *b);
+  virtual void computeIPVariable(AllIPState *aips,const unknownField *ufield,const IPStateBase::whichState ws)=0;
+  virtual void computeIpv(AllIPState *aips,MInterfaceElement *ie, IntPt *GP,const IPStateBase::whichState ws,
+                           partDomain* efMinus, partDomain *efPlus,materialLaw *mlawminus,
+                           materialLaw *mlawplus,fullVector<double> &dispm,
+                           fullVector<double> &dispp,const bool virt,const bool checkfrac=true)=0;
+  virtual void computeIpv(AllIPState *aips,MElement *e, IPStateBase::whichState ws,
+                           materialLaw *mlaw,fullVector<double> &disp)=0;
+  virtual void setGaussIntegrationRule()=0;
+  virtual void inverseLinearTermSign()=0;
+  virtual bool getFormulation() const{return _fullDg;}
+  virtual void setMaterialLaw(const std::map<int,materialLaw*> maplaw)=0;
+  // No materialLaw store here but the function to give the material law exist
+  // The law has to be store in the derivated class
+  virtual materialLaw* getMaterialLaw()=0;
+  virtual const materialLaw* getMaterialLaw() const=0;
+  virtual int getLawNum() const=0;
+  // For dg formulation the stability parameters decrease the critical time step size
+  // in explicit. So this function allows to scale the time step
+  virtual double scaleTimeStep() const {return 1.;}
+  // creation of interface. At least boundary to create interface domain
+  // can be empty be not interdomain creation in this case
+  virtual void createInterface(manageInterface &maninter)=0;
+  //Iedge has to be change in IElement
+  virtual MElement* createVirtualInterface(IElement *ie) const=0;
+  virtual MElement* createInterface(IElement* ie1,IElement* ie2) const=0;
+  // Add for BC
+  virtual FilterDof* createFilterDof(const int comp) const=0;
+#endif
+};
+// class for Dg part domain (pure virtual)
+class dgPartDomain : public partDomain{
+ protected :
+  BilinearTermBase* btermBound;
+  LinearTermBase<double>* ltermBound;
+  BilinearTermBase* btermVirtBound;
+  LinearTermBase<double>* ltermVirtBound;
+  QuadratureBase* integBound;
+  // For matrix by perturbation
+  bool _interByPert;
+  bool _virtByPert;
+
+ public :
+  // TODO protect these variables
+  groupOfElements *gi; // support for the interfaceElement TODO cast to a groupOfElements
+  groupOfElements *gib; // support for the interfaceElement TODO cast to a groupOfElements
+  groupOfElements *giv; // support for the virtual interface element (used to set Neumann and Dirichlet BC)
+#ifndef SWIG
+  dgPartDomain(const int tag, const int phys, const int ws = 0,
+               const bool fdg=false) : partDomain(tag,phys,ws,fdg), _interByPert(false), _virtByPert(false)
+  {
+    gi = new groupOfElements();
+    gib = new groupOfElements();
+    giv = new groupOfElements();
+  }
+  dgPartDomain(const dgPartDomain &source);
+  dgPartDomain& operator=(dgPartDomain &source);
+//  ~dgPartDomain(){delete btermBound; delete ltermBound; delete btermVirtBound; delete ltermVirtBound;
+//                  delete integBound; delete gib; delete giv}
+  BilinearTermBase* getBilinearInterfaceTerm(){return btermBound;}
+  LinearTermBase<double>* getLinearInterfaceTerm()const{return ltermBound;}
+  BilinearTermBase* getBilinearVirtualInterfaceTerm(){return btermVirtBound;}
+  LinearTermBase<double>* getLinearVirtualInterfaceTerm(){return ltermVirtBound;}
+  QuadratureBase* getInterfaceGaussIntegrationRule() const {return integBound;}
+  virtual void computeIPVariable(AllIPState *aips,const unknownField *ufield,const IPStateBase::whichState ws)=0;
+  virtual void computeIpv(AllIPState *aips,MInterfaceElement *ie, IntPt *GP,const IPStateBase::whichState ws,
+                            partDomain* efMinus, partDomain *efPlus,materialLaw *mlawminus,
+                            materialLaw *mlawplus,fullVector<double> &dispm,
+                            fullVector<double> &dispp,const bool virt,const bool checkfrac=true)=0;
+  virtual void computeIpv(AllIPState *aips,MElement *e, IPStateBase::whichState ws,
+                            materialLaw *mlaw,fullVector<double> &disp)=0;
+  virtual void addDirichletBC(nonLinearDirichletBC *diri)=0;
+  virtual void addNeumannBC(nonLinearNeumannBC *neu)=0;
+  virtual void addInitialCondition(initialCondition *initC)=0;
+  virtual void setGaussIntegrationRule()=0;
+  virtual int getDim() const=0;
+  virtual bool IsInterfaceTerms() const{return true;}
+  virtual FunctionSpaceBase* getFunctionSpace() const=0;
+  virtual FunctionSpaceBase* getFunctionSpaceMinus() const=0;
+  virtual FunctionSpaceBase* getFunctionSpacePlus() const=0;
+  virtual void matrixByPerturbation(const int ibulk, const int iinter, const int ivirt,const double eps=1e-8)=0;
+//  static void registerBindings(binding *b);
+  virtual void setMaterialLaw(const std::map<int,materialLaw*> maplaw)=0;
+  virtual materialLaw* getMaterialLaw(){Msg::Error("The law to retrieve is not given on a dgdom"); return NULL;}
+  virtual const materialLaw* getMaterialLaw() const{Msg::Error("The law to retrieve is not given on a dgdom"); return NULL;}
+  virtual materialLaw* getMaterialLawMinus()=0;
+  virtual const materialLaw* getMaterialLawMinus() const=0;
+  virtual materialLaw* getMaterialLawPlus()=0;
+  virtual const materialLaw* getMaterialLawPlus() const=0;
+  virtual int getLawNum() const=0;
+  virtual int getMinusLawNum() const=0;
+  virtual int getPlusLawNum() const=0;
+  virtual const partDomain* getMinusDomain() const=0;
+  virtual const partDomain* getPlusDomain() const=0;
+  virtual partDomain* getMinusDomain()=0;
+  virtual partDomain* getPlusDomain()=0;
+  virtual void createInterface(manageInterface &maninter)=0;
+  virtual MElement* createVirtualInterface(IElement *ie) const=0;
+  virtual MElement* createInterface(IElement *ie1, IElement *ie2) const=0;
+  // Add for BC
+  virtual FilterDof* createFilterDof(const int comp) const=0;
+#endif
+};
+#endif
diff --git a/NonLinearSolver/Interface/CMakeLists.txt b/NonLinearSolver/Interface/CMakeLists.txt
new file mode 100644
index 0000000000..295d70c457
--- /dev/null
+++ b/NonLinearSolver/Interface/CMakeLists.txt
@@ -0,0 +1,15 @@
+# Gmsh - Copyright (C) 1997-2010 C. Geuzaine, J.-F. Remacle
+#
+# See the LICENSE.txt file for license information. Please report all
+# bugs and problems to <gmsh@geuz.org>.
+
+set(SRC
+  IEdge.cpp
+  IElement.cpp
+  InterfaceBuilder.cpp
+  MInterfaceElement.cpp
+  MInterfaceLine.cpp
+)
+
+file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) 
+append_gmsh_src(NonLinearSolver/Interface "${SRC};${HDR}")
diff --git a/NonLinearSolver/Interface/IEdge.cpp b/NonLinearSolver/Interface/IEdge.cpp
new file mode 100644
index 0000000000..34933710d6
--- /dev/null
+++ b/NonLinearSolver/Interface/IEdge.cpp
@@ -0,0 +1,12 @@
+//
+// C++ Interface: terms
+//
+// Description: Class to bluid an interface line (used at initialization)
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2011
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "IEdge.h"
diff --git a/NonLinearSolver/Interface/IEdge.h b/NonLinearSolver/Interface/IEdge.h
new file mode 100644
index 0000000000..877d1cdb5b
--- /dev/null
+++ b/NonLinearSolver/Interface/IEdge.h
@@ -0,0 +1,32 @@
+//
+// C++ Interface: terms
+//
+// Description: Class to bluid an interface line (used at initialization)
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2011
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef _IEDEGE_H_
+#define _IEDEGE_H_
+#include "IElement.h"
+#include "MVertex.h"
+#include "MElement.h"
+// Class used to build 2D interface element
+class IEdge : public IElement{
+  public :
+    IEdge(std::vector<MVertex*> &v,MElement *e, int i) : IElement(v,e,i){};
+    ~IEdge(){};
+    unsigned long int getkey() const{
+      int i1,i2,i3;
+      i1 = vertex[0]->getNum();
+      i2 = vertex[1]->getNum();
+      i1>i2 ? i3=i1*100000+i2 : i3=i2*100000+i1; // change this
+      return i3;
+    }
+    virtual IElement::IEtype getType()const{return IElement::Edge;}
+};
+#endif // _IEDEGE_H_
diff --git a/NonLinearSolver/Interface/IElement.cpp b/NonLinearSolver/Interface/IElement.cpp
new file mode 100644
index 0000000000..03b145b569
--- /dev/null
+++ b/NonLinearSolver/Interface/IElement.cpp
@@ -0,0 +1,12 @@
+//
+// C++ Interface: terms
+//
+// Description: Class to bluid the interface element (used at initialization)
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2011
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "IElement.h"
diff --git a/NonLinearSolver/Interface/IElement.h b/NonLinearSolver/Interface/IElement.h
new file mode 100644
index 0000000000..0b90fcec0b
--- /dev/null
+++ b/NonLinearSolver/Interface/IElement.h
@@ -0,0 +1,38 @@
+//
+// C++ Interface: terms
+//
+// Description: Class to bluid the interface element (used at initialization)
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2011
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef _IELEMENT_H_
+#define _IELEMENT_H_
+#include "MVertex.h"
+#include "MElement.h"
+class IElement{
+ public:
+  enum IEtype{Edge};
+ protected:
+  std::vector<MVertex*> vertex;
+  MElement *elem;
+  int phys;
+ public:
+  IElement(std::vector<MVertex*> &v,MElement *e, int i) : vertex(v), elem(e), phys(i){};
+  ~IElement(){};
+  virtual unsigned long int getkey() const=0;
+  virtual IEtype getType() const=0;
+  // As for now only IEdge exists I don't know if these method are virtual pure
+  // virtual or are only for IEdge
+  virtual std::vector<MVertex*> getVertices() const{return vertex;}
+  virtual MElement* getElement() const{return elem;}
+  virtual MVertex* getFirstInteriorVertex() const {return vertex[2];}
+  virtual MVertex* getLastInteriorVertex() const {return *vertex.end();}
+  virtual int getPhys() const {return phys;}
+
+};
+#endif // _IELEMENT_H_
diff --git a/NonLinearSolver/Interface/InterfaceBuilder.cpp b/NonLinearSolver/Interface/InterfaceBuilder.cpp
new file mode 100644
index 0000000000..b58a71b499
--- /dev/null
+++ b/NonLinearSolver/Interface/InterfaceBuilder.cpp
@@ -0,0 +1,66 @@
+//
+// C++ Interface: terms
+//
+// Description: Class to manage the creation of interface
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2011
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "InterfaceBuilder.h"
+#include "partDomain.h"
+unsigned long int manageInterface::getKey(partDomain* dom1, partDomain *dom2){
+  int i1 = dom1->getPhysical();
+  int i2 = dom2->getPhysical();
+  return manageInterface::getKey(i1,i2);
+}
+
+void manageInterface::insert(IElement *iele,partDomain *dom)
+{
+  unsigned long int key = iele->getkey();
+  IelementContainer::iterator it_edge=mapinter.find(key);
+  if((it_edge == mapinter.end()) or (iele->getType() != it_edge->second->getType()))
+    mapinter.insert(IelementPart(key,iele));
+  else{ // create the interface
+    MElement *interel =  dom->createInterface(iele,it_edge->second);
+    this->createinter(interel,iele,it_edge->second->getPhys());
+  }
+}
+
+void manageInterface::createinter(MElement *iele, IElement *ie, const int phys2)
+{
+  unsigned int physkey = manageInterface::getKey(ie->getPhys(),phys2);
+  #ifdef _DEBUG
+   bool findi = false;
+  #endif
+  for(std::vector<partDomain*>::iterator it = _vdom->begin(); it!=_vdom->end(); ++it){
+    partDomain *dom = *it;
+    if(dom->getPhysical() == physkey){
+      dgPartDomain *dgdom = dynamic_cast<dgPartDomain*>(dom);
+      dgdom->gi->insert(iele);
+      #ifdef _DEBUG
+       findi=true;
+      #endif
+    }
+  }
+  #ifdef _DEBUG
+   if(!findi)
+     Msg::Error("Error with the creation of interfaceelement. It seems that an Interface element is not include in any domain");
+  #endif
+  if(physkey != phys2){
+    // search domain
+    for(std::vector<partDomain*>::iterator it = _vdom->begin(); it!=_vdom->end(); ++it){
+      partDomain *dom = *it;
+      if(dom->getPhysical() == ie->getPhys()){
+        dgPartDomain *dgdom = dynamic_cast<dgPartDomain*>(dom);
+        MElement* interel = dgdom->createVirtualInterface(ie);
+        dgdom->giv->insert(interel);
+      }
+    }
+  }
+  else{
+    this->erase(ie);
+  }
+}
diff --git a/NonLinearSolver/Interface/InterfaceBuilder.h b/NonLinearSolver/Interface/InterfaceBuilder.h
new file mode 100644
index 0000000000..c6471b0de6
--- /dev/null
+++ b/NonLinearSolver/Interface/InterfaceBuilder.h
@@ -0,0 +1,66 @@
+//
+// C++ Interface: terms
+//
+// Description: Class to manage the creation of interface
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2011
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef _INTERFACEBUILDER_H_
+#define _INTERFACEBUILDER_H_
+#include "mlaw.h"
+#include "IElement.h"
+class partDomain;
+class manageInterface{
+ public:
+  typedef std::map<unsigned long int,IElement*> IelementContainer; // create IElement type and Iede derive from Iedge
+  typedef std::pair<unsigned long int,IElement*> IelementPart;
+ protected:
+  IelementContainer mapinter;
+  std::vector<partDomain*> *_vdom;
+ public:
+  static unsigned long int getKey(const int npdom1, const int npdom2){
+    unsigned long int i;
+    if(npdom1 == npdom2){
+      return npdom1;
+    }
+    else{
+      npdom1<npdom2 ? i = npdom2*100000+npdom1 : i = npdom1*100000+npdom2;
+      return i;
+    }
+  }
+
+  unsigned long int getKey(partDomain* dom1, partDomain *dom2);
+  void insert(IElement *iele,partDomain *dom);
+
+  // not optimal for internal interface pass current dom for more efficiency ??
+  void createinter(MElement *ele, IElement *ie, const int phys2);
+
+  manageInterface(std::vector<partDomain*> *vdom) : _vdom(vdom){}
+  ~manageInterface()
+  {
+    for(IelementContainer::iterator it = mapinter.begin(); it!=mapinter.end(); ++it){
+      delete it->second;
+    }
+  }
+  void erase(IElement *ie){
+    unsigned long int key = ie->getkey();
+    IelementContainer::iterator it = mapinter.find(key);
+    if(it != mapinter.end()){
+      delete it->second;
+      mapinter.erase(it);
+    }
+  }
+
+
+  void create(partDomain *dom1, partDomain *dom2, const std::map<int,materialLaw*> &maplaw,const int lawnum=0);
+  void createInterShell(partDomain *dom1, partDomain *dom2, const int lawnum,
+                        const std::map<int,materialLaw*> &maplaw,const int ipert, const double eps=1e-8);
+  IelementContainer::iterator begin(){return mapinter.begin();}
+  IelementContainer::iterator end(){return mapinter.end();}
+
+};
+#endif //_INTERFACEBUILDER_H_
diff --git a/NonLinearSolver/Interface/MInterfaceElement.cpp b/NonLinearSolver/Interface/MInterfaceElement.cpp
new file mode 100644
index 0000000000..eaa687cd15
--- /dev/null
+++ b/NonLinearSolver/Interface/MInterfaceElement.cpp
@@ -0,0 +1,49 @@
+//
+// C++ Interface: terms
+//
+// Description: Class of interface element used for DG
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+// Has to be merge with interface element defined in dg project HOW ??
+#include "MInterfaceElement.h"
+#include "quadratureRules.h"
+#include "MLine.h"
+double MInterfaceElement::characSize(MElement *e)
+{
+  // Compute the area of the element
+  GaussQuadrature Integ_Bulk(GaussQuadrature::Grad); // which rule used for now not the same as the call function ??
+  IntPt *GP;
+  double perimeter = 0., Area = 0.;
+  double jac[3][3];
+  int npts=Integ_Bulk.getIntPoints(e,&GP);
+  // Area
+  for( int i = 0; i < npts; i++){
+    // Coordonate of Gauss' point i
+    const double u = GP[i].pt[0]; const double v = GP[i].pt[1]; const double w = GP[i].pt[2];
+    const double weight = GP[i].weight; const double detJ = e->getJacobian(u, v, w, jac); // Or compute jacobian with crossprod(phi0[0],phi0[1]) ??
+    Area += weight * detJ;
+  }
+  // perimeter
+  int nside = e->getNumEdges();
+  GaussQuadrature Integ_Bound(GaussQuadrature::ValVal);
+  std::vector<MVertex*> vver;
+  for(int i=0;i<nside;i++){
+    IntPt *GPb;
+    e->getEdgeVertices(i,vver);
+    MLineN mlin = MLineN(vver);
+    int npts = Integ_Bound.getIntPoints(&mlin,&GPb);
+    for(int j=0;j<npts; j++){
+      const double u = GPb[j].pt[0]; const double v = GPb[j].pt[1]; const double w = GPb[j].pt[2];
+      const double weight = GPb[j].weight; const double detJ = mlin.getJacobian(u, v, w, jac);
+      perimeter +=weight*detJ;
+    }
+    vver.clear();
+  }
+
+  return Area/perimeter;
+}
diff --git a/NonLinearSolver/Interface/MInterfaceElement.h b/NonLinearSolver/Interface/MInterfaceElement.h
new file mode 100644
index 0000000000..dee64bd16a
--- /dev/null
+++ b/NonLinearSolver/Interface/MInterfaceElement.h
@@ -0,0 +1,31 @@
+//
+// C++ Interface: terms
+//
+// Description: Class of interface element used for DG
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+// Has to be merge with interface element defined in dg project HOW ??
+
+# ifndef _MINTERFACEELEMENT_H_
+# define _MINTERFACEELEMENT_H_
+#include "MElement.h"
+// MinterfaceElement is a pure virtual class whose is interace has to be derived and derived from MElement too
+// so MinterfaceElement can't not be derived from MElement
+class MInterfaceElement{
+ public:
+  MInterfaceElement(){}
+  ~MInterfaceElement(){}
+  virtual MElement* getElem(const int index) const=0;
+  virtual int getEdgeOrFaceNumber(const int index) const=0;
+  virtual bool isSameDirection(const int index) const=0;
+  // should return the element number !!
+  virtual int getNum() const=0;
+  // compute the characteritic size of one element (This function can be defined as a method of MElement) ??
+  static double characSize(MElement *e); // Area/perimeter
+};
+#endif // _MINTERFACEELEMENT
diff --git a/NonLinearSolver/Interface/MInterfaceLine.cpp b/NonLinearSolver/Interface/MInterfaceLine.cpp
new file mode 100644
index 0000000000..a9eeed4903
--- /dev/null
+++ b/NonLinearSolver/Interface/MInterfaceLine.cpp
@@ -0,0 +1,111 @@
+//
+// C++ Interface: terms
+//
+// Description: Class of interface element of line used for DG
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2011
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+// Has to be merge with interface element defined in dg project HOW ??
+
+#include "MInterfaceLine.h"
+MInterfaceLine::MInterfaceLine(std::vector<MVertex*> &v, int num, int part,
+                               MElement *e_minus, MElement *e_plus) : MLineN(v, num, part), MInterfaceElement(),
+                                                                      _num(MElement::getGlobalNumber()) //avoid this ??
+{
+  _numElem[0]=e_minus;
+  _numElem[1]=e_plus;
+  // Edge of element linked to interface element we identifie an interior point of the MLine (degree 2 min for shell) thus we used v[0]
+  for(int jj=0;jj<2;jj++){
+    int nopv = _numElem[jj]->getNumPrimaryVertices();
+    std::vector<MVertex*> vv;
+    for(int i = 0; i < nopv; i++){
+      _numElem[jj]->getEdgeVertices(i,vv);
+      for(int j = 2; j < vv.size(); j++){
+        if(vv[j] == v[2]){ // v[2] because it is the first interior node
+          _numEdge[jj] = i;
+          if(v[0] == vv[0]) _dir[jj] = true; // same orientation
+          else _dir[jj] = false;
+        }
+      }
+    }
+  }
+}
+
+void MInterfaceLine::getLocalVertexNum(const int i,std::vector<int> &vn)
+{
+  switch(_numEdge[i]){
+  case 0 :
+    vn[0] = 0;
+    vn[1] = 1;
+    break;
+  case 1 :
+    vn[0] = 1;
+    vn[1] = 2;
+    break;
+  case 2 :
+    if(_numElem[i]->getType()==TYPE_TRI){vn[0]=2;vn[1]=0;}
+    else{vn[0]=2;vn[1]=3;}
+    break;
+  case 3 :
+    vn[0] = 3;
+    vn[1] = 0;
+    break;
+  default : Msg::Error("Impossible to get local vertex number in this case");
+  }
+  // interior edge node
+  for(int j=2;j<vn.size();j++)
+    vn[j]=_numElem[i]->getNumEdges()+_numEdge[i]*(_numElem[i]->getPolynomialOrder()-1)+(j-2);
+}
+
+  // Get the u v value on element for a abscissa u on the interface element // TODO optmize by store in the class interface element the corresponding value (if many step must be compute once)??
+void MInterfaceLine::getuvOnElem(const double u, double &uem, double &vem, double &uep, double &vep)
+{  // w = 0 as no volume element are taken into account. The point is defined between u=-1 and u=1 on the interface element
+  double ue=0.,ve=0.;
+  for(int jj=0;jj<2;jj++){
+    switch(_numElem[jj]->getType()){
+    case TYPE_TRI :
+      switch(_numEdge[jj]){
+      case 0 :
+        if(_dir[jj]) {ue = 0.5 * ( 1 + u ); ve = 0.;}
+        else {ue = 0.5 * ( 1 - u ); ve = 0.;}
+        break;
+      case 1 :
+        if(_dir[jj]) {ue = 0.5 * (1 - u) ; ve = 0.5 * ( 1 + u );}
+        else {ue = 0.5 * (1 + u) ; ve = 0.5 * ( 1 - u );}
+        break;
+      case 2 :
+        if(_dir[jj]) { ue = 0; ve = 0.5 * (1 - u);}
+        else { ue = 0; ve = 0.5 * (1 + u);}
+        break;
+      }
+    break;
+    case TYPE_QUA :
+      switch(_numEdge[jj]){
+      case 0 :
+        if(_dir[jj]) {ue = u; ve = -1.;}
+        else {ue =-u; ve=-1;}
+        break;
+      case 1 :
+        if(_dir[jj]) {ue =1.; ve = u;}
+        else {ue = 1.; ve = -u;}
+        break;
+      case 2 :
+        if(_dir[jj]) {ue = -u; ve = 1;}
+        else {ue = u; ve = 1;}
+        break;
+      case 3 :
+        if(_dir[jj]) {ue = -1; ve = -u;}
+        else {ue = -1; ve = u;}
+        break;
+      }
+      break;
+      default : Msg::Error("The Method doesn't work for this type of element");
+    }
+    if(jj==0){uem=ue;vem=ve;}
+    else {uep=ue;vep=ve;}
+  }
+}
diff --git a/NonLinearSolver/Interface/MInterfaceLine.h b/NonLinearSolver/Interface/MInterfaceLine.h
new file mode 100644
index 0000000000..cd97f5b31d
--- /dev/null
+++ b/NonLinearSolver/Interface/MInterfaceLine.h
@@ -0,0 +1,58 @@
+//
+// C++ Interface: terms
+//
+// Description: Class of interface element of line used for DG
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2011
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+// Has to be merge with interface element defined in dg project HOW ??
+
+#ifndef _MINTERFACELINE_H_
+#define _MINTERFACELINE_H_
+#include "MLine.h"
+#include "MVertex.h"
+#include "MInterfaceElement.h"
+class MInterfaceLine : public MLineN, public MInterfaceElement{ // or don't derivate but in this case a vector with the vertices of interface element has to be save ??
+  protected :
+    // NUMBER DUPLICATION HOW TO AVOID THIS (MInterfaceElement : public MELelement but 2 MElement at this time and MELement has to be a virtual class ??)
+    int _num;
+    // table of pointer on the two elements linked to the interface element
+    MElement *_numElem[2];
+    // edge's number linked to interface element of minus and plus element
+    int _numEdge[2];
+    // dir = true if the edge and the interface element are defined in the same sens and dir = false otherwise
+    bool _dir[2];
+
+  public :
+
+    MInterfaceLine(std::vector<MVertex*> &v, int num = 0, int part = 0, MElement *e_minus = 0, MElement *e_plus = 0);
+
+    // Destructor
+    ~MInterfaceLine(){}
+
+    // Try to avoid this HOW
+//    int getNum() const{MLineN::getNum();}
+    int getNum() const{return _num;}
+    // Give the number of minus 0 or plus 1 element
+    MElement* getElem(int index) const {return _numElem[index];}
+
+    void getuvOnElem(const double u, double &uem, double &vem, double &uep, double &vep);
+
+    // Return the edge number of element
+    int getEdgeOrFaceNumber(const int i) const {return _numEdge[i];}
+
+    // Return the local vertex number of interface
+    void getLocalVertexNum(const int i,std::vector<int> &vn);
+    // Compute the characteristic size of the side h_s = max_e (area_e/perimeter_e)
+    double getCharacteristicSize(){
+      double cm = this->characSize(_numElem[0]);
+      double cp = this->characSize(_numElem[1]);
+      return cm > cp ? cm : cp;
+    }
+    bool isSameDirection(const int i) const {return _dir[i];}
+};
+#endif // _MINTERFACELINE_H_
diff --git a/NonLinearSolver/contact/CMakeLists.txt b/NonLinearSolver/contact/CMakeLists.txt
new file mode 100644
index 0000000000..7d7eafeba3
--- /dev/null
+++ b/NonLinearSolver/contact/CMakeLists.txt
@@ -0,0 +1,16 @@
+# Gmsh - Copyright (C) 1997-2010 C. Geuzaine, J.-F. Remacle
+#
+# See the LICENSE.txt file for license information. Please report all
+# bugs and problems to <gmsh@geuz.org>.
+
+set(SRC
+  contactDomain.cpp
+  contactTerms.cpp
+  rigidCylinderContactTerms.cpp
+ # inline
+  contactFunctionSpace.h
+  nodeStiffnessContact.h
+)
+
+file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) 
+append_gmsh_src(NonLinearSolver/contact "${SRC};${HDR}")
diff --git a/NonLinearSolver/contact/contactDomain.cpp b/NonLinearSolver/contact/contactDomain.cpp
new file mode 100644
index 0000000000..924d741534
--- /dev/null
+++ b/NonLinearSolver/contact/contactDomain.cpp
@@ -0,0 +1,115 @@
+//
+// contact Domain
+//
+// Description: Domain to solve contact problem
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "contactDomain.h"
+contactDomain::contactDomain(const contactDomain &source){
+  _tag = source._tag;
+  _phys = source._phys;
+  _physSlave = source._physSlave;
+  _penalty = source._penalty;
+  gSlave = source.gSlave;
+  gMaster = source.gMaster;
+  _dom = source._dom;
+  _bterm = source._bterm;
+  _massterm = source._massterm;
+  _lterm = source._lterm;
+  _contype = source._contype;
+  _rigid = source._rigid;
+  _space = source._space;
+  _integ = source._integ;
+}
+
+void contactDomain::setContactType(const int ct){
+  switch(ct){
+   case 0:
+    _contype = rigidCylinder;
+    _rigid = true;
+    break;
+   case 1:
+    _contype = rigidSphere;
+    _rigid = true;
+    break;
+   default:
+    Msg::Error("No contact know for int %d",ct);
+  }
+}
+
+MElement* contactDomain::getFirstElement() const {
+  groupOfElements::elementContainer::const_iterator it = gSlave->begin();
+  return (*it);
+}
+
+rigidCylinderContact::rigidCylinderContact(const int tag, const int physMaster, const int physSlave, const int physPt1,
+                                           const int physPt2, const double penalty,
+                                           const double h) : contactDomain(tag,physMaster,physSlave,
+                                                                           penalty,rigidCylinder,true),
+                                                               _thick(h){
+
+  // void gauss integration
+  _integ = new QuadratureVoid();
+
+  // creation of group of elements
+  gMaster = new groupOfElements(2,physMaster);
+  gSlave = new groupOfElements(2,physSlave);
+  // use for build --> no save
+  groupOfElements gpt1 = groupOfElements(0,physPt1);
+  groupOfElements gpt2 = groupOfElements(0,physPt2);
+
+  // find GC and dimension of cylinder
+  // get vertex
+  groupOfElements::vertexContainer::iterator itpt1 = gpt1.vbegin();
+  groupOfElements::vertexContainer::iterator itpt2 = gpt2.vbegin();
+  MVertex *ver1 = *itpt1;
+  MVertex *ver2 = *itpt2;
+  // Vertices coordinates
+  double x1 = ver1->x(); double y1 = ver1->y(); double z1 = ver1->z();
+  double x2 = ver2->x(); double y2 = ver2->y(); double z2 = ver2->z();
+  //creation of GC vertex
+  double xgc = 0.5*(x1+x2); double ygc = 0.5*(y1+y2); double zgc = 0.5*(z1+z2);
+  _vergc = new MVertex(xgc,ygc,zgc);
+  // dimension of cylinder
+  _length = ver1->distance(ver2);
+  // Radius search for an extreme pnt (ie the point with the most distance of gc)
+  double dist=-1.; // initialization
+  MVertex *vermax;
+  for(groupOfElements::vertexContainer::iterator it=gMaster->vbegin(); it!=gMaster->vend();++it){
+    MVertex *ver = *it;
+    double d = ver->distance(_vergc);
+    if(d > dist){
+      vermax = ver;
+      dist = d;
+    }
+  }
+  // radius = smallest distance of extreme point and a center
+  double r1 = vermax->distance(ver1);
+  double r2 = vermax->distance(ver2);
+  (r1>r2) ? _radius=r2 : _radius=r1;
+
+  // vector director of cylinder's axis
+  _axisDirector = new SVector3(ver1->point(),ver2->point());
+  _axisDirector->normalize();
+}
+
+void rigidCylinderContact::initializeTerms(const unknownField *ufield){
+  rigidContactSpace *sp = dynamic_cast<rigidContactSpace*>(_space);
+  _massterm = new massRigidCylinder(this,sp);
+  _lterm = new forceRigidCylinderContact(this,sp,_thickContact,ufield);
+  rigidContactLinearTermBase<double> *rlterm = dynamic_cast<rigidContactLinearTermBase<double>*>(_lterm);
+  _bterm = new stiffnessRigidCylinderContact(sp,rlterm,ufield);
+}
+
+void rigidCylinderContact::setDomain(partDomain *dom){
+  _dom = dom;
+  FunctionSpace<double> *spdom = dynamic_cast<FunctionSpace<double>*>(dom->getFunctionSpace());
+  if(_space != NULL) delete _space;
+  _space = new rigidContactSpace(_phys,spdom,_vergc);
+}
+
diff --git a/NonLinearSolver/contact/contactDomain.h b/NonLinearSolver/contact/contactDomain.h
new file mode 100644
index 0000000000..885687a419
--- /dev/null
+++ b/NonLinearSolver/contact/contactDomain.h
@@ -0,0 +1,108 @@
+//
+// contact Domain
+//
+// Description: Domain to solve contact problem
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef CONTACTDOMAIN_H_
+#define CONTACTDOMAIN_H_
+#ifndef SWIG
+#include "groupOfElements.h"
+#include "partDomain.h"
+#include "contactTerms.h"
+#include "rigidCylinderContactTerms.h"
+#include "MVertex.h"
+#include "MElement.h"
+template<class T2> class contactBilinearTermBase;
+template<class T2> class contactLinearTermBase;
+#endif
+class contactDomain{
+ public:
+  enum contact{rigidCylinder, rigidSphere};
+ protected:
+  int _phys;
+  int _physSlave;
+  int _tag;
+  double _penalty;
+  BilinearTermBase* _bterm;
+  BilinearTermBase* _massterm;
+  LinearTermBase<double>* _lterm;
+  partDomain *_dom;
+  contact _contype;
+  bool _rigid;
+  FunctionSpaceBase *_space;
+  QuadratureBase *_integ;
+ public:
+  groupOfElements *gMaster;
+  groupOfElements *gSlave;
+#ifndef SWIG
+  contactDomain() : gMaster(0), gSlave(0), _phys(0), _physSlave(0), _tag(0), _contype(rigidCylinder), _dom(0), _penalty(0.), _rigid(true){}
+  contactDomain(const int tag, const int phys, const int physSlave, double pe,
+                contact conty,const bool rigid=false) : _tag(tag), _phys(phys), _physSlave(physSlave),
+                                                          _penalty(pe), _contype(conty),
+                                                          _rigid(rigid), _space(NULL){}
+  contactDomain(const contactDomain &source);
+  ~contactDomain(){}
+
+  virtual void setTag(const int t){ _tag =t;}
+  virtual void setPhys(const int p){_phys =p;}
+  virtual void setPenalty(const double pe){_penalty=pe;}
+  virtual void setDomain(partDomain *dom)=0;
+  virtual void setContactType(const int ct);
+  virtual void setContactType(const contact ct){_contype =ct;}
+  virtual int getTag() const{return _tag;}
+  virtual int getPhys() const{return _phys;}
+  virtual int getPhysSlave() const{return _physSlave;}
+  virtual double getPenalty() const{return _penalty;}
+  virtual contact getContactType() const{return _contype;}
+  virtual partDomain* getDomain() const {return _dom;}
+  virtual MElement * getFirstElement() const;
+  virtual bool isRigid() const {return _rigid;}
+  virtual BilinearTermBase* getMassTerm(){return _massterm;}
+  virtual BilinearTermBase* getStiffnessTerm(){return _bterm;}
+  virtual LinearTermBase<double>* getForceTerm(){return _lterm;}
+  virtual FunctionSpaceBase* getSpace() {return _space;}
+  virtual const FunctionSpaceBase* getSpace() const {return _space;}
+  virtual QuadratureBase* getGaussIntegration() const{return _integ;}
+//  static void registerBindings(binding *b);
+#endif
+};
+
+class rigidCylinderContact : public contactDomain{
+ protected:
+  double _length; // length of cylinder;
+  double _radius; // outer radius of cylinder;
+  double _thick;  // thickness of cylinder;
+  double _thickContact; // use for shell (contact with neutral axis of external fiber is !=0)
+  double _density; // density of cylinder Not a material law for now
+  MVertex *_vergc;  // vertex of gravity center
+  SVector3 *_axisDirector; // normalized vector director of cylinder's axis
+ public:
+  rigidCylinderContact() : contactDomain(), _length(0.), _radius(0.), _thick(0.){
+    _contype = rigidCylinder;
+    _rigid = true;
+    _integ = new QuadratureVoid();
+  }
+  rigidCylinderContact(const int tag, const int physMaster, const int physSlave, const int physpt1,
+                       const int physpt2,const double penalty,const double h);
+  ~rigidCylinderContact(){delete _axisDirector;}
+  void density(const double rho){ _density = rho;}
+//  void setThicknessContact(const double h){_thickContact = h;}
+#ifndef SWIG
+  virtual MVertex* getGC() const{return _vergc;}
+  double getDensity() const{return _density;}
+  double getLength() const{return _length;}
+  double getRadius() const{return _radius;}
+  double getThickness() const{return _thick;}
+  void initializeTerms(const unknownField *ufield);
+  SVector3* getAxisDirector() const{return _axisDirector;}
+  virtual void setDomain(partDomain *dom);
+#endif
+
+};
+#endif // CONTACTDOMAIN_H_
diff --git a/NonLinearSolver/contact/contactFunctionSpace.h b/NonLinearSolver/contact/contactFunctionSpace.h
new file mode 100644
index 0000000000..e2b67f9df9
--- /dev/null
+++ b/NonLinearSolver/contact/contactFunctionSpace.h
@@ -0,0 +1,85 @@
+//
+// functional space for contact
+//
+// Description:
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2011
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+
+#ifndef CONTACTSPACE_H_
+#define CONTACTSPACE_H_
+#include "functionSpace.h"
+#include "Dof3IntType.h"
+template <class T1> class ContactSpaceBase : public FunctionSpaceBase{
+ protected:
+  FunctionSpace<T1> *_space; // functional space of domain where contact is computed
+  const int _id;
+  std::vector<int> _comp;
+ public:
+  ContactSpaceBase(const int id, FunctionSpace<double> *sp) : FunctionSpaceBase(), _id(id), _space(sp){
+    _comp.push_back(0);
+    _comp.push_back(1);
+    _comp.push_back(2);
+  }
+  ContactSpaceBase(const int id, FunctionSpace<double> *sp, const int comp1,
+                   const int comp2 = -1, const int comp3 =-1) : FunctionSpaceBase(), _id(id), _space(sp)
+  {
+    _comp.push_back(comp1);
+    if(comp2 !=-1)
+      _comp.push_back(comp2);
+    if(comp3 != -1)
+      _comp.push_back(comp3);
+  }
+
+  virtual void getKeys(MElement *ele,std::vector<Dof> &keys){
+    _space->getKeys(ele,keys);
+  }
+  virtual int getNumKeys(MElement *ele){
+    return _space->getNumKeys(ele);
+  }
+};
+
+class rigidContactSpace : public ContactSpaceBase<double>{
+ protected:
+  const MVertex *_gc; // Node of gravity center
+ public:
+  rigidContactSpace(const int id, FunctionSpace<double> *sp, MVertex *ver) : ContactSpaceBase<double>(id,sp), _gc(ver){}
+  rigidContactSpace(const int id, FunctionSpace<double> *sp, MVertex *ver, const int comp1,
+                   const int comp2 = -1, const int comp3 =-1) : ContactSpaceBase<double>(id,sp,comp1,comp2,comp3){}
+  virtual void getKeys(MElement *ele,std::vector<Dof> &keys){
+    _space->getKeys(ele,keys);
+    for(int i=0;i<_comp.size();i++){
+      keys.push_back(Dof(_gc->getNum(),Dof3IntType::createTypeWithThreeInts(_comp[i],_id)));
+    }
+  }
+  virtual int getNumKeys(MElement *ele){
+    int nkeysele = _space->getNumKeys(ele);
+    return nkeysele + _comp.size();
+  }
+  virtual void getKeysOfGravityCenter(std::vector<Dof> &keys){
+    for(int i=0;i<_comp.size(); i++)
+      keys.push_back(Dof(_gc->getNum(),Dof3IntType::createTypeWithThreeInts(_comp[i],_id)));
+  }
+  virtual int getNumKeysOfGravityCenter(){
+    return _comp.size();
+  }
+  virtual void getKeys(MElement *ele, const int ind, std::vector<Dof> &keys){
+    // generate keys of element and select the good ones after LAGRANGE OK ?? CHANGE THIS HOW TODO
+    std::vector<Dof> tkeys;
+    this->getKeys(ele,tkeys);
+    int nkeys = this->getNumKeys(ele);
+    int ncomp = _comp.size();
+    int nbver = nkeys/ncomp-1; // because GC is in the nkeys
+    for(int i=0;i<ncomp; i++)
+      keys.push_back(tkeys[ind+i*nbver]);
+    this->getKeysOfGravityCenter(keys);
+  }
+  virtual int getNumKeys(MElement *ele, int ind){
+    return 2*_comp.size();
+  }
+};
+#endif // CONTACTSPACE_H_
+
diff --git a/NonLinearSolver/contact/contactTerms.cpp b/NonLinearSolver/contact/contactTerms.cpp
new file mode 100644
index 0000000000..60e02ffb57
--- /dev/null
+++ b/NonLinearSolver/contact/contactTerms.cpp
@@ -0,0 +1,51 @@
+//
+// contact base term
+//
+// Description: contact term
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2011
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+#include "contactTerms.h"
+#include "unknownField.h"
+template<> void rigidContactLinearTermBase<double>::get(MElement *ele, int npts, IntPt *GP,fullVector<double> &m) const
+{
+  nbdofs = _spc->getNumKeys(ele);
+  nbdofsGC = _spc->getNumKeysOfGravityCenter();
+  m.resize(nbdofs);
+  m.setAll(0.);
+  nbvertex = ele->getNumVertices();
+  nbcomp = (nbdofs-nbdofsGC)/nbvertex;
+  nbcomptimenbvertex = nbvertex*nbcomp;
+  // get displacement of vertices (To know the current node positions)
+  disp.clear(); R.clear();
+  _spc->getKeys(ele,R);
+
+  _ufield->get(R,disp);
+
+  verdisp[3] = disp[nbcomptimenbvertex]; verdisp[4] = disp[nbcomptimenbvertex+1]; verdisp[5] = disp[nbcomptimenbvertex+2];
+  for(int i=0;i<nbvertex;i++){
+    for(int j=0;j<6;j++) mvalue[j] =0.;
+    ver = ele->getVertex(i);
+    verdisp[0] = disp[i]; verdisp[1] = disp[i+nbvertex]; verdisp[2] = disp[i+2*nbvertex];
+    this->get(ver,verdisp,mvalue);
+    // look if there is contact force
+    int jj=0;
+    while(jj<6){
+      if(mvalue[jj] != 0.){
+//        Msg::Info("Contact detected on elem %d vertex %d",ele->getNum(),ele->getVertex(i)->getNum());
+        _allcontactNode->insert(ele,i,_lastNormalContact);
+        for(int j=0;j<nbcomp;j++){
+          m(i+j*nbvertex) += mvalue[j];
+          m(nbcomptimenbvertex+j) += mvalue[j+3]; // count two times
+        }
+        break;
+      }
+      jj++;
+    }
+  }
+ // if(m.norm() != 0.)
+//    m.print("contact");
+}
diff --git a/NonLinearSolver/contact/contactTerms.h b/NonLinearSolver/contact/contactTerms.h
new file mode 100644
index 0000000000..d0b652d20f
--- /dev/null
+++ b/NonLinearSolver/contact/contactTerms.h
@@ -0,0 +1,80 @@
+//
+// contact base term
+//
+// Description: define contact terms
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2011
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef CONTACTTERMS_H_
+#define CONTACTTERMS_H_
+#include "terms.h"
+#include "nodeStiffnessContact.h"
+#include "contactFunctionSpace.h"
+class unknownField;
+template<class T1=double> class contactLinearTermBase : public LinearTermBase<T1>{
+ protected:
+  contactNodeStiffness *_allcontactNode; // need to compute BilinearTerm with more efficiency (compute only for nodes in contact)
+ public:
+  contactLinearTermBase(){
+    _allcontactNode = new contactNodeStiffness();
+  }
+  contactLinearTermBase(const contactLinearTermBase &source){
+    _allcontactNode = source._allcontactNode;
+  }
+  virtual ~contactLinearTermBase(){delete _allcontactNode;}
+  contactNodeStiffness* getContactNode() const {return _allcontactNode;}
+  void clearContactNodes(){_allcontactNode->clear();}
+//  virtual void get(MElement *ele, int npts, IntPt *GP, fullVector<T1> &v)=0;
+};
+
+template <class T2=double>class  contactBilinearTermBase : public BilinearTermBase
+{
+ protected:
+  contactLinearTermBase<T2> *_lterm; // because bilinear terms is compute only for nodes
+                                 // in contact. These nodes are in the linear terms associated to bilinearTerm
+ public:
+  contactBilinearTermBase(contactLinearTermBase<T2> *lterm) : _lterm(lterm){}
+  virtual ~contactBilinearTermBase(){}
+//  virtual void get(MElement *ele, int npts, IntPt *GP, fullMatrix<T2> &m) const=0;
+  // same for all contact
+  contactLinearTermBase<T2>* getLterm() const{return _lterm;}
+  contactNodeStiffness * getContactNodes() const{return _lterm->getContactNode();}
+  void clearContactNodes(){_lterm->clearContactNodes();}
+};
+
+template<class T2=double> class rigidContactLinearTermBase : public contactLinearTermBase<T2>{
+ protected:
+  const unknownField *_ufield;
+  rigidContactSpace *_spc;
+  // data for get function (Allocated once)
+  mutable SVector3 _lastNormalContact; // allow to use the normal in the 2 get functions not very elegant
+  mutable int nbdofs,nbdofsGC, nbvertex,nbcomp,nbcomptimenbvertex;
+  mutable std::vector<double> disp;
+  mutable std::vector<Dof> R;
+  mutable double verdisp[6];
+  mutable double mvalue[6];
+  mutable MVertex *ver;
+ public:
+  rigidContactLinearTermBase(rigidContactSpace *sp,
+                             const unknownField *ufield) : contactLinearTermBase<T2>(),
+                                                                 _ufield(ufield), _spc(sp), _lastNormalContact(0.,0.,0.),
+                                                                 nbdofs(0), nbdofsGC(0), nbvertex(0), nbcomp(0), nbcomptimenbvertex(0)
+  {
+
+  }
+  rigidContactLinearTermBase(const rigidContactLinearTermBase<T2> &source) : contactLinearTermBase<T2>(source){
+    _ufield = source._ufield;
+    _spc = source._spc;
+  }
+  ~rigidContactLinearTermBase(){}
+//  virtual void get(MElement *ele, fullVector<double> &m);
+  virtual void get(const MVertex *ver, const double disp[6],double mvalue[6]) const=0;
+  // same for ALL RIGID CONTACT
+  virtual void get(MElement *ele, int npts, IntPt *GP, fullVector<T2> &v) const;
+};
+#endif // CONTACTTERMS_H_
diff --git a/NonLinearSolver/contact/nodeStiffnessContact.h b/NonLinearSolver/contact/nodeStiffnessContact.h
new file mode 100644
index 0000000000..3f073ddec5
--- /dev/null
+++ b/NonLinearSolver/contact/nodeStiffnessContact.h
@@ -0,0 +1,62 @@
+//
+// contact stiffness
+//
+// Description: Class to manage the Dof for which the stiffness must be computed
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef CONTACTNODESTIFFNESS_H_
+#define CONTACTNODESTIFFNESS_H_
+#include "MElement.h"
+#include "SVector3.h"
+
+struct dataContactStiffnessNode{
+ public:
+  MElement *_ele;
+  int _verIndex;
+  SVector3 _normal;
+  dataContactStiffnessNode() : _ele(NULL), _verIndex(0), _normal(0.,0.,0.){};
+  dataContactStiffnessNode(MElement *ele, const int ind, const SVector3 &nor) : _ele(ele), _verIndex(ind), _normal(nor){}
+  dataContactStiffnessNode(const dataContactStiffnessNode &source){
+    _ele = source._ele;
+    _verIndex = source._verIndex;
+    _normal = source._normal;
+  }
+};
+
+class contactNodeStiffness{
+ public:
+  typedef std::vector<dataContactStiffnessNode> nodeContainer;
+ protected:
+  nodeContainer _nodeInContact;
+  groupOfElements *_g; // group with elements in contact
+ public:
+  contactNodeStiffness(){_g = new groupOfElements();}
+  contactNodeStiffness(const contactNodeStiffness &source){
+    _nodeInContact = source._nodeInContact;
+    _g = source._g;
+  }
+  ~contactNodeStiffness()
+  {
+    if(_g !=NULL) delete _g;
+  };
+
+  void insert(MElement *ele,const int i, SVector3 &normal){
+    _nodeInContact.push_back(dataContactStiffnessNode(ele,i,normal));
+    _g->insert(ele);
+  }
+  void clear(){
+    _nodeInContact.clear();
+    if(_g != NULL) delete _g;
+    _g = new groupOfElements();
+  }
+  nodeContainer::const_iterator nBegin() const{return _nodeInContact.begin();}
+  nodeContainer::const_iterator nEnd() const{return _nodeInContact.end();}
+  groupOfElements::elementContainer::const_iterator elemBegin() const{return _g->begin();}
+  groupOfElements::elementContainer::const_iterator elemEnd() const{return _g->end();}
+};
+#endif // contactNodeStiffness
diff --git a/NonLinearSolver/contact/rigidCylinderContactTerms.cpp b/NonLinearSolver/contact/rigidCylinderContactTerms.cpp
new file mode 100644
index 0000000000..ab732190a1
--- /dev/null
+++ b/NonLinearSolver/contact/rigidCylinderContactTerms.cpp
@@ -0,0 +1,188 @@
+//
+// contact base term
+//
+// Description: contact with a rigid cylinder
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2011
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+#include "rigidCylinderContactTerms.h"
+#include "contactDomain.h"
+#include "unknownField.h"
+massRigidCylinder::massRigidCylinder(rigidCylinderContact *cdom,
+                                     rigidContactSpace *spc) : _length(cdom->getLength()),_radius(cdom->getRadius()),
+                                                               _thick(cdom->getThickness()),_rho(cdom->getDensity()),
+                                                               _spc(spc),nbdofs(0.), masse(0.),Rint(0.){}
+
+void massRigidCylinder::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double> &m) const
+{
+  // get the number of cylinder component (same mass in all direction)
+  int nbdofs = _spc->getNumKeysOfGravityCenter();
+  m.resize(nbdofs,nbdofs,true); // true --> setAll(0.)
+  if(_thick > _radius){ // full cylinder
+    masse = _rho*M_PI*_radius*_radius*_length;
+  }
+  else{ // hollow cylinder
+    Rint = _radius-_thick;
+    masse = _rho*M_PI*_thick*(_radius*_radius-Rint*Rint);
+  }
+  for(int i=0;i<nbdofs;i++)
+      m(i,i) = masse;
+}
+
+ forceRigidCylinderContact::forceRigidCylinderContact(const rigidCylinderContact *cdom,
+                            rigidContactSpace *sp,const double thick,
+                            const unknownField *ufield) : rigidContactLinearTermBase(sp,ufield), _cdom(cdom),
+                                                                _vergc(cdom->getGC()),
+                                                                _axisDirector(cdom->getAxisDirector()),
+                                                                _radius(cdom->getRadius()),
+                                                                _rcontact(cdom->getRadius() + 0.*thick),
+                                                                _halflength(0.5*cdom->getLength()),
+                                                                _GC(cdom->getGC()->point()), d(0.),
+                                                                penetration(0.), penpen(0.)
+{
+  if(_cdom->getDomain()->IsInterfaceTerms()){
+    partDomain *dom = dynamic_cast<partDomain*>(_cdom->getDomain());
+    if(dom->getFormulation()){
+      _fdgfactor = 1.;
+      _facGC =0.5;
+    }
+    else{
+      _fdgfactor = 0.5;
+      _facGC =1.;
+    }
+  }
+  else{
+    _fdgfactor = 0.5;
+    _facGC = 1.;
+  }
+  _penalty = _fdgfactor*_cdom->getPenalty();
+}
+
+void forceRigidCylinderContact::get(const MVertex *ver, const double disp[6],double mvalue[6]) const
+{
+  // B = axis' center
+  // A = vertex for which we look for contact
+  B = _GC;
+  Bdisp.setPosition(disp[3],disp[4],disp[5]);
+  B+=Bdisp;
+  // Distance between vertex and cylinder axis
+  // line BA
+  A = ver->point();
+  Adisp.setPosition(disp[0],disp[1],disp[2]);
+  A+=Adisp;
+  SVector3 BA(A,B);
+  dirAC = crossprod(BA,*_axisDirector);
+  double d = dirAC.norm();
+  // test to know if contact
+  if(d < _rcontact){
+    // check if contact occur before end of cylinder
+    dirAC.normalize();
+    _lastNormalContact = crossprod(dirAC,*_axisDirector);
+    _lastNormalContact.normalize();
+    C.setPosition(A,_lastNormalContact.point(),-d);
+      // check normal direction if C is further of B than A the direction is wrong
+      if(C.distance(B) > A.distance(B)){
+        _lastNormalContact.negate();
+        _lastNormalContact.normalize();
+        C.setPosition(A,_lastNormalContact.point(),-d);
+      }
+      if(C.distance(B) < _halflength){
+        penetration = _rcontact-d;
+        penpen = penetration*_penalty;
+        for(int j=0;j<3;j++){
+          mvalue[j]+= penpen*_lastNormalContact(j);
+          mvalue[j+3] -=_facGC*penpen*_lastNormalContact(j); // count two times
+        }
+      }
+    }
+}
+
+void stiffnessRigidCylinderContact::get(MElement *ele, int npts, IntPt *GP, fullMatrix<double> &m) const
+{
+  int nbdofs = _spc->getNumKeys(ele);
+  m.resize(nbdofs,nbdofs,true); // true --> setAll(0.)
+  // search the vertices for which the matrix has to be computed
+  contactNodeStiffness * contactNodes = _lterm->getContactNode();
+  for(contactNodeStiffness::nodeContainer::const_iterator itn = contactNodes->nBegin(); itn!= contactNodes->nEnd(); ++itn){
+    if(itn->_ele == ele){ // contact
+      this->get(ele,itn->_verIndex,m);
+    }
+  }
+}
+
+// Protected can only be called by stiffnessRigidCylinderContact::get(MElement *ele, int npts, IntPt *GP, fullMatrix<double> &m)
+// NO RESIZE
+void stiffnessRigidCylinderContact::get(MElement *ele, const int verIndex, fullMatrix<double> &m) const
+{
+  // perturbation numeric
+  rigidContactLinearTermBase<double>* rlterm = dynamic_cast<rigidContactLinearTermBase<double>*>(_lterm);
+  int nbdofselem = _spc->getNumKeys(ele) - _spc->getNumKeysOfGravityCenter();
+  int nbFF = ele->getNumVertices();
+  ver = ele->getVertex(verIndex);
+  disp.clear(); R.clear();
+  _spc->getKeys(ele,verIndex,R);
+  _ufield->get(R,disp);
+  for(int j=0;j<6;j++)
+    pertdisp[j] = disp[j];
+
+  // perturbation on each Dofs 3 for vertex and 3 for GC of cylinder
+  for(int i=0;i<6;i++){
+    // set force component to zero
+    for(int j=0;j<6;j++)
+      fp[j] = fm[j] = 0.;
+
+    // Force -
+    pertdisp[i] = disp[i] - _perturbation;
+    rlterm->get(ver,pertdisp,fm);
+
+    // Force +
+    pertdisp[i] = disp[i] + _perturbation;
+    rlterm->get(ver,pertdisp,fp);
+
+    // Assembly in matrix
+    if(i<3){ // perturbation on vertex
+      for(int j=0; j<3; j++){
+        m(verIndex+nbFF*j,verIndex+nbFF*i) -= (fp[j]-fm[j])*_doublepertexpm1;
+        m(nbdofselem+j,verIndex+nbFF*i) -= (fp[j+3]-fm[j+3])*_doublepertexpm1;
+      }
+    }
+    else{ // perturbation on gravity center
+      for(int j=0; j<3; j++){
+        m(verIndex+nbFF*j,nbdofselem+i-3) -= (fp[j]-fm[j])*_doublepertexpm1;
+        m(nbdofselem+j,nbdofselem+i-3) -= (fp[j+3]-fm[j+3])*_doublepertexpm1;
+      }
+    }
+    // virgin pertdisp
+    pertdisp[i] = disp[i];
+  }
+
+  // ANALYTIC WAY MUST BE FIXED
+/*  int nbdofs = _spc->getNumKeys(ele);
+  int nbvertex = ele->getNumVertices();
+  int nbdofGC = _spc->getNumKeysOfGravityCenter();
+  int nbcomp = (nbdofs-nbdofGC)/nbvertex;
+  int nbcompTimesnbVertex = nbcomp*nbvertex;
+  m.resize(nbdofs,nbdofs);
+  m.setAll(0.);
+  double penalty = _fdgfactor*_cdom->getPenalty();
+  for(int i=0;i<nbvertex;i++){
+    SVector3 nor = _allcontactNode->getNormal(ele,i);
+    if(nor.norm() != 0.){ // otherwise no contact
+      double dianor[3][3];
+      diaprod(nor,nor,dianor);
+      for(int j=0;j<3;j++)
+        for(int k=0;k<3;k++)
+          dianor[j][k]*=penalty;
+      for(int j=0;j<nbcomp;j++)
+        for(int k=0;k<nbcomp;k++){
+          m(i+j*nbvertex,i+k*nbvertex) -= dianor[j][k];
+          m(nbcompTimesnbVertex+j,nbcompTimesnbVertex+k) -=0.5*dianor[j][k];
+        }
+    }
+  }
+  m.print("Contact Matrix");*/
+}
+
diff --git a/NonLinearSolver/contact/rigidCylinderContactTerms.h b/NonLinearSolver/contact/rigidCylinderContactTerms.h
new file mode 100644
index 0000000000..de8a87eec7
--- /dev/null
+++ b/NonLinearSolver/contact/rigidCylinderContactTerms.h
@@ -0,0 +1,113 @@
+//
+// contact base term
+//
+// Description: contact with a rigid cylinder
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2011
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+
+#ifndef RIGIDCONTACTCYLINDER_H_
+#define RIGIDCONTACTCYLINDER_H_
+#include "contactTerms.h"
+#include "contactFunctionSpace.h"
+class rigidCylinderContact;
+class massRigidCylinder : public BilinearTermBase{
+ protected:
+  double _length, _radius, _thick, _rho;
+  rigidContactSpace *_spc;
+  // Data for get function (Allocated once)
+  mutable int nbdofs;
+  mutable double masse;
+  mutable double Rint;
+ public:
+  massRigidCylinder(rigidCylinderContact *cdom,rigidContactSpace *spc);
+  massRigidCylinder(rigidContactSpace *spc,double leng, double radius,
+                    double thick,double rho) : _spc(spc), _length(leng), _radius(radius),_thick(thick), _rho(rho){}
+  // Arguments are useless but it's allow to use classical assemble function
+  void get(MElement *ele, int npts, IntPt *GP, fullMatrix<double> &m) const;
+  virtual void get(MElement *ele, int npts, IntPt *GP, std::vector<fullMatrix<double> > &mv) const
+  {
+    Msg::Error("Define me get by integration point massRigidCylinder");
+  }
+  virtual BilinearTermBase* clone () const
+  {
+    return new massRigidCylinder(_spc,_length,_radius,_thick,_rho);
+  }
+};
+
+class forceRigidCylinderContact : public rigidContactLinearTermBase<double>{
+ protected:
+  const rigidCylinderContact *_cdom;
+  double _fdgfactor, _facGC;
+  const MVertex *_vergc;
+  const SVector3* _axisDirector;
+  const double _radius;
+  const double _rcontact;
+  const double _halflength;
+  double _penalty;
+  const SPoint3 _GC;
+  // Data of get function (Allocated once)
+  mutable SPoint3 B,Bdisp,A,Adisp,C;
+  mutable double d,penetration,penpen;
+  mutable SVector3 dirAC;
+ public:
+  forceRigidCylinderContact(const rigidCylinderContact *cdom,
+                            rigidContactSpace *sp,const double thick,
+                            const unknownField *ufield);
+  ~forceRigidCylinderContact(){}
+//  void get(MElement *ele,int npts, IntPt *GP,fullVector<double> &m);
+  // specific function to this contact type ( put in rigidContactSpaceBase ??)
+  // This one cannot be called by Assemble function
+  void get(const MVertex *ver, const double disp[6],double mvalue[6]) const;
+  virtual void get(MElement *ele, int npts, IntPt *GP, std::vector<fullVector<double> > &vv) const
+  {
+    Msg::Error("define me get by gauss point forceRigidCylinderContact");
+  }
+  virtual LinearTermBase<double>* clone () const
+  {
+    return new forceRigidCylinderContact(_cdom,this->_spc,_rcontact-_radius,_ufield);
+  }
+};
+
+
+class stiffnessRigidCylinderContact : public contactBilinearTermBase<double>{
+ private:
+  // can be applied only be applied by classical get function perturbation for 1 vertex
+  void get(MElement *ele, const int verIndex, fullMatrix<double> &m) const;
+ protected:
+  const unknownField *_ufield;
+  rigidContactSpace *_spc;
+  const double _perturbation; // numerical perturbation
+  const double _doublepertexpm1;
+  // Data for get function (Allocated Once)
+  mutable double fp[6];
+  mutable double fm[6];
+  mutable int nbdofs;
+  mutable MVertex *ver;
+  mutable std::vector<Dof> R;
+  mutable std::vector<double> disp;
+  mutable double pertdisp[6];
+ public:
+  stiffnessRigidCylinderContact(rigidContactSpace *space, contactLinearTermBase<double> *lterm, const unknownField *ufield) : contactBilinearTermBase(lterm),
+                                                                                                _ufield(ufield),
+                                                                                                _perturbation(1.e-10),
+                                                                                                _doublepertexpm1(1./(2.e-10)),
+                                                                                                _spc(space), nbdofs(0){}
+  ~stiffnessRigidCylinderContact(){}
+  void get(MElement *ele, int npts, IntPt *GP, fullMatrix<double> &m) const;
+  virtual void get(MElement *ele, int npts, IntPt *GP, std::vector<fullMatrix<double> > &mv) const
+  {
+    Msg::Error("Define me get by integration point stiffnessRigidCylinderContact");
+  }
+  virtual BilinearTermBase* clone () const
+  {
+    return new stiffnessRigidCylinderContact(_spc,_lterm,_ufield);
+  }
+};
+
+
+#endif // RIGIDCONTACTCYLINDER_H_
+
diff --git a/NonLinearSolver/field/CMakeLists.txt b/NonLinearSolver/field/CMakeLists.txt
new file mode 100644
index 0000000000..56a906eb6f
--- /dev/null
+++ b/NonLinearSolver/field/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Gmsh - Copyright (C) 1997-2010 C. Geuzaine, J.-F. Remacle
+#
+# See the LICENSE.txt file for license information. Please report all
+# bugs and problems to <gmsh@geuz.org>.
+
+set(SRC
+  elementField.cpp
+  energyField.cpp
+)
+
+file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) 
+append_gmsh_src(NonLinearSolver/field "${SRC};${HDR}")
diff --git a/NonLinearSolver/field/elementField.cpp b/NonLinearSolver/field/elementField.cpp
new file mode 100644
index 0000000000..1f685758e5
--- /dev/null
+++ b/NonLinearSolver/field/elementField.cpp
@@ -0,0 +1,130 @@
+//
+// C++ Interface: terms
+//
+// Description: Base class to manage a field on element (All field are managed by element in full Dg so displacement is also
+//                                                       considered like a field on element
+//
+// The base class contains archiving data (which is not dependent of the field)
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "elementField.h"
+#include <sstream>
+#include "partDomain.h"
+void elementField::updateFileName(){
+  // add a numero to file name
+  std::ostringstream oss;
+  oss << ++numfile;
+  std::string s = oss.str();
+  std::string snum;
+  // cut filename and its extension
+  size_t ext_pos;
+  if(numfile==1){
+    ext_pos = fileName.find_last_of('.');
+    snum = "0";
+  }
+  else{
+    oss.str("");
+    oss << numfile-1;
+    snum = oss.str();
+    ext_pos = fileName.find_last_of(snum);
+  }
+  std::string newname(fileName,0,ext_pos-(snum.size()-1));
+  ext_pos = fileName.find_last_of('.');
+  std::string ext(fileName,ext_pos+1,fileName.size());
+  fileName  = newname+s+"."+ext;
+  // create initialization of file
+  FILE *fp = fopen(fileName.c_str(), "w");
+  fprintf(fp, "$MeshFormat\n2.1 0 8\n$EndMeshFormat\n");
+  fclose(fp);
+}
+
+void elementField::createFile(){
+  if(view){
+    // creation of file to store displacement (delete the previous one if exist)
+    size_t ext_pos = fileName.find_last_of('.');
+    std::string newname = fileName;
+    newname.resize(ext_pos);
+    std::string rfn = "rm "+newname+"*";
+    system(rfn.c_str());
+    FILE *fp = fopen(fileName.c_str(), "w");
+    fprintf(fp, "$MeshFormat\n2.1 0 8\n$EndMeshFormat\n");
+    fclose(fp);
+  }
+}
+
+elementField::elementField(const std::string &fnn, const uint32_t fms, const int ncomp, const dataType dt,
+                           const bool view_=true) : numfile(0), fileName(fnn), fmaxsize(fms), view(view_),
+                                                      totelem(0), numcomp(ncomp), type(dt){
+  this->createFile();
+  switch(type){
+    case ElementData :
+      dataname = "ElementData";
+      break;
+    case ElementNodeData :
+      dataname = "ElementNodeData";
+      break;
+  }
+}
+
+void elementField::buildView(std::vector<partDomain*> &vdom,const double time,
+                              const int nstep, const std::string &valuename, const int cc=-1, const bool binary=false){
+  if(view){
+    // test file size (and create a new one if needed)
+    uint32_t fileSize;
+    FILE *fp = fopen(fileName.c_str(), "r");
+    if(!fp){
+      Msg::Error("Unable to open file '%s'", fileName.c_str());
+      return;
+    }
+    fseek (fp, 0, SEEK_END);
+    fileSize = (uint32_t) (ftell(fp));
+    if(fileSize > fmaxsize) this->updateFileName();
+    fclose(fp);
+    fp = fopen(fileName.c_str(), "a");
+
+    // compute the number of element
+    if(binary) Msg::Warning("Binary write not implemented yet");
+    fprintf(fp, "$%s\n",dataname.c_str());
+    fprintf(fp, "1\n\"%s\"\n",valuename.c_str());
+    fprintf(fp, "1\n%.16g\n", time);
+    fprintf(fp, "3\n%d\n%d\n%d\n", nstep, numcomp, totelem);
+    std::vector<double> fieldData;
+    if(type == ElementNodeData){
+//      for (unsigned int i = 0; i < elasticFields.size(); ++i)
+      for(std::vector<partDomain*>::iterator itdom=vdom.begin(); itdom!=vdom.end(); ++itdom){
+        partDomain *dom = *itdom;
+        for (groupOfElements::elementContainer::const_iterator it = dom->g->begin(); it != dom->g->end(); ++it){
+          MElement *ele = *it;
+          int numv = ele->getNumVertices();
+          this->get(dom,ele,fieldData,cc);
+          fprintf(fp, "%d %d",ele->getNum(),numv);
+          for(int i=0;i<numv;i++)
+            for(int j=0;j<numcomp;j++)
+              fprintf(fp, " %.16g",fieldData[i+j*numv]);
+          fprintf(fp,"\n");
+          fieldData.clear();
+        }
+      }
+    }
+    else if(type == ElementData){
+      for (unsigned int i = 0; i < vdom.size(); ++i)
+        for (groupOfElements::elementContainer::const_iterator it = vdom[i]->g->begin(); it != vdom[i]->g->end(); ++it){
+          MElement *ele = *it;
+          fieldData.resize(numcomp);
+          this->get(vdom[i],ele,fieldData,cc);
+          fprintf(fp, "%d",ele->getNum());
+          for(int j=0;j<numcomp;j++)
+            fprintf(fp, " %.16g",fieldData[j]);
+          fprintf(fp,"\n");
+        }
+    }
+    fprintf(fp, "$End%s\n",dataname.c_str());
+    fclose(fp);
+  }
+  else Msg::Warning("No displacement view created because the variable view is set to false for this field\n");
+}
+
diff --git a/NonLinearSolver/field/elementField.h b/NonLinearSolver/field/elementField.h
new file mode 100644
index 0000000000..fdfa53888f
--- /dev/null
+++ b/NonLinearSolver/field/elementField.h
@@ -0,0 +1,51 @@
+//
+// C++ Interface: terms
+//
+// Description: Base class to manage a field on element (All field are managed by element in full Dg so displacement is also
+//                                                       considered like a field on element
+//
+// The base class contains archiving data (which is not dependent of the field)
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef ELEMENTFIELD_H_
+#define ELEMENTFIELD_H_
+#include <string>
+#include <stdint.h>
+#include "MElement.h"
+#include <vector>
+#include <iostream>
+#include <fstream>
+class partDomain;
+#include "groupOfElements.h"
+class elementField{
+ protected :
+  // data needed to archive displacement
+  // enum for chosen is ElementData or ElementNodeData more ??
+  enum dataType{ElementData, ElementNodeData};
+  dataType type;
+  bool view;
+  std::string fileName; // name of file where the displacement are store
+  long int totelem; // total number of element present in all elasticFields
+  uint32_t fmaxsize; // Size max of file in bytes (if size of file is greater a new one is created) TODO Argument for this parameter ?
+  int numfile; // numero of file
+  int numcomp;
+  std::string dataname;
+  // function to update file name
+  void updateFileName();
+  void createFile();
+
+ public :
+  elementField(const std::string &fnn, const uint32_t fms, const int ncomp, const dataType dt,
+               const bool view_);
+  ~elementField(){};
+  void setTotElem(const int ne){totelem=ne;}
+  virtual void get(partDomain* dom, MElement *ele,std::vector<double> &fieldData,const int comp=-1)=0; // comp allow to use an enum
+                                                                                         // in derivate class to choose which component to save
+  virtual void buildView(std::vector<partDomain*> &vdom,const double time,
+                  const int nstep, const std::string &valuename, const int cc,const bool binary);
+};
+#endif //
+
diff --git a/NonLinearSolver/field/energyField.cpp b/NonLinearSolver/field/energyField.cpp
new file mode 100644
index 0000000000..701150e554
--- /dev/null
+++ b/NonLinearSolver/field/energyField.cpp
@@ -0,0 +1,173 @@
+//
+// C++ Interface: energetic field
+//
+// Description: Class derived from element field to manage energetic balance
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "energyField.h"
+#include "explicitHulbertChung.h"
+#include "explicitDofManager.h"
+#include "ipField.h"
+#include "SVector3.h"
+#include "unknownField.h"
+#include "unknownDynamicField.h"
+double dot(const std::vector<double> &a, const fullVector<typename dofManager<double>::dataMat> &b){
+  double c = 0.;
+  for(int i =0; i<a.size(); i++){
+    c += a[i]*b(i);
+  }
+  return c;
+}
+
+double dot(const std::vector<double> &a, const std::vector<double> &b){
+  double c=0.;
+  for(int i =0; i<a.size(); i++){
+    c += a[i]*b[i];
+  }
+  return c;
+}
+
+double energeticField::kineticEnergy() const {
+  explicitHCDofManager<double> *ddm = dynamic_cast<explicitHCDofManager<double>*>(_pAssembler);
+  if(ddm == NULL)  return 0.; // system is not dynamic --> kinetic energy = 0
+  else return ddm->getKineticEnergy();
+}
+
+double energeticField::kineticEnergy(MElement *ele, const partDomain *dom) const{
+  explicitHulbertChung<double> * esys = dynamic_cast<explicitHulbertChung<double>*>(_lsys);
+  explicitHCDofManager<double> *ddm = dynamic_cast<explicitHCDofManager<double>*>(_pAssembler);
+  double ener=0.;
+  if(ddm != NULL){
+    // get Dof
+    std::vector<Dof> R;
+    std::vector<double> velocities;
+    std::vector<double> vmass;
+    FunctionSpaceBase *sp = dom->getFunctionSpace();
+    sp->getKeys(ele,R);
+    int nkeys = sp->getNumKeys(ele);
+    ddm->getDofValue(R,velocities,initialCondition::velocity);
+    ddm->getVertexMass(R,vmass);
+    for(int i=0; i!=nkeys; i++)
+      ener+=vmass[i]*velocities[i]*velocities[i];
+    R.clear(); velocities.clear(); vmass.clear();
+  }
+  return ener;
+}
+
+double energeticField::deformationEnergy(MElement *ele, const partDomain *dom) const{
+  return _ipf->computeDeformationEnergy(ele,dom);
+}
+
+double energeticField::deformationEnergy() const{
+  return _ipf->computeDeformationEnergy();
+}
+
+double energeticField::externalWork(){
+  double Deltawext=0.;
+  for(std::vector<partDomain*>::iterator itdom=_domvec.begin(); itdom!=_domvec.end();++itdom){
+    partDomain *dom = *itdom;
+    for(partDomain::neuContainer::iterator itn=dom->neuBegin(); itn!=dom->neuEnd();++itn){
+      nonLinearNeumannBC *neu = *itn;
+      FunctionSpaceBase *neuspace = neu->_space;
+      fullVector<typename dofManager<double>::dataMat> localVector;
+      std::vector<Dof> R;
+      std::vector<double> disp;
+      std::vector<double> deltau;
+      for(groupOfElements::elementContainer::const_iterator it = neu->g->begin(); it!=neu->g->end(); ++it){
+        MElement *e = *it;
+        R.clear(); disp.clear(); deltau.clear();
+        IntPt *GP;
+        //int npts=dom->getBulkGaussIntegrationRule()->getIntPoints(e,&GP); ?????????,
+        int npts = neu->integ->getIntPoints(e,&GP);
+        neu->_term->get(e,npts,GP,localVector);
+        fullVector<typename dofManager<double>::dataMat> fextnp1(localVector);
+        neuspace->getKeys(e,R);
+        _ufield->get(R,disp);
+        int ndofs = neuspace->getNumKeys(e);
+        // DeltaWext = 0.5*(Fn+1+Fn)*(un+1-un)
+        for(int i=0;i<ndofs;i++){
+          _fextnp1[R[i]] = localVector(i);
+          localVector(i) += _fextn[R[i]];
+          deltau.push_back(disp[i] - _dispn[R[i]]);
+          _dispnp1[R[i]] = disp[i];
+        }
+        Deltawext += dot(deltau,localVector);
+      }
+    }
+ }
+
+  // Now compute the work of external forces due to prescribed displacement (-Wint - Winertia)
+  // ATTENTION _allaef containts -fint so no minus
+  // Do the scalar product on vector (more efficient) TO DO THE SCALAR PRODUCT WITH BLAS HOW ??
+  std::vector<double> disp;
+  std::vector<double> acc;
+  std::vector<double> _mass;
+  std::vector<double> forceval;
+//  std::vector<double> finertval;
+  std::vector<Dof> R;
+  for(int i=0; i<_allaef.size(); i++){
+    R.push_back(_allaef[i].D);
+    forceval.push_back(_allaef[i].val);
+  }
+  _ufield->get(R,disp);
+  // Compute inertial forces if needed
+  explicitHCDofManager<double> *ddm = dynamic_cast<explicitHCDofManager<double>*>(_pAssembler);
+  if(ddm != NULL){ // otherwise static cases and no inertial forces
+    unknownDynamicField *duf = dynamic_cast<unknownDynamicField*>(_ufield);
+    duf->get(R,acc,initialCondition::acceleration);
+    ddm->getVertexMass(R,_mass);
+    for(int i=0; i<forceval.size(); i++)
+      forceval[i] -= _mass[i]*acc[i];
+  }
+  for(int i=0;i<R.size(); i++){
+    _fextnp1[R[i]] = forceval[i];
+    forceval[i] += _fextn[R[i]];
+    _dispnp1[R[i]] = disp[i];
+    disp[i] -= _dispn[R[i]];
+  }
+
+  Deltawext += dot(forceval,disp);
+
+  // swap value (next step)
+  _fextn.swap(_fextnp1);
+  _dispn.swap(_dispnp1);
+
+  // New value of Wext W = 0.5*F*u
+  _wext += 0.5*Deltawext;
+  return _wext;
+}
+
+void energeticField::get(partDomain *dom,MElement *ele,std::vector<double> &ener, const int cc){
+  switch(cc){
+   //case 0:
+   // ener[0] = this->kineticEnergy(ele,dom) + this->deformationEnergy(ele,dom);
+   // break;
+   case 1:
+    ener[0] = this->kineticEnergy(ele,dom);
+    break;
+   case 2:
+    ener[0] = this->deformationEnergy(ele,dom);
+    break;
+   case 3:
+    ener[0] = this->externalWork();
+   default:
+    ener[0] = this->kineticEnergy(ele,dom) + this->deformationEnergy(ele,dom);
+  }
+}
+
+void energeticField::archive(const double time){
+  FILE *fp = fopen(_fname.c_str(),"a");
+  double ekin,edefo,etot,wext;
+  ekin = this->kineticEnergy();
+  edefo= this->deformationEnergy();
+  wext = this->externalWork();
+  etot = ekin + edefo;
+  fprintf(fp,"%e;%e;%e;%e;%e;\n",time,ekin,edefo,wext,etot);
+  fclose(fp);
+}
+
diff --git a/NonLinearSolver/field/energyField.h b/NonLinearSolver/field/energyField.h
new file mode 100644
index 0000000000..06333e0f6b
--- /dev/null
+++ b/NonLinearSolver/field/energyField.h
@@ -0,0 +1,89 @@
+//
+// C++ Interface: energetic field
+//
+// Description: Class derived from element field to manage energetic balance
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef ENERGETICFIELD_H_
+#define ENERGETICFIELD_H_
+
+#include "elementField.h"
+#include "nonLinearMechSolver.h"
+class energeticField : public elementField{
+ protected:
+  linearSystem<double> *_lsys;
+  IPField *_ipf;
+  unknownField *_ufield;
+  dofManager<double> *_pAssembler;
+  const std::string _fname; // file to store total energy in function of time
+  std::vector<partDomain*> &_domvec;
+  std::vector<fextPrescribedDisp> &_allaef;
+  std::map<Dof,double> _fextn;
+  std::map<Dof,double> _dispn;
+  std::map<Dof,double> _fextnp1;
+  std::map<Dof,double> _dispnp1;
+
+  double _wext;
+
+ public:
+  energeticField(linearSystem<double> *lsys, IPField *ipf,
+                 unknownField *ufield, dofManager<double> *pAssembler,
+                 std::vector<partDomain*> &domvec,
+                 std::vector<fextPrescribedDisp> &allaef) : elementField("energy.msh",100000000,1,elementField::ElementData,true),
+                                              _lsys(lsys), _ipf(ipf), _ufield(ufield), _pAssembler(pAssembler),
+                                              _fname("energy.csv"), _domvec(domvec), _allaef(allaef), _wext(0.){
+    // initialize file to store energy
+    FILE *fp = fopen(_fname.c_str(),"w");
+    fprintf(fp,"Time;Kinetic;Deformation;Wext;Total\n");
+    fprintf(fp,"0.;0.;0.;0;0.\n"); // false if initial deformation FIX IT HOW ??
+    fclose(fp);
+    long int nelem=0;
+    for(std::vector<partDomain*>::iterator itdom=_domvec.begin(); itdom!=_domvec.end();++itdom){
+      partDomain *dom = *itdom;
+      nelem+=dom->g->size();
+      for(partDomain::neuContainer::iterator itn=dom->neuBegin(); itn!=dom->neuEnd();++itn){
+        nonLinearNeumannBC *neu = *itn;
+        FunctionSpaceBase *neuspace = neu->_space;
+        std::vector<Dof> R;
+        for(groupOfElements::elementContainer::const_iterator it = neu->g->begin(); it!=neu->g->end(); ++it){
+          MElement *e = *it;
+          R.clear();
+          neuspace->getKeys(e,R);
+          int ndofs = neuspace->getNumKeys(e);
+          for(int i=0;i<ndofs;i++){
+            _fextn.insert(std::pair<Dof,double>(R[i],0.));
+            _dispn.insert(std::pair<Dof,double>(R[i],0.));
+            _fextnp1.insert(std::pair<Dof,double>(R[i],0.));
+            _dispnp1.insert(std::pair<Dof,double>(R[i],0.));
+          }
+        }
+      }
+    }
+    this->setTotElem(nelem);
+    // Wext for prescribed displacement
+    for(int i=0; i<_allaef.size(); i++){
+      _fextn.insert(std::pair<Dof,double>(_allaef[i].D,0.));
+      _dispn.insert(std::pair<Dof,double>(_allaef[i].D,0.));
+      _fextnp1.insert(std::pair<Dof,double>(_allaef[i].D,0.));
+      _dispnp1.insert(std::pair<Dof,double>(_allaef[i].D,0.));
+    }
+  }
+  ~energeticField(){}
+
+  // functions to compute the different parts of energy
+  double kineticEnergy() const; // More efficient than a loop on element thanks to vector operation via PETSC
+  double kineticEnergy(MElement *ele, const partDomain *dom) const;
+  double deformationEnergy(MElement *ele, const partDomain *dom) const;
+  double deformationEnergy() const;
+  double externalWork();
+
+  void get(partDomain *dom,MElement *ele,std::vector<double> &ener, const int cc = -1);
+  void archive(const double time);
+};
+#endif // ENERGETICFIELD_H_
+
diff --git a/NonLinearSolver/internalPoints/CMakeLists.txt b/NonLinearSolver/internalPoints/CMakeLists.txt
index 5b693a1305..2990968ad2 100644
--- a/NonLinearSolver/internalPoints/CMakeLists.txt
+++ b/NonLinearSolver/internalPoints/CMakeLists.txt
@@ -4,7 +4,10 @@
 # bugs and problems to <gmsh@geuz.org>.
 
 set(SRC
+  ipField.cpp
   ipstate.cpp
+  # inline
+  ipvariable.h
 )
 
 file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) 
diff --git a/NonLinearSolver/internalPoints/ipField.cpp b/NonLinearSolver/internalPoints/ipField.cpp
new file mode 100644
index 0000000000..077254f577
--- /dev/null
+++ b/NonLinearSolver/internalPoints/ipField.cpp
@@ -0,0 +1,293 @@
+//
+// C++ Interface: terms
+//
+// Description: Class to compute Internal point
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "ipField.h"
+#include "mlaw.h"
+#include "ipstate.h"
+#include "nonLinearMechSolver.h"
+void IPField::compute1state(IPStateBase::whichState ws){
+  for(std::vector<partDomain*>::iterator itdom=_efield->begin(); itdom!=_efield->end(); ++itdom){
+    partDomain *dom = *itdom;
+    dom->computeIPVariable(_AIPS,_ufield,ws);
+  }
+}
+
+void IPField::initialBroken(MElement *iele, materialLaw* mlaw ){
+  Msg::Info("Interface element %d is broken at initialization",iele->getNum());
+  materialLaw2LawsInitializer * mflaw = dynamic_cast<materialLaw2LawsInitializer*>(mlaw);
+  // get ipstate
+  AllIPState::ipstateElementContainer *vips;
+  IPStateBase *ips;
+  vips = _AIPS->getIPstate(iele->getNum());
+  for(int i=0;i<vips->size();i++){
+    ips = (*vips)[i];
+    mflaw->initialBroken(ips);
+  }
+}
+
+void IPField::initialBroken(GModel* pModel, std::vector<int> &vnumphys){
+  std::vector<MVertex*> vv;
+  for(int i=0;i<vnumphys.size();i++){
+    // get the vertex associated to the physical entities
+    pModel->getMeshVerticesForPhysicalGroup(1,vnumphys[i],vv);
+    // find the InterfaceElement associated to these vertex (identify interior node as degree 2 min)
+    for(std::vector<partDomain*>::iterator itfield = _efield->begin(); itfield != _efield->end(); ++itfield){
+      dgPartDomain *dgdom = dynamic_cast<dgPartDomain*>(*itfield);
+      for(groupOfElements::elementContainer::const_iterator it = dgdom->gi->begin(); it!=dgdom->gi->end(); ++it)
+        for(int k=0;k<vv.size();k++)
+          if(vv[k] == (*it)->getVertex(2) ) this->initialBroken(*it, dgdom->getMaterialLaw());
+    }
+    vv.clear();
+  }
+}
+
+void IPField::archive(const double time){
+  for(std::vector<ip2archive>::iterator it=viparch.begin(); it!=viparch.end(); ++it){
+    ip2archive &ipa = *it;
+    // get ip value
+    double val;
+    switch(ipa.comp){
+      case -1 :
+        val = this->getStress(ipa.domain,ipa.ele,IPStateBase::current,ipa.numgauss,-1);
+        break;
+      case 0 :
+        val = this->getStress(ipa.domain,ipa.ele,IPStateBase::current,ipa.numgauss,component::xx);
+        break;
+      case 1 :
+        val = this->getStress(ipa.domain,ipa.ele,IPStateBase::current,ipa.numgauss,component::yy);
+        break;
+      case 2 :
+        val = this->getStress(ipa.domain,ipa.ele,IPStateBase::current,ipa.numgauss,component::zz);
+        break;
+      case 3 :
+        val = this->getStress(ipa.domain,ipa.ele,IPStateBase::current,ipa.numgauss,component::xy);
+        break;
+      case 4 :
+        val = this->getStress(ipa.domain,ipa.ele,IPStateBase::current,ipa.numgauss,-1);
+    }
+    FILE *fp = fopen(ipa.fname.c_str(),"a");
+    fprintf(fp,"%e;%e\n",time,val);
+    fclose(fp);
+  }
+}
+
+double IPField::computeDeformationEnergy(MElement *ele, const partDomain *dom) const
+{
+  IntPt *GP;
+  double jac[3][3];
+  int npts = dom->getBulkGaussIntegrationRule()->getIntPoints(ele,&GP);
+  AllIPState::ipstateElementContainer *vips = _AIPS->getIPstate(ele->getNum());
+  double ener =0.;
+  for(int i=0;i<npts;i++){
+    IPStateBase* ips = (*vips)[i];
+    IPVariableMechanics *ipv = dynamic_cast<IPVariableMechanics*>(ips->getState(IPStateBase::current));
+    #ifdef DEBUG_
+     if(ipv == NULL){
+       Msg::Error("Compute defo energy on an non mechanics gauss' point");
+       return 0.;
+     }
+    #endif
+    double enerpt = ipv->defoEnergy();
+    // gauss point weight
+    double weight = GP[i].weight;
+    // Shell Only compute detJ OK
+//    IPVariableShell *ipvs = dynamic_cast<IPVariableShell*>(ipv);
+//    double detJ2 = ipvs->getLocalBasis()->getJacobian();
+    const double u = GP[i].pt[0]; const double v = GP[i].pt[1]; const double w = GP[i].pt[2];
+    const double detJ = ele->getJacobian(u, v, w, jac);
+    ener += weight*detJ*enerpt;
+  }
+  return ener;
+}
+
+IPField::IPField(std::vector<partDomain*> *ef,dofManager<double>* pa,
+          GModel *pmo, unknownField* uf, std::vector<archiveIPVariable> &vaip): _efield(ef), _dm(pa),
+                                                                                     _ufield(uf),
+                                                                                     elementField("stress.msh",100000000,1,
+                                                                                                  elementField::ElementData,true){
+  // Creation of storage for IP data
+  _AIPS = new AllIPState(pmo, *_efield);
+  // compute the number of element
+  long int nelem=0;
+  for(std::vector<partDomain*>::iterator itdom=_efield->begin(); itdom!=_efield->end(); ++itdom){
+    partDomain *dom = *itdom;
+    nelem+= dom->g->size();
+  }
+  this->setTotElem(nelem);
+  this->buildView(*_efield,0.,0,"VonMises",-1,false);
+  this->buildView(*_efield,0.,0,"sigmaxx",0,false);
+  this->buildView(*_efield,0.,0,"sigmayy",1,false);
+  this->buildView(*_efield,0.,0,"tauxy",3,false);
+
+  // Initiate file
+  FILE *fp = fopen("cohesiveLaw.csv","w");
+  fprintf(fp,"time;inter num;gauss num;sc;deltac;delta;d_n;d_t;n22;m22;n21;m21\n");
+  fclose(fp);
+  fp = fopen("crackPath.csv","w");
+  fprintf(fp,"time;inter num;x0;y0;z0;x1;y1;z1\n");
+  fclose(fp);
+
+  // Build the viparch vector (find the nearest ipvariable to each given vertex)
+  for(std::vector<archiveIPVariable>::iterator ita=vaip.begin(); ita!=vaip.end(); ++ita){
+    archiveIPVariable &aip = *ita;
+    // get the vertex of the node
+    groupOfElements g(0,aip.numphys);
+    groupOfElements::vertexContainer::iterator itv = g.vbegin();
+    MVertex *ver = *itv;
+    bool flagfind=false;
+    MElement *elefind = NULL;
+    partDomain *domfind;
+    dgPartDomain *dgdom;
+    bool samedim = false;
+    for(std::vector<partDomain*>::iterator itdom=_efield->begin(); itdom!=_efield->end(); ++itdom){
+      partDomain *dom = *itdom;
+      dgdom = dynamic_cast<dgPartDomain*>(dom);
+      if(dgdom != NULL){ // otherwise the domain doesn't contain interface element
+        for(groupOfElements::elementContainer::iterator it2 = dgdom->gi->begin(); it2 != dgdom->gi->end(); ++it2 ){
+          MElement *iele = *it2; // two elements on interface
+          int numv = iele->getNumVertices();
+          for(int j=0;j<numv;j++){
+            if(ver == iele->getVertex(j)){
+              elefind = iele;
+              domfind = dom;
+              flagfind = true;
+              break;
+            }
+          }
+          if(flagfind) break;
+        }
+        if(!flagfind){ // the interface element are on boundary
+          for(groupOfElements::elementContainer::iterator iti = dgdom->gib->begin(); iti!=dgdom->gib->end(); ++iti){
+            MElement *ie = *iti;
+            int numv = ie->getNumVertices();
+            for(int j=0;j<numv;j++){
+              if(ver == ie->getVertex(j)){
+                elefind = ie;
+                domfind = dom;
+                flagfind = true;
+                break;
+              }
+            }
+            if(flagfind) break;
+          }
+        }
+      }
+      if(!flagfind){ // no interface element found (Can happend on boundary)
+        for(groupOfElements::elementContainer::iterator it2 = dom->g->begin(); it2 != dom->g->end(); ++it2 ){
+          MElement *ele = *it2;
+          int numv = ele->getNumVertices();
+          for(int j=0;j<numv;j++){
+            if(ver == ele->getVertex(j)){
+              elefind = ele;
+              samedim = true;
+              flagfind = true;
+              domfind = dom;
+              break;
+            }
+          }
+          if(flagfind) break;
+        }
+      }
+    }
+    // Now the element where is situated the node is know find the nearest Gauss Point
+    IntPt *GP;
+    QuadratureBase *gq;
+    if(samedim){ //bulk point
+      gq = domfind->getBulkGaussIntegrationRule();
+    }
+    else{
+      dgPartDomain *dgfind = dynamic_cast<dgPartDomain*>(domfind);
+      gq = dgfind->getInterfaceGaussIntegrationRule();
+    }
+    int npts = gq->getIntPoints(elefind,&GP);
+     // coordonate in uvw of vertex
+    double uvw[3];
+    double xyz[3];
+    xyz[0] = ver->x(); xyz[1] = ver->y(); xyz[2] = ver->z();
+    elefind->xyz2uvw(xyz,uvw);
+    double distmin = 1.e100; // inf value at itnitialization
+    double dist, u,v,w;
+    int nummin;
+    for(int i=0;i<npts;i++){
+      u = GP[i].pt[0]; v = GP[i].pt[1]; w = GP[i].pt[2];
+      dist = sqrt((u-uvw[0])*(u-uvw[0]) + (v-uvw[1])*(v-uvw[1]) + (w-uvw[2])*(w-uvw[2]));
+      if(dist<distmin){
+        distmin = dist;
+        nummin = i;
+      }
+    }
+    // Store information
+    viparch.push_back(ip2archive(elefind,domfind,aip.numphys,nummin,aip.ipval));
+    // remove file LINUX ONLY ??
+    std::ostringstream oss;
+    oss << aip.numphys;
+    std::string s = oss.str();
+    oss.str("");
+    oss << aip.ipval;
+    std::string s2 = oss.str();
+    std::string rfname = "rm IP"+s+"val"+s2+".csv";
+    system(rfname.c_str());
+  }
+}
+
+double IPField::getStress(const partDomain *ef,MElement *ele, const IPStateBase::whichState ws,
+                            const int num, const int cmp) const{
+  double svm =0.;
+  if(num<10000){ // value in a particular gauss point
+    IPStateBase* ips = (*_AIPS->getIPstate(ele->getNum()))[num];
+    IPVariableMechanics *ipv = dynamic_cast<IPVariableMechanics*>(ips->getState(ws));
+    #ifdef DEBUG_
+     if(ipv != NULL)
+    #endif
+      return ipv->stressComp(cmp);
+    #ifdef DEBUG_
+     else{
+      Msg::Error("Compute Von Mises stress on a non mechanical element");
+      return 0.;
+     }
+    #endif
+  }
+  else{ // loop on all IPVariable of an element and return a particular value (max, min, mean)
+    double svmp;
+    IntPt *GP;
+    int npts = ef->getBulkGaussIntegrationRule()->getIntPoints(ele,&GP);
+    AllIPState::ipstateElementContainer *vips = _AIPS->getIPstate(ele->getNum());
+    for(int i=0;i<npts;i++){
+      IPStateBase* ips = (*vips)[i];
+      IPVariableMechanics *ipv = dynamic_cast<IPVariableMechanics*>(ips->getState(ws));
+      #ifdef DEBUG_
+      if(ipv == NULL){
+        Msg::Error("Compute Von Mises stress on a non mechanical element");
+        return 0.;
+      }
+      #endif
+      svmp = ipv->stressComp(cmp);
+      if(i==0)
+        svm = svmp;
+      else{
+        switch(num){
+          case IPField::max :
+            if(svmp>svm) svm=svmp;
+            break;
+          case IPField::min :
+            if(svmp<svm) svm=svmp;
+            break;
+          case IPField::mean :
+            svm+=svmp;
+            break;
+        }
+      }
+    }
+    if(num==IPField::mean) svm/=(double)npts;
+  }
+  return svm;
+}
+
diff --git a/NonLinearSolver/internalPoints/ipField.h b/NonLinearSolver/internalPoints/ipField.h
new file mode 100644
index 0000000000..a5a427f36a
--- /dev/null
+++ b/NonLinearSolver/internalPoints/ipField.h
@@ -0,0 +1,237 @@
+//
+// C++ Interface: terms
+//
+// Description: Class to compute Internal point
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+# ifndef _IPFIELD_H_
+# define _IPFIELD_H_
+#include<vector>
+#include"Dof3IntType.h"
+#include"quadratureRules.h"
+#include "unknownField.h"
+#include "elementField.h"
+#include "GModel.h"
+#include "ipstate.h"
+#include "partDomain.h"
+struct archiveIPVariable;
+class IPField : public elementField {
+  protected :
+    // Struct for archiving
+    struct ip2archive{
+      MElement *ele; // element where the point is situated (if node is common to several element the first one met is chosen. Normally OK continuity)
+      int numgauss; // local gauss num
+      std::string fname; // file name where archive IP
+      int comp;  // component to archive
+      const partDomain *domain; // address of domain needed to access IP
+      // constructor
+      ip2archive(MElement *e, const partDomain *dom, const int nump, const int num, const int ipval) : ele(e),
+                                                                                           domain(dom),numgauss(num), comp(ipval){
+        // build file name
+        std::ostringstream oss;
+        oss << nump;
+        std::string s = oss.str();
+        oss.str("");
+        oss << ipval;
+        std::string s2 = oss.str();
+        fname = "IP"+s+"val"+s2+".csv";
+      }
+      ip2archive(const ip2archive &source) : ele(source.ele), domain(source.domain){
+        numgauss = source.numgauss;
+        fname = source.fname;
+        comp =source.comp;
+      }
+      ~ip2archive(){}
+    };
+    std::vector<partDomain*>* _efield;
+    dofManager<double> *_dm;
+    AllIPState *_AIPS;
+    unknownField *_ufield;
+    std::vector<ip2archive> viparch;
+//    normalVariation _nvaripfield; // To avoid multiple allocation
+ public :
+  enum ElemValue{mean=10001, max=10002, min=10003}; // enum to select a particular value on element
+  IPField(std::vector<partDomain*> *ef,dofManager<double>* pa,
+          GModel *pmo, unknownField* uf, std::vector<archiveIPVariable> &vaip);
+  void archive(const double time);
+
+  AllIPState* getAips() const {return _AIPS;}
+  ~IPField(){delete _AIPS;}
+  void compute1state(IPStateBase::whichState ws);
+
+  // On element only ?? Higher level to pass the associated element (pass edge num)
+  // get value with a operation
+  double getStress(const partDomain *ef,MElement *ele, const IPStateBase::whichState ws, const int num,
+                   const int cmp) const;
+  // function to archive
+  virtual void get(partDomain *dom, MElement *ele, std::vector<double> &stress, const int cc=-1){
+    switch(cc){
+      case -1 :
+        stress[0]= this->getStress(dom,ele,IPStateBase::current,mean,-1);
+        break;
+      case 0 :
+        stress[0] = this->getStress(dom,ele,IPStateBase::current,mean,component::xx);
+        break;
+      case 1 :
+        stress[0] = this->getStress(dom,ele,IPStateBase::current,mean,component::yy);
+        break;
+      case 2 :
+        stress[0] = this->getStress(dom,ele,IPStateBase::current,mean,component::zz);
+        break;
+      case 3 :
+        stress[0] = this->getStress(dom,ele,IPStateBase::current,mean,component::xy);
+        break;
+      case 4 :
+        stress[0]= this->getStress(dom,ele,IPStateBase::current,max,-1);
+    }
+  }
+
+  // Interaction with Aips
+  void copy(IPStateBase::whichState source, IPStateBase::whichState dest){_AIPS->copy(source,dest);}
+  void nextStep(const double time=0.){
+    _AIPS->nextStep();
+  }
+
+  // initial broken
+  void initialBroken(GModel* pModel, std::vector<int> &vnumphys);
+  void initialBroken(MElement *iele, materialLaw *mlaw);
+
+  template<class T> void getIPv(const MElement *ele,const T** vipv, const IPStateBase::whichState ws= IPStateBase::current) const
+  {
+    AllIPState::ipstateElementContainer* vips = _AIPS->getIPstate(ele->getNum());
+    for(int i=0; i<vips->size(); i++){
+      IPStateBase* ips = (*vips)[i];
+      vipv[i] = dynamic_cast<const T*>(ips->getState(ws));
+    }
+  }
+  template<class T> void getIPv(const MElement *ele,const T** vipv, const T** vipvprev) const
+  {
+    AllIPState::ipstateElementContainer *vips = _AIPS->getIPstate(ele->getNum());
+    for(int i=0; i<vips->size(); i++){
+      IPStateBase* ips = (*vips)[i];
+      vipv[i] = dynamic_cast<const T*>(ips->getState(IPStateBase::current));
+      vipvprev[i] = dynamic_cast<const T*>(ips->getState(IPStateBase::previous));
+    }
+  }
+  template<class T1,class T2> void getIPv(const MInterfaceElement *iele, const T1** vipv_m, const T2** vipv_p,
+                                          const IPStateBase::whichState ws=IPStateBase::current) const
+  {
+    AllIPState::ipstateElementContainer *vips = _AIPS->getIPstate(iele->getNum());
+    // SAME NUMBER OF GAUSS POINTS ON BOTH SIDES
+    int npts = vips->size()/2;
+    for(int i=0;i<npts;i++){
+      IPStateBase *ipsm = (*vips)[i];
+      IPStateBase *ipsp = (*vips)[i+npts];
+      vipv_m[i] = dynamic_cast<const T1*>(ipsm->getState(ws));
+      vipv_p[i] = dynamic_cast<const T2*>(ipsp->getState(ws));
+    }
+  }
+  template<class T1,class T2> void getIPv(const MInterfaceElement *iele, const T1** vipv_m, const T1** vipvprev_m,
+                                             const T2** vipv_p, const T2** vipvprev_p) const
+  {
+    AllIPState::ipstateElementContainer *vips = _AIPS->getIPstate(iele->getNum());
+    // SAME NUMBER OF GAUSS POINTS ON BOTH SIDES
+    int npts = vips->size()/2;
+    for(int i=0;i<npts;i++){
+      IPStateBase *ipsm = (*vips)[i];
+      IPStateBase *ipsp = (*vips)[i+npts];
+      vipv_m[i] = dynamic_cast<const T1*>(ipsm->getState(IPStateBase::current));
+      vipv_p[i] = dynamic_cast<const T2*>(ipsp->getState(IPStateBase::current));
+      vipvprev_m[i] = dynamic_cast<const T1*>(ipsm->getState(IPStateBase::previous));
+      vipvprev_p[i] = dynamic_cast<const T2*>(ipsp->getState(IPStateBase::previous));
+    }
+  }
+  template<class T1,class T2> void getIPv(const MInterfaceElement *iele, T1** vipv_m, T2** vipv_p,
+                                             const IPStateBase::whichState ws=IPStateBase::current) const
+  {
+    AllIPState::ipstateElementContainer *vips = _AIPS->getIPstate(iele->getNum());
+    // SAME NUMBER OF GAUSS POINTS ON BOTH SIDES
+    int npts = vips->size()/2;
+    for(int i=0;i<npts;i++){
+      IPStateBase *ipsm = (*vips)[i];
+      IPStateBase *ipsp = (*vips)[i+npts];
+      vipv_m[i] = dynamic_cast<T1*>(ipsm->getState(ws));
+      vipv_p[i] = dynamic_cast<T2*>(ipsp->getState(ws));
+    }
+  }
+  template<class T1,class T2> void getIPv(const MInterfaceElement *iele, T1** vipv_m, T2** vipvprev_m,
+                                             T2** vipv_p, T2** vipvprev_p) const
+  {
+    AllIPState::ipstateElementContainer *vips = _AIPS->getIPstate(iele->getNum());
+    // SAME NUMBER OF GAUSS POINTS ON BOTH SIDES
+    int npts = vips->size()/2;
+    for(int i=0;i<npts;i++){
+      IPStateBase *ipsm = (*vips)[i];
+      IPStateBase *ipsp = (*vips)[i+npts];
+      vipv_m[i] = dynamic_cast<T1*>(ipsm->getState(IPStateBase::current));
+      vipv_p[i] = dynamic_cast<T2*>(ipsp->getState(IPStateBase::current));
+      vipvprev_m[i] = dynamic_cast<T1*>(ipsm->getState(IPStateBase::previous));
+      vipvprev_p[i] = dynamic_cast<T2*>(ipsp->getState(IPStateBase::previous));
+    }
+  }
+
+
+  template<class T1> void getIPv(const MInterfaceElement *iele, const T1** vipv_m,
+                                   const IPStateBase::whichState ws=IPStateBase::current) const
+  {
+    AllIPState::ipstateElementContainer *vips = _AIPS->getIPstate(iele->getNum());
+    // SAME NUMBER OF GAUSS POINTS ON BOTH SIDES
+    int npts = vips->size();
+    for(int i=0;i<npts;i++){
+      IPStateBase *ipsm = (*vips)[i];
+      vipv_m[i] = dynamic_cast<const T1*>(ipsm->getState(ws));
+    }
+  }
+  template<class T1> void getIPv(const MInterfaceElement *iele, const T1** vipv_m, const T1** vipvprev_m) const
+  {
+    AllIPState::ipstateElementContainer *vips = _AIPS->getIPstate(iele->getNum());
+    // SAME NUMBER OF GAUSS POINTS ON BOTH SIDES
+    int npts = vips->size();
+    for(int i=0;i<npts;i++){
+      IPStateBase *ipsm = (*vips)[i];
+      vipv_m[i] = dynamic_cast<const T1*>(ipsm->getState(IPStateBase::current));
+      vipvprev_m[i] = dynamic_cast<const T1*>(ipsm->getState(IPStateBase::previous));
+    }
+  }
+
+  template<class T1> void getIPv(const MInterfaceElement *iele, T1** vipv_m,
+                                   const IPStateBase::whichState ws=IPStateBase::current) const
+  {
+    AllIPState::ipstateElementContainer *vips = _AIPS->getIPstate(iele->getNum());
+    int npts = vips->size();
+    for(int i=0;i<npts;i++){
+      IPStateBase *ipsm = (*vips)[i];
+      vipv_m[i] = dynamic_cast<T1*>(ipsm->getState(ws));
+    }
+  }
+  template<class T1> void getIPv(const MInterfaceElement *iele, T1** vipv_m, T1** vipvprev_m) const
+  {
+    AllIPState::ipstateElementContainer *vips = _AIPS->getIPstate(iele->getNum());
+    int npts = vips->size();
+    for(int i=0;i<npts;i++){
+      IPStateBase *ipsm = (*vips)[i];
+      vipv_m[i] = dynamic_cast<T1*>(ipsm->getState(IPStateBase::current));
+      vipvprev_m[i] = dynamic_cast<T1*>(ipsm->getState(IPStateBase::previous));
+    }
+  }
+  double computeDeformationEnergy(MElement *ele, const partDomain *dom) const;
+  double computeDeformationEnergy() const{
+//    Msg::Error("Defo energy only for shell");
+    double ener=0.;
+    for(std::vector<partDomain*>::const_iterator itdom=_efield->begin(); itdom!=_efield->end(); ++itdom){
+      partDomain *dom = *itdom;
+      for(groupOfElements::elementContainer::const_iterator it=dom->g->begin(); it!=dom->g->end(); ++it){
+        MElement *ele = *it;
+        ener += this->computeDeformationEnergy(ele,dom);
+      }
+    }
+    return ener;
+  }
+};
+#endif // IPField
+
diff --git a/NonLinearSolver/internalPoints/ipstate.cpp b/NonLinearSolver/internalPoints/ipstate.cpp
index d3333c5644..0d7ab3c965 100644
--- a/NonLinearSolver/internalPoints/ipstate.cpp
+++ b/NonLinearSolver/internalPoints/ipstate.cpp
@@ -1 +1,125 @@
+//
+// C++ Interface: terms
+//
+// Description: Class to store internal variables at gauss point
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
 #include "ipstate.h"
+#include "partDomain.h"
+#include "MInterfaceElement.h"
+#include "MElement.h"
+IP3State::~IP3State(){
+  if(_initial) delete _initial;
+  if(_step2) delete _step2;
+  if(_step1) delete _step1;
+}
+
+IP3State::IP3State(const IP3State &source) : IPStateBase()
+{
+  _initial = source._initial;
+  _step1 = source._step1;
+  _step2 = source._step2;
+  _st = source._st;
+}
+
+IP3State & IP3State::operator = (const IPStateBase &source){
+  IPStateBase::operator=(source);
+  const IP3State *src = dynamic_cast<const IP3State*>(&source);
+  *_initial = *src->_initial;
+  *_step1 = *src->_step1;
+  *_step2 = *src->_step2;
+  _st = src->_st;
+  return *this;
+}
+
+IPVariable* IP3State::getState(const whichState wst) const
+{
+  switch(wst){
+    case initial :
+      return _initial;
+      break;
+    case previous :
+      if(*_st) return _step1; else return _step2;
+      break;
+    case current :
+      if(*_st) return _step2; else return _step1;
+      break;
+    default : Msg::Error("Impossible to select the desired state for internal variable \n");
+  }
+}
+
+AllIPState::AllIPState(GModel *pModel, std::vector<partDomain*> &vdom)
+{
+  state = true; // at creation of object state is true
+  IntPt *GP; // needed to know the number of gauss point
+  for(std::vector<partDomain*>::iterator itdom=vdom.begin(); itdom!=vdom.end(); ++itdom){
+    partDomain *dom = *itdom;
+    if(dom->IsInterfaceTerms()){
+      dgPartDomain *dgdom = dynamic_cast<dgPartDomain*>(dom);
+      materialLaw *mlawMinus = dgdom->getMaterialLawMinus();
+      materialLaw *mlawPlus = dgdom->getMaterialLawPlus();
+      // loop
+      for(groupOfElements::elementContainer::const_iterator it=dgdom->gi->begin(); it!=dgdom->gi->end();++it){
+        MElement *ele = *it;
+        MInterfaceElement* iele = dynamic_cast<MInterfaceElement*>(ele);
+ 	    // 2* because IP is duplicated for fullDg formulation
+        int npts_inter=2*dgdom->getInterfaceGaussIntegrationRule()->getIntPoints(ele,&GP);
+        ipstateElementContainer tp(npts_inter);
+        for(int i=0;i<npts_inter/2;i++){
+          mlawMinus->createIPState(tp[i],&state,ele,iele->getElem(0)->getNumVertices());
+        }
+        for(int i=npts_inter/2;i<npts_inter;i++){
+          mlawPlus->createIPState(tp[i],&state,ele,iele->getElem(1)->getNumVertices());
+        }
+        _mapall.insert(ipstatePairType(iele->getNum(),tp));
+      }
+      // Virtual interface element (no duplication)
+      materialLaw *mlaw = dgdom->getMaterialLaw();
+      for(groupOfElements::elementContainer::const_iterator it=dgdom->gib->begin(); it!=dgdom->gib->end();++it){
+        MElement *ele = *it;
+        MInterfaceElement *iele = dynamic_cast<MInterfaceElement*>(ele);
+        int npts_inter=dgdom->getInterfaceGaussIntegrationRule()->getIntPoints(ele,&GP);
+        ipstateElementContainer tp(npts_inter);
+        for(int i=0;i<npts_inter;i++){
+          mlaw->createIPState(tp[i],&state,ele,iele->getElem(0)->getNumVertices());
+        }
+        _mapall.insert(ipstatePairType(iele->getNum(),tp));
+      }
+    }
+    // bulk element
+    materialLaw *mlaw = dom->getMaterialLaw();
+    for (groupOfElements::elementContainer::const_iterator it = dom->g->begin(); it != dom->g->end(); ++it){
+      MElement *ele = *it;
+      int npts_bulk=dom->getBulkGaussIntegrationRule()->getIntPoints(ele,&GP);
+      ipstateElementContainer tp(npts_bulk);
+      for(int i=0;i<npts_bulk;i++){
+        mlaw->createIPState(tp[i],&state,ele,ele->getNumVertices());
+      }
+      _mapall.insert(ipstatePairType(ele->getNum(),tp));
+    }
+  }
+}
+AllIPState::~AllIPState()
+{
+  for(ipstateContainer::iterator it=_mapall.begin();it!=_mapall.end();++it){
+    ipstateElementContainer vips = (*it).second;
+    for(int i=0;i<vips.size();i++)
+	  delete vips[i];
+  }
+};
+
+AllIPState::ipstateElementContainer* AllIPState::getIPstate(const long int num)
+{
+  return &(_mapall.find(num)->second);
+}
+
+AllIPState::ipstateElementContainer* AllIPState::operator[](const long int num)
+{
+  return &(_mapall.find(num)->second);
+}
diff --git a/NonLinearSolver/internalPoints/ipstate.h b/NonLinearSolver/internalPoints/ipstate.h
index e69de29bb2..e6489ca1e1 100644
--- a/NonLinearSolver/internalPoints/ipstate.h
+++ b/NonLinearSolver/internalPoints/ipstate.h
@@ -0,0 +1,74 @@
+//
+// C++ Interface: terms
+//
+// Description: Class to store internal variables at gauss point
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef IPSTATE_H_
+#define IPSTATE_H_
+#include "GModel.h"
+#include "ipvariable.h"
+// enum to access to component of stress and deformation GLOBAL ??
+struct component{
+ enum enumcomp{xx,yy,zz,xy,xz,yz};
+};
+class partDomain;
+class dgPartDomain;
+class materialLaw;
+class IPStateBase{
+ public:
+  IPStateBase(){}
+  IPStateBase(const IPStateBase &source){}
+  virtual IPStateBase& operator=(const IPStateBase &source){return *this;}
+  enum whichState{initial, previous, current}; // keep previous OVERLOAD enum in daughter class ???
+  virtual IPVariable* getState(const whichState wst=IPStateBase::current) const=0;
+};
+
+class IP3State : public IPStateBase{
+ protected :
+  IPVariable *_initial;     // initial state t=0
+  IPVariable *_step1;    // previous step if _st = true and current step otherwise
+  IPVariable *_step2;     // current step if _st = true and previous step otherwise
+  const bool *_st; // pointer on a bool value to choice what vector is current and what vector is previous
+ public :
+  IP3State(bool *st) : IPStateBase(),_st(st), _initial(NULL), _step1(NULL), _step2(NULL){}
+  IP3State(const bool *st,IPVariable *init,
+           IPVariable *st1, IPVariable *st2): _st(st), _initial(init), _step1(st1), _step2(st2){}
+  ~IP3State();
+  IP3State(const IP3State &source);
+  virtual IP3State & operator = (const IPStateBase &source);
+  IPVariable* getState(const whichState wst=IPStateBase::current) const;
+};
+
+// Class to access to the IPState of all gauss point
+class AllIPState{
+ public:
+  typedef std::map<long int, std::vector<IPStateBase*> > ipstateContainer;
+  typedef std::pair<long int, std::vector<IPStateBase*> > ipstatePairType;
+  typedef std::vector<IPStateBase*> ipstateElementContainer;
+ protected:
+  ipstateContainer _mapall;
+  bool state; // flag to switch previous and current (change the pointer in place of copy all variables)
+ public :
+  AllIPState(GModel *pModel, std::vector<partDomain*> &vdom);
+  ~AllIPState();
+  ipstateElementContainer* getIPstate(const long int num);
+  ipstateElementContainer* operator[](const long int num);
+  void nextStep() {state ? state=false : state=true;} // change boolvalue
+  void copy(const IPStateBase::whichState ws1, const IPStateBase::whichState ws2){
+    for(ipstateContainer::iterator it=_mapall.begin(); it!=_mapall.end();++it){
+      std::vector<IPStateBase*> *vips = &((*it).second);
+      for(int i=0;i<vips->size();i++){
+        IPVariable *ipv1= (*vips)[i]->getState(ws1);
+        IPVariable *ipv2= (*vips)[i]->getState(ws2);
+        *ipv2 =*ipv1;
+      }
+    }
+  }
+};
+#endif // IPSTATE_H_
diff --git a/NonLinearSolver/internalPoints/ipvariable.h b/NonLinearSolver/internalPoints/ipvariable.h
new file mode 100644
index 0000000000..ef4a9a1636
--- /dev/null
+++ b/NonLinearSolver/internalPoints/ipvariable.h
@@ -0,0 +1,93 @@
+//
+// C++ Interface: ipvariable
+//
+// Description: Base class for ipvariable
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2011
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+// class with the variables of IP (stress, deformation and localBasis)
+
+#ifndef IPVARIABLE_H_
+#define IPVARIABLE_H_
+#include <stdlib.h>
+#include <stdio.h>
+
+class IPVariable
+{
+ public :
+  IPVariable(){}
+  virtual ~IPVariable(){}
+  // copie constructor
+  IPVariable(const IPVariable &source){};
+  virtual IPVariable &operator=(const IPVariable &source){return *this;};
+};
+
+class IPVariableMechanics : public IPVariable{
+ public:
+  IPVariableMechanics(): IPVariable(){}
+  IPVariableMechanics(const IPVariableMechanics &source) : IPVariable(source){};
+  virtual IPVariableMechanics &operator=(const IPVariable &source){
+    IPVariable::operator=(source);
+    return *this;
+  }
+  virtual double defoEnergy() const{return 0;}
+  virtual double stressComp(const int i) const{return 0;}
+};
+
+template<class Tbulk,class Tfrac> class IPVariable2ForFracture : virtual public IPVariableMechanics{
+ protected:
+  Tbulk *_ipvbulk;
+  Tfrac *_ipvfrac;
+  bool _broken; // To know which law to use
+ public:
+  IPVariable2ForFracture() : IPVariableMechanics(), _ipvbulk(NULL), _ipvfrac(NULL), _broken(false){}
+  IPVariable2ForFracture(const IPVariable2ForFracture &source) : IPVariableMechanics(source), _broken(source._broken)
+  {
+    (*_ipvbulk) = (*(dynamic_cast<const IPVariable*>(source._ipvbulk)));
+    if(source._ipvfrac != NULL)
+      if(_ipvfrac == NULL) _ipvfrac = new Tfrac(*(source._ipvfrac));
+      else  (*_ipvfrac) = (*(dynamic_cast<const IPVariable*>(source._ipvfrac)));
+  }
+  IPVariable2ForFracture& operator=(const IPVariable &source)
+  {
+    IPVariableMechanics::operator=(source);
+    const IPVariable2ForFracture *ipvf =dynamic_cast<const IPVariable2ForFracture *> (&source);
+    _broken = ipvf->_broken;
+    (*_ipvbulk) = (*(dynamic_cast<const IPVariableMechanics*>(ipvf->_ipvbulk)));
+    if(ipvf->_ipvfrac != NULL){
+      if(_ipvfrac == NULL) _ipvfrac = new Tfrac(*(ipvf->_ipvfrac));
+      else (*_ipvfrac) = (*(dynamic_cast<IPVariableMechanics*>(ipvf->_ipvfrac)));
+    }
+    else{
+      if(_ipvfrac != NULL) delete _ipvfrac;
+      _ipvfrac =NULL;
+    }
+    return *this;
+  }
+  ~IPVariable2ForFracture()
+  {
+    if(_ipvbulk != NULL){
+      delete _ipvbulk;
+    }
+    if(_ipvfrac != NULL){
+      delete _ipvfrac;
+    }
+  }
+  const bool broken() const{return _broken;}
+  bool isbroken(){return _broken;}
+  void broken(){_broken=true;}
+  void nobroken(){_broken=false;}
+  Tbulk* getIPvBulk(){return _ipvbulk;}
+  const Tbulk* getIPvBulk() const{return _ipvbulk;}
+  Tfrac* getIPvFrac(){return _ipvfrac;}
+  const Tfrac* getIPvFrac() const {return _ipvfrac;}
+  void setIPvBulk(IPVariable *ipv){ _ipvbulk = dynamic_cast<Tbulk*>(ipv);}
+  void setIPvFrac(IPVariable *ipv){ _ipvfrac = dynamic_cast<Tfrac*>(ipv);}
+};
+
+#endif //IPVARIABLE_H_
+
diff --git a/NonLinearSolver/materialLaw/CMakeLists.txt b/NonLinearSolver/materialLaw/CMakeLists.txt
new file mode 100644
index 0000000000..39d2c54aa8
--- /dev/null
+++ b/NonLinearSolver/materialLaw/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Gmsh - Copyright (C) 1997-2010 C. Geuzaine, J.-F. Remacle
+#
+# See the LICENSE.txt file for license information. Please report all
+# bugs and problems to <gmsh@geuz.org>.
+
+set(SRC
+  mlaw.cpp
+)
+
+file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) 
+append_gmsh_src(NonLinearSolver/materialLaw "${SRC};${HDR}")
diff --git a/NonLinearSolver/materialLaw/mlaw.cpp b/NonLinearSolver/materialLaw/mlaw.cpp
new file mode 100644
index 0000000000..10add0ba1e
--- /dev/null
+++ b/NonLinearSolver/materialLaw/mlaw.cpp
@@ -0,0 +1,26 @@
+//
+//
+//
+// Description: Define material law
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "mlaw.h"
+materialLaw::materialLaw(const int num, const bool init): _num(num), _initialized(init){}
+
+materialLaw::materialLaw(const materialLaw &source)
+{
+  _num = source._num;
+  _initialized = source._initialized;
+}
+
+materialLaw& materialLaw::operator=(const materialLaw &source)
+{
+  _num = source._num;
+  _initialized = source._initialized;
+  return *this;
+}
diff --git a/NonLinearSolver/materialLaw/mlaw.h b/NonLinearSolver/materialLaw/mlaw.h
new file mode 100644
index 0000000000..053eb71e84
--- /dev/null
+++ b/NonLinearSolver/materialLaw/mlaw.h
@@ -0,0 +1,94 @@
+//
+// C++ Interface: terms
+//
+// Description: Define material law
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef _MLAW_H_
+#define _MLAW_H_
+#ifndef SWIG
+#include "ipstate.h"
+#include "MElement.h"
+#endif
+class materialLaw{
+ public :
+  enum matname{linearElasticPlaneStress, linearElasticPlaneStressWithDamage, linearElasticOrthotropicPlaneStress, cohesiveLaw, fracture};
+ protected :
+  int _num; // number of law (must be unique !)
+  bool _initialized; // to initialize law
+#ifndef SWIG
+ public:
+  // constructor
+  materialLaw(const int num, const bool init=true);
+  ~materialLaw(){}
+  materialLaw(const materialLaw &source);
+  materialLaw& operator=(const materialLaw &source);
+  virtual int getNum() const{return _num;}
+  virtual matname getType() const=0;
+  virtual void createIPState(IPStateBase* &ips,const bool* state_=NULL,const MElement *ele=NULL, const int nbFF_=0) const=0;
+  virtual void initLaws(const std::map<int,materialLaw*> &maplaw)=0;
+  virtual const bool isInitialized() {return _initialized;}
+  // for explicit scheme it must return sqrt(E/rho) adapted to your case
+  virtual double soundSpeed() const=0;
+#endif
+};
+#ifndef SWIG
+class materialLaw2LawsInitializer{
+ public:
+  materialLaw2LawsInitializer(){}
+  ~materialLaw2LawsInitializer(){}
+  materialLaw2LawsInitializer(const materialLaw2LawsInitializer &source){}
+//  virtual materialLaw::matname getType() const{return materialLaw::fracture;}
+  virtual void initialBroken(IPStateBase *ips) const=0;
+};
+
+// If you used two laws your class has to be derived from this one
+template<class Tbulk, class Tfrac>class fractureBy2Laws : public materialLaw2LawsInitializer{
+ protected:
+  const int _nbulk;
+  const int _nfrac;
+  Tbulk *_mbulk;
+  Tfrac *_mfrac;
+ public:
+  fractureBy2Laws(const int num, const int nbulk, const int nfrac) : materialLaw2LawsInitializer(),
+                                                                       _nbulk(nbulk), _nfrac(nfrac),
+                                                                       _mbulk(NULL), _mfrac(NULL){}
+  fractureBy2Laws(const fractureBy2Laws &source) : materialLaw2LawsInitializer(source), _nbulk(source._nbulk),
+                                                    _nfrac(source._nfrac),
+                                                    _mbulk(source._mbulk), _mfrac(source._mfrac){}
+  ~fractureBy2Laws(){};
+  virtual const int bulkLawNumber() const{return _nbulk;}
+  virtual const int fractureLawNumber() const{return _nfrac;}
+  virtual const Tbulk* getBulkLaw() const{return _mbulk;}
+  virtual Tbulk* getBulkLaw(){return _mbulk;}
+  virtual const Tfrac* getFractureLaw() const{return _mfrac;}
+  virtual void initLaws(const std::map<int,materialLaw*> &maplaw)
+  {
+    bool findb=false;
+    bool findc=false;
+    for(std::map<int,materialLaw*>::const_iterator it = maplaw.begin(); it != maplaw.end(); ++it)
+    {
+      int num = it->first;
+      if(num == _nbulk){
+        findb=true;
+        it->second->initLaws(maplaw);
+        _mbulk = dynamic_cast<Tbulk*>(it->second);
+      }
+      if(num == _nfrac){
+        findc=true;
+        it->second->initLaws(maplaw);
+        _mfrac = dynamic_cast<Tfrac*>(it->second);
+      }
+    }
+    if(!findb) Msg::Error("The bulk law is not initialize for shellFractureByCohesiveLaw number %d",_nbulk);
+    if(!findc) Msg::Error("The cohesive law is not initialize for shellFractureByCohesiveLaw number %d",_nfrac);
+  }
+  virtual void initialBroken(IPStateBase *ips) const=0;
+};
+#endif // SWIG
+#endif //MLAW_H_
diff --git a/NonLinearSolver/nlTerms/CMakeLists.txt b/NonLinearSolver/nlTerms/CMakeLists.txt
new file mode 100644
index 0000000000..a325c8c2dc
--- /dev/null
+++ b/NonLinearSolver/nlTerms/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Gmsh - Copyright (C) 1997-2010 C. Geuzaine, J.-F. Remacle
+#
+# See the LICENSE.txt file for license information. Please report all
+# bugs and problems to <gmsh@geuz.org>.
+
+set(SRC
+  nlTerms.cpp
+)
+
+file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) 
+append_gmsh_src(NonLinearSolver/nlTerms "${SRC};${HDR}")
diff --git a/NonLinearSolver/nlTerms/nlTerms.cpp b/NonLinearSolver/nlTerms/nlTerms.cpp
new file mode 100644
index 0000000000..4969d3fd9e
--- /dev/null
+++ b/NonLinearSolver/nlTerms/nlTerms.cpp
@@ -0,0 +1,130 @@
+//
+// C++ Interface: terms
+//
+// Description: Basic term for non linear solver
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2011
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "nlTerms.h"
+#include "MInterfaceElement.h"
+#include "unknownField.h"
+#include "ipField.h"
+template<> void BilinearTermPerturbation<double>::get(MElement *ele,int npts,IntPt *GP,fullMatrix<double> &m) const
+{
+  MInterfaceElement *iele = dynamic_cast<MInterfaceElement*>(ele);
+  std::vector<Dof> R;
+  if(_nlterm->isData())
+    _nlterm->set(&disp);
+  if(iele == NULL){ // compute on element
+    int nbdof = space1.getNumKeys(ele);
+    m.resize(nbdof,nbdof,false); // set operation after
+    disp.resize(nbdof);
+    space1.getKeys(ele,R);
+    _ufield->get(R,disp);
+
+    // Size of force vector
+    fp.resize(nbdof);
+    fm.resize(nbdof);
+
+    for(int i=0;i<nbdof;i++){
+      // pertubation +
+      disp(i) += _eps;
+      _dom->computeIpv(_ipf->getAips(),ele,IPStateBase::current,_dom->getMaterialLaw(),disp);
+
+      _nlterm->get(ele,npts,GP,fp);
+      // perturbation -
+      disp(i) -=_twoeps;
+      _dom->computeIpv(_ipf->getAips(),ele,IPStateBase::current,_dom->getMaterialLaw(),disp);
+      _nlterm->get(ele,npts,GP,fm);
+      // restore dof value
+      disp(i) += _eps;
+      fp.axpy(fm,-1);
+      m.copyOneColumn(fp,i); // divide by 1/(2eps) at the end
+    }
+    _dom->computeIpv(_ipf->getAips(),ele,IPStateBase::current,_dom->getMaterialLaw(),disp);
+  }
+  else{
+    // get displacement of element
+    space1.getKeys(iele->getElem(0),R);
+    if(iele->getElem(0) != iele->getElem(1))
+      space2.getKeys(iele->getElem(1),R);
+    disp.resize(R.size());
+    _ufield->get(R,disp);
+    dgPartDomain *dgdom = dynamic_cast<dgPartDomain*>(_dom);
+    bool virt=false;
+    if(iele->getElem(0) == iele->getElem(1)) virt = true;
+    // store in dispm and dispp
+    int nbdof_m = space1.getNumKeys(iele->getElem(0));
+    int nbdof_p = 0;
+    dispm.resize(nbdof_m);
+    for(int i=0;i<nbdof_m;i++)
+      dispm(i) = disp(i);
+    if(!virt){
+      nbdof_p = space2.getNumKeys(iele->getElem(1));
+      dispp.resize(nbdof_p);
+      for(int i=0;i<nbdof_p;i++)
+        dispp(i) = disp(i+nbdof_m);
+      m.resize(nbdof_m+nbdof_p,nbdof_m+nbdof_p);
+    }
+    else
+      m.resize(nbdof_m,nbdof_m,false);
+    fp.resize(disp.size()); // use disp size to know the number of dof (here unknow if interafce or virtual interface)
+    fm.resize(disp.size());
+
+    // Perturbation on minus element
+    for(int i=0;i<nbdof_m;i++){
+      // dof perturbation +
+      disp(i)+=_eps;
+      dispm(i)+=_eps;
+      dgdom->computeIpv(_ipf->getAips(),iele,GP,IPStateBase::current,dgdom->getMinusDomain(),dgdom->getPlusDomain(),
+                        dgdom->getMaterialLawMinus(),dgdom->getMaterialLawPlus(),dispm,dispp,virt,false); // 0 for - elem and npts for + elem
+      _nlterm->get(ele,npts,GP,fp);
+      // dof perturbation -
+      disp(i)-=_twoeps;
+      dispm(i)-=_twoeps;
+      dgdom->computeIpv(_ipf->getAips(),iele,GP,IPStateBase::current,dgdom->getMinusDomain(),dgdom->getPlusDomain(),
+                        dgdom->getMaterialLawMinus(),dgdom->getMaterialLawPlus(),dispm,dispp,virt,false); // 0 for - elem and npts for + elem
+      _nlterm->get(ele,npts,GP,fm);
+      disp(i)+=_eps;
+      dispm(i)+=_eps;
+      fp.axpy(fm,-1);
+      m.copyOneColumn(fp,i); // divide by 1/(2eps) at the end
+    }
+    // restore ipv value
+    dgdom->computeIpv(_ipf->getAips(),iele,GP,IPStateBase::current,dgdom->getMinusDomain(), dgdom->getPlusDomain(),
+                      dgdom->getMaterialLawMinus(),dgdom->getMaterialLawPlus(),dispm,dispp,virt,false); // 0 for - elem and npts for + elem
+    if(!virt){ // Otherwise virtual interface element
+      // Perturbation on plus element
+      for(int i=0;i<nbdof_p;i++){
+        // dof perturbation +
+        disp(i+nbdof_m)+=_eps;
+        dispp(i)+=_eps;
+        dgdom->computeIpv(_ipf->getAips(),iele,GP,IPStateBase::current,dgdom->getMinusDomain(),dgdom->getPlusDomain(),
+                          dgdom->getMaterialLawMinus(),dgdom->getMaterialLawPlus(),dispm,dispp,virt,false); // 0 for - elem and npts for + elem
+        _nlterm->get(ele,npts,GP,fp);
+        // dof perturbation +
+        disp(i+nbdof_m)-=_twoeps;
+        dispp(i)-=_twoeps;
+        dgdom->computeIpv(_ipf->getAips(),iele,GP,IPStateBase::current,dgdom->getMinusDomain(),dgdom->getPlusDomain(),
+                          dgdom->getMaterialLawMinus(), dgdom->getMaterialLawPlus(),dispm,dispp,virt,false); // 0 for - elem and npts for + elem
+        _nlterm->get(ele,npts,GP,fm);
+        disp(i+nbdof_m)+=_eps;
+        dispp(i)+=_eps;
+        fp.axpy(fm,-1);
+        m.copyOneColumn(fp,i+nbdof_m); // divide by 1/(2eps) at the end
+      }
+      // restore ipv values
+      dgdom->computeIpv(_ipf->getAips(),iele,GP,IPStateBase::current,dgdom->getMinusDomain(),dgdom->getPlusDomain(),
+                        dgdom->getMaterialLawMinus(),dgdom->getMaterialLawPlus(),dispm,dispp,virt,false);
+    }
+  }
+  // divide all components by 1/2eps
+  m.scale(_onedivtwoeps);
+//  m.print("matrix by perturbation");
+
+}
+
diff --git a/NonLinearSolver/nlTerms/nlTerms.h b/NonLinearSolver/nlTerms/nlTerms.h
new file mode 100644
index 0000000000..37ff76384b
--- /dev/null
+++ b/NonLinearSolver/nlTerms/nlTerms.h
@@ -0,0 +1,109 @@
+//
+// C++ Interface: terms
+//
+// Description: Basic term for non linear solver
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2011
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef NONLINEARTERMS_H_
+#define NONLINEARTERMS_H_
+// lineartermBase and Bilinear term base are not be able
+// to take easily into account a perturbation of the unknown field
+// It leads to a very poorly efficient computation of matrix by perturbation
+// I change the basis class for this reason ALL assemble functions have to be "duplicated"
+#include "terms.h"
+class unknownField;
+class IPField;
+class partDomain;
+class  BiNonLinearTermBase : public BilinearTermBase
+{
+ public :
+  virtual ~BiNonLinearTermBase() {}
+  virtual void get(MElement *ele, int npts, IntPt *GP, fullMatrix<double> &m) = 0;
+  virtual void set(const fullVector<double> *datafield) = 0 ;
+  virtual const bool isData() const=0; // if true use this get function otherwise uses classical get
+};
+
+// Void term to avoid segmentation fault on domain for pure interface domain (Assemble on element)
+class BilinearTermVoid : public BilinearTermBase
+{
+ public:
+  virtual ~BilinearTermVoid(){}
+  virtual void get(MElement *ele, int npts, IntPt *GP, fullMatrix<double> &m){};
+  virtual void get(MElement *ele, int npts, IntPt *GP, std::vector<fullMatrix<double> > &mv) const{}
+  virtual BilinearTermBase* clone () const
+  {
+    return new BilinearTermVoid();
+  }
+};
+
+template<class T2=double> class  nonLinearTermBase : public LinearTermBase<T2>
+{
+ protected:
+  bool inverseSign; // has to be disappeared when solver is written with fext and fint
+ public:
+  nonLinearTermBase() : inverseSign(false){}
+  virtual ~nonLinearTermBase(){}
+//  virtual void get(MElement *ele, int npts, IntPt *GP, fullVector<T2> &v);
+  virtual void set(const fullVector<double> *datafield) = 0;
+  virtual const bool isData() const=0; // if true use this get function otherwise uses classical get
+  void invSign(){inverseSign ? inverseSign = false : inverseSign = true;} // has to dissappear
+};
+
+// Void term to avoid segmentation fault on domain for pure interface domain (Assemble on element)
+class LinearTermVoid : public LinearTermBase<double>
+{
+public:
+  virtual ~LinearTermVoid(){}
+  virtual void get(MElement *ele, int npts, IntPt *GP, fullVector<double> &v) const{};
+  virtual void get(MElement *ele, int npts, IntPt *GP, std::vector<fullVector<double> > &vv) const{}
+  virtual LinearTermBase<double>* clone () const
+  {
+    return new LinearTermVoid();
+  }
+};
+
+// BiNonLinear term by perturbation via nonLinearterm
+template <class T2=double> class BilinearTermPerturbation : public BilinearTermBase{
+ protected:
+  nonLinearTermBase<T2> *_nlterm;
+  FunctionSpaceBase &space1;
+  FunctionSpaceBase &space2;
+  unknownField *_ufield;
+  partDomain *_dom;
+  IPField *_ipf;
+  const double _eps;
+  const double _twoeps;
+  const double _onedivtwoeps;
+ private:
+  mutable fullVector<double> dispm;
+  mutable fullVector<double> dispp;
+  mutable fullVector<double> disp;
+  mutable fullVector<double> fm;
+  mutable fullVector<double> fp;
+ public:
+  BilinearTermPerturbation(LinearTermBase<T2> *lterm, FunctionSpaceBase &sp1, FunctionSpaceBase &sp2,
+                       unknownField *ufield, IPField *ipf, partDomain *dom,
+                       const double pert=1e-8) : space1(sp1), space2(sp2), _nlterm(dynamic_cast<nonLinearTermBase<T2>*>(lterm)),
+                                                   _ufield(ufield), _dom(dom),
+                                                   _ipf(ipf), _eps(pert), _twoeps(pert+pert),
+                                                   _onedivtwoeps(1./(pert+pert)){}
+  ~BilinearTermPerturbation(){}
+  virtual void get(MElement *ele,int npts,IntPt *GP,fullMatrix<T2> &m) const;
+  virtual void get(MElement *ele, int npts, IntPt *GP, std::vector<fullMatrix<double> > &mv) const
+  {
+    Msg::Error("Define me ?? get without integration BilinearTermPerturbation");
+  }
+  virtual BilinearTermBase* clone () const
+  {
+    return new BilinearTermPerturbation<T2>(_nlterm,space1,space2,_ufield,_ipf,_dom,_eps);
+  }
+};
+
+#endif // NONLINEARTERMS_H_
+
diff --git a/NonLinearSolver/nlsolver/CMakeLists.txt b/NonLinearSolver/nlsolver/CMakeLists.txt
new file mode 100644
index 0000000000..ef986dbe12
--- /dev/null
+++ b/NonLinearSolver/nlsolver/CMakeLists.txt
@@ -0,0 +1,21 @@
+# Gmsh - Copyright (C) 1997-2010 C. Geuzaine, J.-F. Remacle
+#
+# See the LICENSE.txt file for license information. Please report all
+# bugs and problems to <gmsh@geuz.org>.
+
+set(SRC
+  nonLinearMechSolver.cpp
+  unknownDynamicField.cpp
+  unknownField.cpp
+  unknownStaticField.cpp
+  # inline
+  Dof3IntType.h
+  explicitDofManager.h
+  explicitHulbertChung.h
+  nlsolAlgorithms.h
+  staticDofManager.h
+  timeFunction.h
+)
+
+file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) 
+append_gmsh_src(NonLinearSolver/nlsolver "${SRC};${HDR}")
diff --git a/NonLinearSolver/nlsolver/Dof3IntType.h b/NonLinearSolver/nlsolver/Dof3IntType.h
new file mode 100644
index 0000000000..0c7aba525e
--- /dev/null
+++ b/NonLinearSolver/nlsolver/Dof3IntType.h
@@ -0,0 +1,32 @@
+//
+// Description: Derivate class of Dof used for FullDg formulation where the type includes 3 informations (field,local vertex number, dof)
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef DGC0DOF_H_
+#define DGC0DOF_H_
+#include "dofManager.h"
+// Two functions are added to dof to define type with three int
+// Use by high level so impossible to let this in the projects ?
+class Dof3IntType : public Dof{
+  public :
+    Dof3IntType(long int ent, int type) : Dof(ent,type){}
+    ~Dof3IntType(){}
+    inline static int createTypeWithThreeInts(int comp,int field, int num=0){return 100000*field+100*num+comp;}
+    inline static void getThreeIntsFromType(int t, int &comp, int &field, int &num){
+      field = t/100000;
+      int i1=t%100000;
+      num = i1/100;
+      comp= i1%100;
+    }
+    // This function is used for Cg/Dg case (Allow to call the same function for the Two formulations)
+    inline static void getThreeIntsFromType(int t, int &comp, int &field){
+      field = t/100000;
+      comp =t%100000;
+    }
+};
+#endif // Dof3IntType
diff --git a/NonLinearSolver/nlsolver/explicitDofManager.h b/NonLinearSolver/nlsolver/explicitDofManager.h
new file mode 100644
index 0000000000..047cbb6e4f
--- /dev/null
+++ b/NonLinearSolver/nlsolver/explicitDofManager.h
@@ -0,0 +1,304 @@
+//
+// C++ Interface: dof manager for dynamic problems
+//
+// Description:  derive the dofManager for a dynamic problem (access to velocities and acceleration)
+//               and contains a mass matrix
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef EXPLICITDOFMANAGER_H_
+#define EXPLICITDOFMANAGER_H_
+
+#include "staticDofManager.h"
+#include "explicitHulbertChung.h"
+template<class T>
+class explicitHCDofManager : public staticDofManager<T>{
+ protected:
+  // map to have the initial conditions BC for positions, velocities and acceleration
+  //std::map<Dof, std::vector<dataVec> > initial; position in dofManager.h not used ??
+  std::map<Dof, typename dofManager<T>::dataVec> _initpositions;
+  std::map<Dof, typename dofManager<T>::dataVec> _initvelocities;
+  std::map<Dof, typename dofManager<T>::dataVec> _initaccelerations;
+
+  // for prescribed velocities and accelerations
+  std::map<Dof, typename dofManager<T>::dataVec> _fixedpositions; // needed to compute velocities (position of last time step)
+  std::map<Dof, typename dofManager<T>::dataVec> _fixedvelocities;
+  std::map<Dof, typename dofManager<T>::dataVec> _fixedaccelerations;
+  std::map<Dof, typename dofManager<T>::dataVec> _fixedmass; // needed to compute kinetic energy
+
+  // pointer to an explicit system (allow to avoid multi dynamic_cast)
+  explicitHulbertChung<T> *_currentExpl;
+
+ public:
+  explicitHCDofManager(linearSystem< typename dofManager<T>::dataMat> *l) : staticDofManager<T>(l){
+    _currentExpl = dynamic_cast<explicitHulbertChung<T>*>(l);
+  }
+  explicitHCDofManager(linearSystem< typename dofManager<T>::dataMat > *l1, linearSystem< typename dofManager<T>::dataMat > *l2){
+    _currentExpl = dynamic_cast<explicitHulbertChung<T> >(l1);
+  }
+
+  // Function assemble matrix is rewritten to allow to have 2 matrix stiffness and mass
+  virtual inline void assemble(std::vector<Dof> &R, const fullMatrix<typename dofManager<T>::dataMat> &m,
+                               const typename explicitHulbertChung<T>::whichMatrix wm=explicitHulbertChung<T>::stiff){
+    if (!this->_current->isAllocated()) this->_current->allocate(this->unknown.size());
+    std::vector<int> NR(R.size());
+    for (unsigned int i = 0; i < R.size(); i++)
+    {
+      std::map<Dof, int>::iterator itR = this->unknown.find(R[i]);
+      if (itR != this->unknown.end()) NR[i] = itR->second;
+      else NR[i] = -1;
+    }
+    if(wm == explicitHulbertChung<T>::stiff)
+    {
+      for (unsigned int i = 0; i < R.size(); i++)
+      {
+        if (NR[i] != -1)
+        {
+          for (unsigned int j = 0; j < R.size(); j++)
+          {
+            if (NR[j] != -1)
+            {
+              this->_current->addToMatrix(NR[i], NR[j], m(i, j));
+            }
+            else
+            {
+              typename std::map<Dof,  typename dofManager<T>::dataVec>::iterator itFixed = this->fixed.find(R[j]);
+              if (itFixed == this->fixed.end())
+                assembleLinConst(R[i],R[j],m(i,j));
+            }
+          }
+        }
+        else
+        {
+          for (unsigned int j = 0; j < R.size(); j++){
+          assembleLinConst(R[i],R[j],m(i,j));
+          }
+        }
+      }
+    }
+    else{ // mass matrix
+      for (unsigned int i = 0; i < R.size(); i++)
+        if (NR[i] != -1)
+          for (unsigned int j = 0; j < R.size(); j++)
+            //if (NR[j] != -1)
+              this->_currentExpl->addToMatrix(NR[i], NR[j], m(i, j),explicitHulbertChung<T>::mass);
+        else{ // store mass in _fixedmass
+          double linemass=0.;
+          // if already exist in _fixed mass retrieve value to add sum because diagonal matrix
+          typename std::map<Dof,typename dofManager<T>::dataVec>::iterator itm = this->_fixedmass.find(R[i]);
+          if(itm != this->_fixedmass.end())
+            linemass+=itm->second;
+          for(unsigned int j=0; j<R.size(); j++)
+            linemass+=m(i,j);
+          this->_fixedmass[R[i]] = linemass;
+        }
+    }
+  }
+
+  // Function to fix dof (fix velocities and acceleration Too. Must be modified to prescribed a velocities or an acceleration)
+  inline void fixDof(Dof key, const typename dofManager<T>::dataVec &value){
+     if(this->unknown.find(key) != this->unknown.end())
+      return;
+    this->fixed[key] = value;
+    this->_fixedvelocities[key]=0.;
+    this->_fixedaccelerations[key]=0.;
+    this->RHSfixed[key]=0.;
+  }
+
+  // function with get operation (WARNING All getDofValue are not redifined)
+  virtual inline void getDofValue(std::vector<Dof> &keys,std::vector<typename dofManager<T>::dataVec> &Vals,
+                                    const typename initialCondition::whichCondition wv= initialCondition::position)
+  {
+    int ndofs=keys.size();
+    size_t originalSize = Vals.size();
+    Vals.resize(originalSize+ndofs);
+    for (int i=0;i<ndofs;++i) getDofValue(keys[i], Vals[originalSize+i],wv);
+  }
+
+  virtual inline void getDofValue(Dof key,  typename dofManager<T>::dataVec &val,
+                                  initialCondition::whichCondition wv= initialCondition::position) const
+  {
+   switch(wv){
+    case initialCondition::position:
+     {
+       typename std::map<Dof, typename dofManager<T>::dataVec>::const_iterator it = this->fixed.find(key);
+       if (it != this->fixed.end()) {
+         val =  it->second;
+         return ;
+       }
+     }
+     {
+       std::map<Dof, int>::const_iterator it = this->unknown.find(key);
+       if (it != this->unknown.end()) {
+         _currentExpl->getFromSolution(it->second, val,wv);
+         return;
+       }
+     }
+     {
+       typename std::map<Dof, DofAffineConstraint< typename dofManager<T>::dataVec > >::const_iterator it = this->constraints.find(key);
+       if (it != this->constraints.end())
+       {
+          typename dofManager<T>::dataVec tmp(val);
+          val = it->second.shift;
+          for (unsigned i=0;i<(it->second).linear.size();i++)
+          {
+             std::map<Dof, int>::const_iterator itu = this->unknown.find(((it->second).linear[i]).first);
+             getDofValue(((it->second).linear[i]).first, tmp);
+             dofTraits<T>::gemm(val,((it->second).linear[i]).second, tmp, 1, 1);
+          }
+          return ;
+       }
+     }
+     break;
+     case initialCondition::velocity:
+     {
+       typename std::map<Dof, typename dofManager<T>::dataVec>::const_iterator it = this->_fixedvelocities.find(key);
+       if (it != this->_fixedvelocities.end()) {
+         val =  it->second;
+         return ;
+       }
+     }
+     {
+       std::map<Dof, int>::const_iterator it = this->unknown.find(key);
+       if (it != this->unknown.end()) {
+         _currentExpl->getFromSolution(it->second, val,wv);
+         return;
+       }
+     }
+     break;
+     case initialCondition::acceleration:
+     {
+       typename std::map<Dof, typename dofManager<T>::dataVec>::const_iterator it = this->_fixedaccelerations.find(key);
+       if (it != this->_fixedaccelerations.end()) {
+         val =  it->second;
+         return ;
+       }
+     }
+     {
+       std::map<Dof, int>::const_iterator it = this->unknown.find(key);
+       if (it != this->unknown.end()) {
+         _currentExpl->getFromSolution(it->second, val,wv);
+         return;
+       }
+     }
+     break;
+    }
+  }
+
+  // specific functions tfor initial conditions
+  // I don't use the initial vector because initial conditions are given directly
+  // to the solver
+  virtual inline void setInitialCondition(const Dof &R, const typename dofManager<T>::dataVec &value,
+                                          const typename initialCondition::whichCondition wc){
+
+    if (!this->_current->isAllocated()) this->_current->allocate(this->unknown.size());
+    // find the dof in map if not find -1
+    int NR=-1;
+    std::map<Dof, int>::iterator itR = this->unknown.find(R);
+    if (itR != this->unknown.end()){
+      NR = itR->second;
+      _currentExpl->setInitialCondition(NR, value,wc);
+    }
+    else{ // insert the initial conditions
+      typename std::map<Dof, typename dofManager<T>::dataVec>::iterator it;
+      if(wc == initialCondition::position){
+        this->_initpositions[R] = value;
+        // Find if the two others exist. If not set to zero
+        it = this->_initvelocities.find(R);
+        if (it == this->_initvelocities.end()) _initvelocities[R] = 0.;
+        it = this->_initaccelerations.find(R);
+        if (it == this->_initaccelerations.end()) _initaccelerations[R] = 0.;
+        // set initial position in fixedpos or 0
+         _fixedpositions[R] = value;
+    }
+      else if(wc == initialCondition::velocity){
+        _initvelocities[R] = value;
+        // Find if the two others exist. If not set to zero
+        it = this->_initpositions.find(R);
+        if (it == this->_initpositions.end()) this->_initpositions[R] = 0.;
+        it = this->_initaccelerations.find(R);
+        if (it == this->_initaccelerations.end()) _initaccelerations[R] = 0.;
+         _fixedpositions[R] = 0.;
+      }
+      else if(wc == initialCondition::acceleration){
+        _initaccelerations[R] = value;
+        // Find if the two others exist. If not set to zero
+        it = this->_initpositions.find(R);
+        if (it == this->_initpositions.end()) this->_initpositions[R] = 0.;
+        it = this->_initvelocities.find(R);
+        if (it == this->_initvelocities.end()) _initvelocities[R] = 0.;
+        _fixedpositions[R] = 0.;
+      }
+    }
+  }
+
+  // Function to update the fixed dof value
+  // must be rewritten to take into account a fixed velocity
+  virtual void updateFixedDof(const double timeStep){
+    // loop
+    for(typename std::map<Dof, typename dofManager<T>::dataVec>::iterator it=this->fixed.begin(); it!=this->fixed.end(); ++it){
+      // watch for an initial position
+      typename std::map<Dof, typename dofManager<T>::dataVec>::iterator itpos = _initpositions.find(it->first);
+      double initpos=0.;
+      typename dofManager<T>::dataVec lastpos=_fixedpositions[it->first];
+      typename dofManager<T>::dataVec lastvelo = _fixedvelocities[it->first];
+      if(itpos != _initpositions.end() ) initpos = itpos->second;
+      it->second = it->second + initpos;
+      _fixedpositions[it->first] = it->second;
+      _fixedvelocities.find(it->first)->second = (it->second - lastpos)/timeStep;
+      // update acceleration with plexus manual theory
+      //_fixedaccelerations.find(it->first)->second = (it->second/timeStep - _fixedvelocities.find(it->first)->second)/timeStep;
+      _fixedaccelerations.find(it->first)->second = 0.; //(_fixedvelocities.find(it->first)->second -lastvelo)/timeStep;
+    }
+  }
+  virtual void getVertexMass(std::vector<Dof> &R, std::vector<typename dofManager<T>::dataVec> &vmass){
+    if(this->_current->isAllocated()){
+      std::map<Dof, int>::const_iterator it;
+      double mass;
+      for(int i=0;i<R.size(); i++){
+        it = this->unknown.find(R[i]);
+        if(it != this->unknown.end()){
+          _currentExpl->getFromMatrix(it->second,it->second,mass);
+          vmass.push_back(mass);
+        }
+        else{  // find mass in _fixedmass
+          typename std::map<Dof,typename dofManager<T>::dataVec>::iterator itm = this->_fixedmass.find(R[i]);
+          if(itm != _fixedmass.end()) vmass.push_back(itm->second);
+          else vmass.push_back(0.);
+        }
+      }
+    }
+    else{
+      for(int i=0;i<R.size(); i++) vmass.push_back(0.);
+    }
+  }
+
+  // Function to get global kinetic energy. Used vector PETSC function so it's more quick
+  double getKineticEnergy() const{
+    double ener = _currentExpl->getKineticEnergy(); // energy of free dofs
+    // add energy of fixed dof
+    for(typename std::map<Dof,typename dofManager<T>::dataVec>::const_iterator it = _fixedmass.begin(); it!=_fixedmass.end(); ++it){
+      double mv = it->second;
+      double v = 0.;
+      typename std::map<Dof,typename dofManager<T>::dataVec>::const_iterator itv = _fixedvelocities.find(it->first);
+      if(itv != _fixedvelocities.end()) v = itv->second;
+      ener += 0.5*mv*v*v;
+    }
+    return ener;
+  }
+
+  // Print Right Hand Side (Use for debug)
+  void printRightHandSide() const{
+    Msg::Info("Right Hand Side");
+    for(std::map<Dof,int>::const_iterator it=this->unknown.begin(); it!=this->unknown.end(); ++it){
+      double force;
+      _currentExpl->getFromRightHandSide(it->second,force);
+      Msg::Info("Dof Ent: %d Dof Type %d value %e",it->first.getEntity(),it->first.getType(),force);
+    }
+  }
+};
+#endif // EXPLICITDOFMANAGER_H_
+
diff --git a/NonLinearSolver/nlsolver/explicitHulbertChung.h b/NonLinearSolver/nlsolver/explicitHulbertChung.h
new file mode 100644
index 0000000000..6028640131
--- /dev/null
+++ b/NonLinearSolver/nlsolver/explicitHulbertChung.h
@@ -0,0 +1,399 @@
+//
+// C++ explicit Newmark scheme
+//
+// Description: implementation of the explicit algorithms of alpha-generalized method
+//              This system is derived from linearSystem from compatibility reason (use of Assemble function and DofManager
+//              even if the system is not a no linear system FIX THIS ??
+//              for now works only this PETsc
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef EXPLICITHULBERTCHUNGSYSTEM_H_
+#define EXPLICITHULBERTCHUNGSYSTEM_H_
+
+#include "GmshConfig.h"
+#include "GmshMessage.h"
+#include "linearSystem.h"
+#include "partDomain.h"
+
+#if defined(HAVE_PETSC)
+#include <petsc.h>
+#include <petscksp.h>
+
+// 4 vectors are necessary per step and two step are kept
+// current and next. Creation of a class regrouping the four vector
+template<class scalar>
+class explicitStep{
+ private:
+  void _try(int ierr) const { CHKERRABORT(PETSC_COMM_WORLD, ierr); }
+ public : // Direct access by the system
+  Vec _b, _x, _xdot, _xddot;
+  explicitStep(){}
+  ~explicitStep(){}
+  void clear(){
+   _try(VecDestroy(_b));
+   _try(VecDestroy(_x));
+   _try(VecDestroy(_xdot));
+   _try(VecDestroy(_xddot));
+  }
+
+  void allocate(int nbRows){
+    _try(VecCreate(PETSC_COMM_WORLD, &_x));
+    _try(VecSetSizes(_x, nbRows, PETSC_DETERMINE));
+    _try(VecSetFromOptions(_x)); // Usefull ??
+    _try(VecDuplicate(_x, &_b));
+    _try(VecDuplicate(_x, &_xdot));
+    _try(VecDuplicate(_x, &_xddot));
+  }
+};
+
+template<class scalar>
+class explicitHulbertChung : public linearSystem<scalar>{
+ public :
+  enum state{current, next};
+//  enum whatValue{position, velocity, acceleration};
+  enum whichMatrix{stiff, mass};
+ protected:
+  int _blockSize; // for block Matrix (not used for now)
+  bool _isAllocated, _whichStep, _imassAllocated;
+  double _alpham, _beta,_gamma; // parameters of scheme
+  double _timeStep; // value of time step
+  int _nbRows; // To know the system size.
+  // values used by solve function
+  double _oneDivbyOneMinusAlpham,_minusAlphamDivbyOneMinusAlpham;
+  double _oneMinusgammaDeltat,_gammaDeltat,_Deltat2halfMinusbeta,_Deltat2beta;
+  explicitStep<scalar> *_currentStep, *_previousStep, *_step1, *_step2;
+  Vec _M; // mass matrix
+  Vec _invM; // inverse of mass matrix
+  Vec _v2; // square of velocitie (kinetic energy)
+
+  // function to invert mass matrix
+  void invertMassMatrix(){
+    _try(VecCopy(_M,_invM));
+    _try(VecReciprocal(_invM));
+    _imassAllocated=true;
+  }
+
+ private:
+  void _try(int ierr) const { CHKERRABORT(PETSC_COMM_WORLD, ierr); }
+
+ public:
+  explicitHulbertChung(double alpham=0., double beta=0.,
+                        double gamma=0.5) : _isAllocated(false), _whichStep(true), _blockSize(0),
+                                                                  _alpham(alpham), _beta(beta), _gamma(gamma),
+                                                                  _timeStep(0.), _nbRows(0), _imassAllocated(false){
+    _oneDivbyOneMinusAlpham = 1./(1.-_alpham);
+    _minusAlphamDivbyOneMinusAlpham = - _alpham * _oneDivbyOneMinusAlpham;
+    _oneMinusgammaDeltat = (1.-_gamma)*_timeStep;
+    _gammaDeltat = _gamma*_timeStep;
+    _Deltat2halfMinusbeta = _timeStep*_timeStep *(0.5-_beta);
+    _Deltat2beta = _timeStep * _timeStep * _beta;
+    _step1 = new explicitStep<scalar>();
+    _step2 = new explicitStep<scalar>();
+    _currentStep = _step1;
+    _previousStep = _step2;
+  }
+  ~explicitHulbertChung(){delete _step1; delete _step2;}
+
+  void nextStep(){
+    if(_whichStep){
+      _currentStep = _step2;
+      _previousStep = _step1;
+      _whichStep =false;
+    }
+    else{
+     _currentStep = _step1;
+     _previousStep = _step2;
+     _whichStep = true;
+    }
+  }
+
+  virtual void clear(){
+    if(_isAllocated){
+      _try(VecDestroy(_M));
+      _try(VecDestroy(_invM));
+      _try(VecDestroy(_v2));
+      _step1->clear();
+      _step2->clear();
+      _nbRows=0;
+    }
+    _isAllocated=false;
+    _imassAllocated=false;
+  }
+  // Or compute directly the time step here ??
+  virtual void setTimeStep(const double dt){
+    _timeStep = dt;
+    // update variables which depends on _timeStep
+    _oneMinusgammaDeltat = (1.-_gamma)*_timeStep;
+    _gammaDeltat = _gamma*_timeStep;
+    _Deltat2halfMinusbeta = _timeStep*_timeStep *(0.5-_beta);
+    _Deltat2beta = _timeStep * _timeStep * _beta;
+
+  }
+  virtual bool isAllocated() const { return _isAllocated; }
+  virtual void allocate(int nbRows){
+    clear();
+    _try(VecCreate(PETSC_COMM_WORLD, &_M));
+    _try(VecSetSizes(_M, nbRows, PETSC_DETERMINE));
+    _try(VecSetFromOptions(_M)); // Usefull ??
+    _try(VecDuplicate(_M, &_invM));
+    _try(VecDuplicate(_M, &_v2));
+    _step1->allocate(nbRows);
+    _step2->allocate(nbRows);
+    _isAllocated = true;
+    _nbRows=nbRows;
+  }
+  // get the value of diagonalized mass matrix col is not used
+  virtual void getFromMatrix(int row, int col, scalar &val) const{
+#if defined(PETSC_USE_COMPLEX)
+    PetscScalar *tmp;
+    _try(VecGetArray(_M, &tmp));
+    PetscScalar s = tmp[row];
+    _try(VecRestoreArray(_M, &tmp));
+    // FIXME specialize this routine
+    val = s.real();
+#else
+    VecGetValues(_M, 1, &row, &val);
+#endif
+  }
+  virtual void addToRightHandSide(int row, const scalar &val)
+  {
+    PetscInt i = row;
+    PetscScalar s = val;
+    _try(VecSetValues(_currentStep->_b, 1, &i, &s, ADD_VALUES));
+  }
+
+  virtual void getFromRightHandSide(int row, scalar &val) const
+  {
+#if defined(PETSC_USE_COMPLEX)
+    PetscScalar *tmp;
+    _try(VecGetArray(_currentStep->_b, &tmp));
+    PetscScalar s = tmp[row];
+    _try(VecRestoreArray(_currentStep->_b, &tmp));
+    // FIXME specialize this routine
+    val = s.real();
+#else
+    VecGetValues(_currentStep->_b, 1, &row, &val);
+#endif
+  }
+
+  virtual double normInfRightHandSide() const
+  {
+    PetscReal nor;
+    _try(VecNorm(_currentStep->_b, NORM_INFINITY, &nor));
+    return nor;
+  }
+
+  // Add to mass matrix (which is diagonalized)
+  virtual void addToMatrix(int row, int col, const scalar &val){
+    Msg::Error("No stiffness matrix for an explicit newmark scheme");
+  }
+  virtual void addToMatrix(int row, int col, const scalar &val, const whichMatrix wm)
+  {
+    if(wm == stiff){
+      this->addToMatrix(row,col,val);
+    }
+    else if( wm == mass){
+      PetscInt i = row;
+      PetscScalar s = val;
+      _try(VecSetValues(_M, 1, &i, &s, ADD_VALUES));
+    }
+    else{
+     Msg::Error("stiff and mass are the only possible matrix choice");
+    }
+
+  }
+
+  virtual void getFromSolution(int row, scalar &val) const
+  {
+#if defined(PETSC_USE_COMPLEX)
+    PetscScalar *tmp;
+    _try(VecGetArray(_currentStep->_x, &tmp));
+    PetscScalar s = tmp[row];
+    _try(VecRestoreArray(_currentStep->_x, &tmp));
+    val = s.real();
+#else
+    VecGetValues(_currentStep->_x, 1, &row, &val);
+#endif
+  }
+
+  virtual void getFromSolution(int row, scalar &val, const initialCondition::whichCondition wv) const
+  {
+    switch(wv){
+     case initialCondition::position:
+       this->getFromSolution(row,val);
+     break;
+     case initialCondition::velocity:
+#if defined(PETSC_USE_COMPLEX)
+      PetscScalar *tmp;
+      _try(VecGetArray(_currentStep->_xdot, &tmp));
+      PetscScalar s = tmp[row];
+      _try(VecRestoreArray(_currentStep->_xdot, &tmp));
+      val = s.real();
+#else
+      VecGetValues(_currentStep->_xdot, 1, &row, &val);
+#endif
+     break;
+     case initialCondition::acceleration:
+#if defined(PETSC_USE_COMPLEX)
+      PetscScalar *tmp;
+      _try(VecGetArray(_currentStep->_xddot, &tmp));
+      PetscScalar s = tmp[row];
+      _try(VecRestoreArray(_currentStep->_xddot, &tmp));
+      val = s.real();
+#else
+      VecGetValues(_currentStep->_xddot, 1, &row, &val);
+#endif
+     break;
+     default:
+       Msg::Error("Impossible to get value from solution. Only possible choices position, velocity, acceleration ");
+    }
+
+  }
+
+/*  virtual void getFromSolution(int row, scalar &val) const
+  {
+#if defined(PETSC_USE_COMPLEX)
+      PetscScalar *tmp;
+      _try(VecGetArray(_currentStep->_x, &tmp));
+      PetscScalar s = tmp[row];
+      _try(VecRestoreArray(_currentStep->_x, &tmp));
+      val = s.real();
+#else
+      VecGetValues(_currentStep->_x, 1, &row, &val);
+#endif
+  }*/
+
+
+  virtual void zeroMatrix(){
+    if (_isAllocated) {
+      _try(VecAssemblyBegin(_M));
+      _try(VecAssemblyEnd(_M));
+      _try(VecZeroEntries(_M));
+    }
+  }
+
+  virtual void zeroRightHandSide()
+  {
+    if (_isAllocated) {
+      _try(VecAssemblyBegin(_currentStep->_b));
+      _try(VecAssemblyEnd(_currentStep->_b));
+      _try(VecZeroEntries(_currentStep->_b));
+    }
+  }
+
+  int systemSolve(){
+#if defined(PETSC_USE_COMPLEX)
+  Msg::Error("explicit Newmark resolution is not implemented for complex number\n");
+#else
+    // check if the mass matrix is computed or not
+    if(!_imassAllocated) this->invertMassMatrix();
+
+// The following comment are kept to explain what is done component by component
+//    double x,xdot,xddot,fextMinusfint, imasse, xddotn, xdotn, xn;
+//    for(PetscInt i=0;i<_nbRows;i++){
+
+      // accelerations n+1
+//      VecGetValues(_previousStep->_b, 1, &i, &fextMinusfint);
+//      VecGetValues(_invM, 1, &i, &imasse);
+//      VecGetValues(_previousStep->_xddot, 1 , &i, &xddotn);
+//      xddot = _oneDivbyOneMinusAlpham*imasse*fextMinusfint + _minusAlphamDivbyOneMinusAlpham * xddotn;
+//      _try(VecSetValues(_currentStep->_xddot, 1, &i, &xddot, INSERT_VALUES));
+      _try(VecPointwiseMult(_currentStep->_xddot,_invM,_previousStep->_b));
+      _try(VecScale(_currentStep->_xddot,_oneDivbyOneMinusAlpham));
+      _try(VecAXPY(_currentStep->_xddot,_minusAlphamDivbyOneMinusAlpham,_previousStep->_xddot));
+
+      // velocities n+1
+//      VecGetValues(_previousStep->_xdot, 1 , &i, &xdotn);
+//      xdot = xdotn + _oneMinusgammaDeltat*xddotn + _gammaDeltat*xddot;
+//      _try(VecSetValues(_currentStep->_xdot, 1 , &i, &xdot, INSERT_VALUES));
+      _try(VecCopy(_previousStep->_xdot,_currentStep->_xdot));
+      // Regroups the two in one operation with VecMAXPY ??
+      _try(VecAXPY(_currentStep->_xdot,_oneMinusgammaDeltat,_previousStep->_xddot));
+      _try(VecAXPY(_currentStep->_xdot,_gammaDeltat,_currentStep->_xddot));
+
+      // positions n+1
+//      VecGetValues(_previousStep->_x, 1 , &i, &xn);
+//      x = xn + _timeStep * xdotn + _Deltat2halfMinusbeta * xddotn + _Deltat2beta * xddot;
+//      _try(VecSetValues(_currentStep->_x, 1 , &i, &x, INSERT_VALUES));
+      _try(VecCopy(_previousStep->_x,_currentStep->_x));
+      // Regroups the three in one operation with VecMAXPY ??
+      _try(VecAXPY(_currentStep->_x,_timeStep,_previousStep->_xdot));
+      _try(VecAXPY(_currentStep->_x,_Deltat2halfMinusbeta,_previousStep->_xddot));
+      _try(VecAXPY(_currentStep->_x,_Deltat2beta,_currentStep->_xddot));
+ //   }
+#endif
+    return 1;
+  }
+
+    // Specific functions (To put initial conditions)
+    // set on current step a next step operation is necessary after the prescribtion of initial value step0->step1
+    void setInitialCondition(int row, scalar val, const typename initialCondition::whichCondition wc=initialCondition::position){ //CANNOT PASS VAL BY REF WHY ??
+      PetscInt i = row;
+      switch(wc){
+       case initialCondition::position:
+        _try(VecSetValues(_currentStep->_x, 1, &i, &val, INSERT_VALUES));
+        break;
+       case initialCondition::velocity:
+        _try(VecSetValues(_currentStep->_xdot, 1, &i, &val, INSERT_VALUES));
+        break;
+       case initialCondition::acceleration:
+        _try(VecSetValues(_currentStep->_xddot, 1 , &i, &val, INSERT_VALUES));
+        break;
+       default:
+        Msg::Warning("Invalid initial conditions");
+      }
+    }
+
+    // Get mass of system
+    virtual double getSystemMass(){
+      double m,mele;
+      m=0.;
+      for(PetscInt i=0;i<_nbRows;i++){
+      VecGetValues(_M, 1, &i, &mele);
+        m+=mele;
+      }
+      return m;
+    }
+  // function to get the kinetic energy
+  double getKineticEnergy(){
+    if(isAllocated()){
+      PetscScalar ener;
+      _try(VecPointwiseMult(_v2,_currentStep->_xdot,_currentStep->_xdot));
+      _try(VecDot(_M,_v2,&ener));
+      return 0.5*ener;
+    }
+    else return 0.;
+  }
+};
+
+#else
+template <class scalar>
+class explicitHulbertChung : public linearSystem<scalar> {
+ public :
+  explicitHulbertChung()
+  {
+    Msg::Error("PETSc is not available in this version of Gmsh and so it is impossible to use explicit alpha generalized scheme");
+  }
+  virtual bool isAllocated() const { return false; }
+  virtual void allocate(int nbRows) {}
+  virtual void clear(){}
+  virtual void addToMatrix(int row, int col, const scalar &val) {}
+  virtual void getFromMatrix(int row, int col, scalar &val) const {}
+  virtual void addToRightHandSide(int row, const scalar &val) {}
+  virtual void getFromRightHandSide(int row, scalar &val) const { return 0.; }
+  virtual void getFromSolution(int row, scalar &val) const { return 0.; }
+  virtual void zeroMatrix() {}
+  virtual void zeroRightHandSide() {}
+  virtual int systemSolve() { return 0; }
+  virtual double normInfRightHandSide() const{return 0;}
+};
+
+#endif
+
+#endif // EXPLICITHULBERTCHUNGSYSTEM_H_
+
diff --git a/NonLinearSolver/nlsolver/nlsolAlgorithms.h b/NonLinearSolver/nlsolver/nlsolAlgorithms.h
new file mode 100644
index 0000000000..6f922cf652
--- /dev/null
+++ b/NonLinearSolver/nlsolver/nlsolAlgorithms.h
@@ -0,0 +1,228 @@
+//
+// C++ Interface: terms
+//
+// Description: non linear assembly fonctions
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2011
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef NONLINEARSOLVERALGORITHMS_H_
+#define NONLINEARSOLVERALGORITHMS_H_
+#include "dofManager.h"
+#include "quadratureRules.h"
+#include "MVertex.h"
+#include "MInterfaceElement.h"
+#include "functionSpace.h"
+#include "explicitHulbertChung.h"
+#include "solverAlgorithms.h"
+#include "explicitDofManager.h"
+
+// Assemble linear term. The field of term can be pass (compute matrix by perturbation and avoid a additional getKeys)
+// FIX THIS (use classical assemble) when field will be defined properly
+
+template<class Iterator, class Assembler> void Assemble(LinearTermBase<double> *term, FunctionSpaceBase &space,
+                                                        Iterator itbegin, Iterator itend,
+                                                        QuadratureBase &integrator,
+                                                        const unknownField *ufield,Assembler &assembler)
+{
+  fullVector<typename Assembler::dataMat> localVector(0);
+  std::vector<Dof> R;
+  nonLinearTermBase<double> *nlterm = dynamic_cast<nonLinearTermBase<double>*>(term);
+  if( (nlterm !=NULL) and (nlterm->isData())){
+    fullVector<double> disp;
+    nlterm->set(&disp);
+    for (Iterator it = itbegin; it != itend; ++it){
+      MElement *e = *it;
+      R.clear();
+      IntPt *GP;
+      int npts = integrator.getIntPoints(e, &GP);
+      space.getKeys(e, R);
+      disp.resize(R.size());
+      ufield->get(R,disp);
+      term->get(e, npts, GP, localVector); //localVector.print();
+      assembler.assemble(R, localVector);
+    }
+  }
+  else{
+    for (Iterator it = itbegin; it != itend; ++it){
+      MElement *e = *it;
+      R.clear();
+      IntPt *GP;
+      int npts = integrator.getIntPoints(e, &GP);
+      space.getKeys(e, R);
+      term->get(e, npts, GP, localVector); //localVector.print();
+      assembler.assemble(R, localVector);
+    }
+
+  }
+}
+
+// Function Assemble for mass matrix. An other function is needed because Two matrix in the system
+template<class Iterator,class Assembler> void AssembleMass(BilinearTermBase *term,FunctionSpaceBase &space,Iterator itbegin,
+                                                           Iterator itend,QuadratureBase &integrator,Assembler &assembler) // symmetric
+{
+  fullMatrix<typename Assembler::dataMat> localMatrix;
+  // remove the Dynamic Cast
+  explicitHCDofManager<typename Assembler::dataVec>* expAss = dynamic_cast<explicitHCDofManager<typename Assembler::dataVec>*>(&assembler);
+  std::vector<Dof> R;
+  for (Iterator it = itbegin;it!=itend; ++it)
+  {
+    MElement *e = *it;
+    R.clear();
+    IntPt *GP;
+    int npts=integrator.getIntPoints(e,&GP);
+    term->get(e,npts,GP,localMatrix);
+    space.getKeys(e,R);
+    expAss->assemble(R, localMatrix,explicitHulbertChung<double>::mass);
+  }
+}
+
+// Assemble mass for a rigid contact space. Only ddl of GC
+template<class Assembler>
+void AssembleMass(BilinearTermBase *term, rigidContactSpace *space,Assembler *assembler){
+  fullMatrix<typename Assembler::dataMat> localMatrix;
+  explicitHCDofManager<typename Assembler::dataVec>* expAss = dynamic_cast<explicitHCDofManager<typename Assembler::dataVec>*>(assembler);
+  std::vector<Dof> R;
+  space->getKeysOfGravityCenter(R);
+  MElement *ele;
+  IntPt *GP;
+  term->get(ele,0,GP,localMatrix);
+  expAss->assemble(R, localMatrix,explicitHulbertChung<double>::mass);
+}
+
+template<class Assembler> void FixNodalDofs(FunctionSpaceBase *space,MElement *e,Assembler &assembler,simpleFunction<typename Assembler::dataVec> &fct,FilterDof &filter,bool fullDg)
+{
+  std::vector<MVertex*> tabV;
+  int nv=e->getNumVertices();
+  std::vector<Dof> R;
+  space->getKeys(e,R);
+  tabV.reserve(nv);
+  for (int i=0;i<nv;++i) tabV.push_back(e->getVertex(i));
+
+  if(!fullDg){
+    for (std::vector<Dof>::iterator itd=R.begin();itd!=R.end();++itd)
+    {
+      Dof key=*itd;
+      if (filter(key))
+      {
+        for (int i=0;i<nv;++i)
+        {
+          if (tabV[i]->getNum()==key.getEntity())
+          {
+            //printf("Fix dof number %d comp %d\n",key.getEntity(),key.getType());
+            assembler.fixDof(key, fct(tabV[i]->x(),tabV[i]->y(),tabV[i]->z()));
+            break;
+          }
+        }
+      }
+    }
+  }
+  else{
+    for (std::vector<Dof>::iterator itd=R.begin();itd!=R.end();++itd)
+    {
+      Dof key=*itd;
+      if (filter(key))
+      {
+        for (int i=0;i<nv;++i)
+        {
+          assembler.fixDof(key, fct(tabV[i]->x(),tabV[i]->y(),tabV[i]->z()));
+          break;
+        }
+      }
+    }
+  }
+}
+
+template<class Iterator,class Assembler> void FixNodalDofs(FunctionSpaceBase *space,Iterator itbegin,Iterator itend,Assembler &assembler,
+                                                           simpleFunction<typename Assembler::dataVec> &fct,FilterDof &filter,bool fullDg)
+{
+  for (Iterator it=itbegin;it!=itend;++it)
+  {
+    FixNodalDofs(space,*it,assembler,fct,filter,fullDg);
+  }
+}
+
+template<class Assembler>
+void FixNodalDofs(rigidContactSpace *space,simpleFunction<typename Assembler::dataVec> &fct,FilterDof &filter, Assembler &assembler){
+  std::vector<Dof> R;
+  space->getKeysOfGravityCenter(R);
+  for(int i=0;i<R.size();i++){
+    if(filter(R[i]))
+      assembler.fixDof(R[i], fct(0.,0.,0.));
+  }
+
+}
+template<class Assembler> void SetInitialDofs(FunctionSpaceBase *space,MElement *e,Assembler &assembler,
+                                            const double &value,const initialCondition::whichCondition whichC,
+                                            FilterDof &filter,bool fullDg)
+{
+  std::vector<MVertex*> tabV;
+  int nv=e->getNumVertices();
+  std::vector<Dof> R;
+//  FunctionSpace<double> *dgspace = dynamic_cast<FunctionSpace<double>*>(space);
+  space->getKeys(e,R);
+  tabV.reserve(nv);
+  explicitHCDofManager<double> *dynass= dynamic_cast<explicitHCDofManager<double>*>(&assembler); // remove this dynamic_cast
+  for (int i=0;i<nv;++i) tabV.push_back(e->getVertex(i));
+
+  if(!fullDg){
+    for (std::vector<Dof>::iterator itd=R.begin();itd!=R.end();++itd)
+    {
+      Dof key=*itd;
+      if (filter(key))
+      {
+        for (int i=0;i<nv;++i)
+        {
+          if (tabV[i]->getNum()==key.getEntity())
+          {
+            //printf("Fix dof number %d comp %d\n",key.getEntity(),key.getType());
+            dynass->setInitialCondition(key,value,whichC);
+            break;
+          }
+        }
+      }
+    }
+  }
+  else{
+    for (std::vector<Dof>::iterator itd=R.begin();itd!=R.end();++itd)
+    {
+      Dof key=*itd;
+      if (filter(key))
+      {
+        for (int i=0;i<nv;++i)
+        {
+          dynass->setInitialCondition(key, value,whichC);
+          break;
+        }
+      }
+    }
+  }
+}
+
+template<class Iterator,class Assembler> void SetInitialDofs(FunctionSpaceBase *space,Iterator itbegin,Iterator itend,
+                                                           const double &value,const initialCondition::whichCondition whichC,
+                                                            Assembler &assembler, FilterDof &filter,bool fullDg)
+{
+  for (Iterator it=itbegin;it!=itend;++it)
+  {
+    SetInitialDofs(space,*it,assembler,value,whichC,filter,fullDg);
+  }
+}
+
+// Function Numbering Dof for rigid contact (Create Three Dofs for GC of rigid bodies)
+template<class Assembler>
+void NumberDofs(rigidContactSpace &space, Assembler &assembler){
+  // get Dofs of GC
+  std::vector<Dof> R;
+  space.getKeysOfGravityCenter(R);
+  // Put them into DofManager
+  int nbdofs=R.size();
+  for (int i=0;i<nbdofs;++i)
+    assembler.numberDof(R[i]);
+}
+
+#endif //NONLINEARSOLVERALGORITHMS_H_
+
diff --git a/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp b/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp
new file mode 100644
index 0000000000..3e7fdce439
--- /dev/null
+++ b/NonLinearSolver/nlsolver/nonLinearMechSolver.cpp
@@ -0,0 +1,1852 @@
+// Gmsh - Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to <gmsh@geuz.org>.
+
+#include <string.h>
+#include "GmshConfig.h"
+#include "nonLinearMechSolver.h"
+#include "linearSystemCSR.h"
+#include "linearSystemPETSc.h"
+#include "linearSystemGMM.h"
+#include "Numeric.h"
+#include "nlTerms.h"
+#include "solverAlgorithms.h"
+#include "quadratureRules.h"
+#include "MPoint.h"
+#include "ipstate.h"
+#include "ipField.h"
+#include "timeFunction.h"
+#include "GModel.h"
+#include "explicitHulbertChung.h"
+#include "nlsolAlgorithms.h"
+#include "nonLinearMechSolver.h"
+#include "explicitDofManager.h"
+#include "unknownDynamicField.h"
+#include "MTriangle.h"
+#include "MQuadrangle.h"
+#include "energyField.h"
+#include "nlsolAlgorithms.h"
+#include "solverAlgorithms.h"
+#include "quadratureRules.h"
+#include "MPoint.h"
+#include "timeFunction.h"
+#include "unknownStaticField.h"
+#include "staticDofManager.h"
+#include "contactTerms.h"
+
+
+#if defined(HAVE_POST)
+#include "PView.h"
+#include "PViewData.h"
+#endif
+
+// nonLinearMechSolver
+void nonLinearMechSolver::loadModel(const std::string meshFileName)
+{
+  pModel = new GModel();
+  pModel->readMSH(meshFileName.c_str());
+  _dim = pModel->getNumRegions() ? 3 : 2;
+}
+
+void nonLinearMechSolver::init(){
+
+  // Set the material law for each domain and the gauss integration rule
+  for(std::vector<partDomain*>::iterator it = domainVector.begin(); it!=domainVector.end(); ++it){
+    partDomain *dom = *it;
+    dom->setMaterialLaw(maplaw);
+  }
+
+  // create interfaceElement
+  this->createInterfaceElement();
+
+  for(std::vector<partDomain*>::iterator it = domainVector.begin(); it!=domainVector.end(); ++it){
+    partDomain *dom = *it;
+    dom->setGaussIntegrationRule();
+  }
+
+  // Split the BC between the different domain HAS TO BE AFTER DOMAIN INITIALIZATION
+  this->splitBoundaryConditions();
+
+  // initialisation of archiving force
+  this->initArchiveForce();
+
+  // find the domain associated to a physical slave number of a rigid contact interaction
+  // WARNING a contact interaction cannot be defined on two domains in the same time
+  // a physical group has to be define by domain
+  this->initContactInteraction();
+}
+
+void nonLinearMechSolver::initContactInteraction(){
+  // find a common element betwwen slave group of element and the group of element of partdomain
+  bool flagfind;
+  for(contactContainer::iterator it = _allContact.begin(); it!=_allContact.end(); ++it){
+    contactDomain *cdom = *it;
+    flagfind = false;
+    // get first element
+    MElement *elementcont = cdom->getFirstElement();
+    for(std::vector<partDomain*>::iterator itdom = domainVector.begin(); itdom!=domainVector.end(); ++itdom){
+      partDomain *dom = *itdom;
+      for(groupOfElements::elementContainer::iterator ite=dom->g->begin(); ite!=dom->g->end(); ++ite){
+        MElement *ele = *ite;
+        if(ele == elementcont){
+          flagfind =true;
+          cdom->setDomain(dom);
+//          spaceManager->addSpace(cdom);
+          break;
+        }
+      }
+      if(flagfind) break;
+    }
+  }
+
+  // now init the contact boundary conditions
+  for(std::vector<rigidContactBC>::iterator it=allContactBC.begin(); it!=allContactBC.end(); ++it){
+    rigidContactBC &diri = *it;
+    if(diri.onWhat == nonLinearBoundaryCondition::RIGIDCONTACT){
+      for(contactContainer::iterator itcdom = _allContact.begin(); itcdom!=_allContact.end(); ++itcdom){
+        contactDomain *cdom = *itcdom;
+        if(cdom->getPhys() == diri._tag){
+          rigidContactSpace *sp = dynamic_cast<rigidContactSpace*>(cdom->getSpace());
+          diri.setSpace(sp);
+          break;
+        }
+      }
+    }
+  }
+}
+
+void nonLinearMechSolver::splitBoundaryConditions(){
+
+  // loop on BC
+   // BC which are prescribed weakly (the interfaceElement has to be finded in vinter)
+   // to prescribed the BC
+
+   // Theta
+   for(std::vector<nonLinearNeumannBC>::iterator it=allTheta.begin(); it!=allTheta.end(); ++it){
+     nonLinearNeumannBC &neu = *it;
+     for(groupOfElements::elementContainer::iterator ite=neu.g->begin(); ite!=neu.g->end(); ++ite){
+       MVertex *vv = (*ite)->getVertex(2);
+       for(std::vector<partDomain*>::iterator itdom=domainVector.begin(); itdom!=domainVector.end(); ++itdom){
+         partDomain *dom = *itdom;
+         if(dom->IsInterfaceTerms()){ // change this (virtual interface has to be defined on domain)
+           // Ok because 2nd degree min BoundaryInterfaceElement is created only for this vertex
+           dgPartDomain *dgdom = dynamic_cast<dgPartDomain*>(dom);
+           groupOfElements *gvi = dgdom->giv;
+           for(groupOfElements::elementContainer::const_iterator it_inter = gvi->begin(); it_inter!=gvi->end();++it_inter){
+             MElement *minter = *it_inter;
+             //loop on component of map_edge
+             int numvertexminus1 = minter->getNumVertices()-1;
+             if((vv == minter->getVertex(2)) or (vv == minter->getVertex(numvertexminus1))){
+               dgdom->gib->insert(minter);
+               break;
+             }
+           }
+         }
+       }
+     }
+   }
+
+  //Dirichlet
+  for(int i=0;i<allDirichlet.size();i++){
+    // loop on element
+    // map
+    std::map<partDomain*,std::vector<MElement*> > mapfind;
+    for(groupOfElements::elementContainer::iterator it=allDirichlet[i].g->begin(); it!=allDirichlet[i].g->end();++it){
+      MElement *e = *it;
+      // Loop on all Domain to find on which domain the BC is applied
+      for(std::vector<partDomain*>::iterator itdom=domainVector.begin(); itdom!=domainVector.end(); ++itdom){
+        // if Dimensions are the same the element can be find with a comparison to element
+        partDomain *dom = *itdom;
+        // otherwise the vertex must be identified separately
+        MElement *etest = *(dom->g->begin());
+        if( (etest !=NULL) and (etest->getDim() == e->getDim())){
+          for(groupOfElements::elementContainer::iterator it2=dom->g->begin(); it2!=dom->g->end(); ++it2){
+            if(*it2 == e){ // The Element is contained in the domain
+              mapfind[dom].push_back(e);
+              break;
+            }
+          }
+        }
+        else{ // loop on Vertex identify the BC with first INTERIOR vertex of e degree 2 min OK ( border vertex are included in 2 elements)
+               // an element is included in one domain --> one vertex of Element is OK
+               // On interface the BC is put on the first met domain
+          MVertex *ver = e->getVertex(2);
+          for(groupOfElements::vertexContainer::iterator itv=dom->g->vbegin(); itv!=dom->g->vend(); ++itv){
+            if((*itv) == ver){
+              mapfind[(*itdom)].push_back(e);
+              break;
+            }
+          }
+        }
+      }
+    }
+    // now One BC is created on domain
+    for(std::map<partDomain*,std::vector<MElement*> >::iterator it=mapfind.begin(); it!=mapfind.end(); ++it){
+      if(it->second.size() !=0){
+        allDirichlet[i].g = new groupOfElements(it->second);
+        nonLinearDirichletBC *diri = new nonLinearDirichletBC(allDirichlet[i]);
+        it->first->addDirichletBC(diri);
+      }
+    }
+  }
+
+  // Idem for Neumann BC APPLY ON FIRST FOUNDED DOM
+  for(int i=0;i<allNeumann.size();i++){
+    // loop on element
+    // map
+    std::map<partDomain*,std::vector<MElement*> > mapfind;
+    std::map<partDomain*,MElement*> mapelemtype; // need for gauss quadrature rule TODO Regroup with mapfind in a structure but no time benefit
+    for(groupOfElements::elementContainer::iterator it=allNeumann[i].g->begin(); it!=allNeumann[i].g->end();++it){
+      MElement *e = *it;
+      // Loop on all Domain to find on which domain the BC is applied
+      bool flagfind = false;
+      for(std::vector<partDomain*>::iterator itdom=domainVector.begin(); itdom!=domainVector.end(); ++itdom){
+        // if Dimensions are the same the element can be find with a comparison to element
+        partDomain *dom = *itdom;
+        // otherwise the vertex must be identified separately
+        MElement *etest = *(dom->g->begin());
+        mapelemtype[dom] = etest;
+        if( (etest != NULL) and (etest->getDim() == e->getDim())){
+          for(groupOfElements::elementContainer::iterator it2=dom->g->begin(); it2!=dom->g->end(); ++it2){
+            if(*it2 == e){ // The Element is contained in the domain
+              mapfind[dom].push_back(e);
+              flagfind = true;
+              break;
+            }
+          }
+        }
+        else{ // loop on Vertex identify the BC with first vertex of e
+               // an element is included in one domain --> one vertex of Element is OK
+          MVertex *ver = e->getVertex(0);
+          for(groupOfElements::vertexContainer::iterator itv=dom->g->vbegin(); itv!=dom->g->vend(); ++itv){
+            if((*itv) == ver){
+              mapfind[(*itdom)].push_back(e);
+              flagfind = true;
+              break;
+            }
+          }
+        }
+      if(flagfind)
+        break;
+      }
+    }
+    // now One BC is created on domain
+    for(std::map<partDomain*,std::vector<MElement*> >::iterator it=mapfind.begin(); it!=mapfind.end(); ++it){
+      nonLinearNeumannBC *neu = new nonLinearNeumannBC(allNeumann[i]);
+      neu->g = new groupOfElements(it->second);
+      it->first->addNeumannBC(neu);
+    }
+  }
+
+  // Initial
+  for(int i=0;i<allinitial.size();i++){
+    // loop on element
+    // map
+    std::map<partDomain*,std::vector<MElement*> > mapfind;
+    for(groupOfElements::elementContainer::iterator it=allinitial[i].g->begin(); it!=allinitial[i].g->end();++it){
+      MElement *e = *it;
+      // Loop on all Domain to find on which domain the BC is applied
+      for(std::vector<partDomain*>::iterator itdom=domainVector.begin(); itdom!=domainVector.end(); ++itdom){
+        // if Dimensions are the same the element can be find with a comparison to element
+        partDomain *dom = *itdom;
+        // otherwise the vertex must be identified separately
+        MElement *etest = *(dom->g->begin());
+        if(etest->getDim() == e->getDim()){
+          for(groupOfElements::elementContainer::iterator it2=dom->g->begin(); it2!=dom->g->end(); ++it2){
+            if(*it2 == e){ // The Element is contained in the domain
+              mapfind[dom].push_back(e);
+              break;
+            }
+          }
+        }
+        else{ // loop on Vertex identify the BC with first vertex of e
+               // an element is included in one domain --> one vertex of Element is OK
+               // On interface the BC is put on the first met domain
+          MVertex *ver = e->getVertex(0);
+          for(groupOfElements::vertexContainer::iterator itv=dom->g->vbegin(); itv!=dom->g->vend(); ++itv){
+            if((*itv) == ver){
+              mapfind[(*itdom)].push_back(e);
+              break;
+            }
+          }
+        }
+      }
+    }
+    // now One Initial Condition is created on domain
+    for(std::map<partDomain*,std::vector<MElement*> >::iterator it=mapfind.begin(); it!=mapfind.end(); ++it){
+      initialCondition *initC = new initialCondition(allinitial[i]);
+      initC->g = new groupOfElements(it->second);
+      it->first->addInitialCondition(initC);
+    }
+  }
+  // At this stage the BC contains in allDirichlet and allNeumann are not used so
+  // they can be deleted
+  allNeumann.clear();
+  allDirichlet.clear();
+  allinitial.clear();
+};
+
+void nonLinearMechSolver::setTimeForBC(double time){
+  for (std::vector<partDomain*>::iterator itdom = domainVector.begin(); itdom!=domainVector.end(); ++itdom){
+    (*itdom)->setTimeBC(time);
+  }
+
+  // set time for rigid contact BC
+  for(std::vector<rigidContactBC>::iterator it = allContactBC.begin(); it!=allContactBC.end(); ++it){
+    (*it)._f.setTime(time);
+  }
+}
+
+void nonLinearMechSolver::fixNodalDofs(){
+  // Fixation (prescribed displacement)
+  for(std::vector<partDomain*>::iterator itdom=domainVector.begin(); itdom!=domainVector.end(); ++itdom){
+    partDomain *dom = *itdom;
+    for(partDomain::diriContainer::iterator it=dom->diriBegin(); it!=dom->diriEnd(); ++it){
+      nonLinearDirichletBC *diri = *it;
+      FixNodalDofs(diri->_space,diri->g->begin(),diri->g->end(),*pAssembler,diri->_f,*diri->_filter,dom->getFormulation());
+    }
+  }
+
+  // prescribed displacement of rigid bodies (CG)
+  for(std::vector<rigidContactBC>::iterator it=allContactBC.begin(); it!=allContactBC.end(); ++it){
+    rigidContactBC &rcbc = *it;
+    int physMaster = rcbc._tag; // for rigid BC tag == physMaster;
+    // Find the associated dom to create filter dof (Store in the BC to avoid search at each iteration !!)
+    FilterDof *filter;
+    bool ffind = false;
+    for(contactContainer::const_iterator it=_allContact.begin(); it!=_allContact.end();++it){
+      contactDomain *cdom = *it;
+      if(cdom->getPhys() == physMaster){
+        filter = cdom->getDomain()->createFilterDof(rcbc._comp);
+        ffind = true;
+        break;
+      }
+    }
+    if(ffind)
+      FixNodalDofs(rcbc.space,rcbc._f,*filter,*pAssembler);
+    else
+      Msg::Error("Impossible to fix dof for rigid contact BC %d",rcbc._tag);
+  }
+}
+
+void nonLinearMechSolver::numberDofs(linearSystem<double> *lsys){
+  // we number the dofs : when a dof is numbered, it cannot be numbered
+  // again with another number.
+  for(std::vector<partDomain*>::iterator itdom = domainVector.begin(); itdom!=domainVector.end(); ++itdom)
+  {
+    partDomain *dom = *itdom;
+    NumberDofs(*(dom->getFunctionSpace()), dom->g->begin(), dom->g->end(),*pAssembler);
+  }
+  // NumberDofs of Rigid Contact Entities (Dofs for GC)
+  for(contactContainer::iterator it = _allContact.begin(); it!=_allContact.end(); ++it){
+    contactDomain* cdom = *it;
+    if(cdom->isRigid()){
+      rigidContactSpace *rcspace = dynamic_cast<rigidContactSpace*>(cdom->getSpace());
+      NumberDofs(*rcspace,*pAssembler);
+    }
+  }
+  // total number of unkowns to allocate the system
+  double nunk = pAssembler->sizeOfR();
+  // allocate system
+  lsys->allocate(nunk);
+}
+
+void nonLinearMechSolver::addDomain(partDomain* dom){
+  // initialization of GroupOfElements
+  int dim = dom->getDim();
+  int phys = dom->getPhysical();
+  dom->g = new groupOfElements(dim,phys);
+  domainVector.push_back(dom);
+}
+
+void nonLinearMechSolver::addMaterialLaw(materialLaw* mlaw){
+  maplaw.insert(std::pair<int,materialLaw*>(mlaw->getNum(),mlaw));
+}
+
+materialLaw* nonLinearMechSolver::getMaterialLaw(const int num){
+  return (maplaw.find(num)->second);
+}
+
+void nonLinearMechSolver::thetaBC(const int numphys){
+  groupOfElements *goe = new groupOfElements(1,numphys);
+  this->insertTheta(numphys,goe);
+}
+
+void nonLinearMechSolver::setInitOrRestartFileName(const std::string fname){
+  initOrResartfname =fname;
+  _restart = true;
+}
+
+void nonLinearMechSolver::restart(unknownField *ufield){
+  if(!_restart) // no file to restart
+    return;
+  // create a map between elem number and adress
+  std::map<long int,std::pair<partDomain*,MElement*> > allelem;
+  for(std::vector<partDomain*>::iterator itdom = domainVector.begin(); itdom!=domainVector.end(); ++itdom){
+    partDomain *dom = *itdom;
+    for(groupOfElements::elementContainer::iterator ite = dom->g->begin(); ite!=dom->g->end(); ++ite){
+      MElement *ele = *ite;
+      std::pair<partDomain*,MElement*> pa(dom,ele);
+      allelem.insert(std::pair<long int,std::pair<partDomain*,MElement*> >(ele->getNum(),pa));
+    }
+  }
+
+  // read data in file
+  FILE *f = fopen(initOrResartfname.c_str(), "r");
+  char what[256];
+  while(!feof(f)){
+    fscanf(f, "%s", what);
+    if(!strcmp(what,"$ElementNodeData")){
+      int nstring;
+      fscanf(f,"%d",&nstring);
+      int i=0;
+      char what2[256];
+      while(i<nstring){
+        fscanf(f,"%s",&what2);
+        i++;
+      }
+      int nint, n;
+      fscanf(f,"%d",&nint);
+      i=0;
+      while(i<nint){
+        fscanf(f,"%d",&n);
+        i++;
+      }
+      fscanf(f,"%d",&nint);
+      i=0;
+      while(i<nint){
+        fscanf(f,"%d",&n);
+        i++;
+      }
+      int elemnum,elemtype,ndofs,nvertex,ncomp;
+      i = 0;
+      int n2 = n; // because n is modified by fscanf(f,"%ld %d",&elemnum,&elemtype); WHY ??
+      while(i<n2){
+        fscanf(f,"%d %d",&elemnum,&elemtype);
+        //MElement *ele = allelem[elemnum].second;
+        //partDomain *dom = allelem[elem]
+        std::map<long int,std::pair<partDomain*,MElement*> >::iterator it = allelem.find(elemnum);
+        MElement *ele = (it->second).second;
+        partDomain *dom = (it->second).first;
+        FunctionSpaceBase *space = dom->getFunctionSpace();
+        std::vector<Dof> R;
+        space->getKeys(ele,R);
+        ndofs = space->getNumKeys(ele);
+        nvertex = ele->getNumVertices();
+        ncomp = ndofs/nvertex;
+        int j=0;
+        std::vector<double> disp;
+        disp.resize(ndofs);
+        //double temp;
+        while(j<nvertex){
+          for(int k=0;k<ncomp;k++){
+            fscanf(f,"%lf",&disp[j+k*nvertex]);
+          }
+          j++;
+        }
+        // set displacement in displacement field
+        ufield->setInitial(R,disp);
+        i++;
+      }
+    }
+  }
+  fclose(f);
+  ufield->buildView(domainVector,0.0,0,"displacement",-1,false);
+}
+
+void nonLinearMechSolver::insertTheta(const int numphys, groupOfElements *goe){
+  nonLinearNeumannBC neu;
+  neu.g = goe;
+  neu.onWhat = nonLinearBoundaryCondition::UNDEF;
+  neu._tag = numphys;
+  neu._f = new simpleFunctionTimeWithConstant<double>(0.);
+  allTheta.push_back(neu);
+}
+
+void nonLinearMechSolver::physInitBroken(const int numphys){
+  initbrokeninter.push_back(numphys);
+}
+
+void nonLinearMechSolver::createInterfaceElement(){
+  // Compute and add interface element to the model
+  // Loop on mesh element and store each edge (which will be distributed between InterfaceElement, Boundary InterfaceElement and VirtualInterfaceElement)
+  // A tag including the vertex number is used to identified the edge common to two elements. In this case a interface element is created
+  // manage creation of interface between 2 domains
+  manageInterface maninter(&domainVector);
+  // loop on element
+  for(std::vector<partDomain*>::iterator itdom=domainVector.begin(); itdom !=domainVector.end(); ++itdom)
+  {
+    partDomain *dom = *itdom;
+    dom->createInterface(maninter);
+/*    dgPartDomain* dom = dynamic_cast<dgPartDomain*>(*itdom);
+    if(dom->IsInterfaceTerms()){
+      for (groupOfElements::elementContainer::const_iterator it = dom->g->begin(); it != dom->g->end(); ++it)
+      {
+        MElement *e=*it;
+        int nedge = e->getNumEdges();
+        for(int j=0;j<nedge;j++){
+          std::vector<MVertex*> vv;
+          e->getEdgeVertices(j,vv);
+          Iedge ie = Iedge(vv,e,dom->getPhysical());
+          unsigned long int key = ie.getkey();
+          const std::map<unsigned long int,Iedge>::iterator it_edge=map_edge.find(key);
+          if(it_edge == map_edge.end()) // The edge doesn't exist -->inserted into the map
+            map_edge.insert(std::pair<unsigned long int,Iedge>(key,ie));
+          else{ // create an interface element and remove the entry in map_edge
+            MInterfaceElement *interel =  new MInterfaceElement(vv, 0, 0, e, it_edge->second.getElement());
+            // Two cases
+            if(ie.getPhys() == it_edge->second.getPhys()) // Internal Interface
+              dom->gi->insert(interel);
+            else{ // Interface between 2 domains --> create a new domain if it doesn't exist
+              // find the domain of itedge
+              std::vector<partDomain*>::iterator itdom2;
+              for(itdom2 = domainVector.begin(); itdom2!=domainVector.end(); ++itdom2)
+                if((*itdom2)->getPhysical() == it_edge->second.getPhys()) break;
+              manageDom->add(interel,dom,*itdom2,maplaw);
+              this->addInterface(interel);
+            }
+            map_edge.erase(it_edge);
+          }
+        }
+      }
+    }*/
+  }
+
+  for(std::vector<partDomain*>::iterator itdom = domainVector.begin(); itdom!=domainVector.end(); ++itdom){
+    partDomain *dom = *itdom;
+    int phys = dom->getPhysical();
+    for(manageInterface::IelementContainer::iterator it=maninter.begin(); it!=maninter.end(); ++it){
+      IElement *ie = it->second;
+      if(ie->getPhys() == phys){
+        dgPartDomain *dgdom = dynamic_cast<dgPartDomain*>(dom);
+        MElement* interel = dom->createVirtualInterface(ie);
+        dgdom->giv->insert(interel);
+      }
+    }
+  }
+}
+
+void nonLinearMechSolver::createInterfaceElement_2()
+{
+  // The contructor of dgGroupCollection create automatically the GroupsOfElements
+/*  _groups = dgGroupCollection(this->pModel,this->_dim,1); // TODO ?? Add parameter to model to store order
+  _groups.buildGroupsOfInterfaces();
+  // Affichage temporaire pour vérification
+  int nn = _groups.getNbFaceGroups();
+  printf("Number of group of faces : %d\n",nn);
+  for(int i=0;i<nn;i++){
+    printf("Group of face number %d\n",i);
+    dgGroupOfFaces *inter = _groups.getFaceGroup(i);
+    int nnn = inter->getNbGroupOfConnections();
+    printf("Number of connection group %d \n",nnn);
+    for(int j=0;j<nnn;j++){
+      const dgGroupOfConnections connec = inter->getGroupOfConnections(j);
+      printf("Connection's group number %d\n",j);
+      int nnnn = connec.getNbClosures();
+      printf("Number of closures %d\n",nnnn);
+      for(int k=0;k<nnnn;k++){
+        printf("Closure number %d\n",k);
+        std::vector<int> vec = connec.getClosure(k);
+        for(int kk=0;kk<vec.size();kk++){
+          printf(" %d ",vec[kk]);
+        }
+        printf("\n");
+      }
+    }
+  }*/
+}
+
+void nonLinearMechSolver::initTerms(unknownField *ufield, IPField *ipf){
+  for(std::vector<partDomain*>::iterator itdom = domainVector.begin(); itdom!=domainVector.end(); ++itdom){
+    partDomain *dom = *itdom;
+    dom->initializeTerms(ufield,ipf);
+  }
+
+  // contact domain
+  for(contactContainer::iterator it = _allContact.begin(); it!=_allContact.end(); ++it){
+    contactDomain *cdom = *it;
+    if(cdom->getContactType() == contactDomain::rigidCylinder){
+      rigidCylinderContact *rcc = dynamic_cast<rigidCylinderContact*>(cdom);
+      rcc->initializeTerms(ufield);
+    }
+    else Msg::Error("Terms are not defined for contact type %d",cdom->getContactType());
+  }
+
+}
+
+void nonLinearMechSolver::solveStaticLinar()
+{
+// init data
+this->init();
+linearSystem<double> *lsys;
+if(nonLinearMechSolver::whatSolver == Taucs){
+    #if defined(HAVE_TAUCS)
+      lsys = new linearSystemCSRTaucs<double>;
+      printf("Taucs is chosen to solve\n");
+    #else
+      lsys = new linearSystemGmm<double>;
+      lsys = dynamic_cast<linearSystemGmm<double>*>(lsys);
+      dynamic_cast<linearSystemGmm<double>*>(lsys)->setNoisy(2);
+      printf("Taucs is not installed\n Gmm is chosen to solve\n");
+    #endif
+}
+else if(nonLinearMechSolver::whatSolver == Petsc){
+    #if defined(HAVE_PETSC)
+      lsys = new linearSystemPETSc<double>;
+      printf("PETSc is chosen to solve\n");
+    #else
+      lsys = new linearSystemGmm<double>;
+      lsys = dynamic_cast<linearSystemGmm<double>*>(lsys);
+      dynamic_cast<linearSystemGmm<double>*>(lsys)->setNoisy(2);
+      printf("PETSc is not installed\n Gmm is chosen to solve\n");
+    #endif
+}
+else{
+  lsys = new linearSystemGmm<double>;
+  dynamic_cast<linearSystemGmm<double>*>(lsys)->setNoisy(2);
+  printf("Gmm is chosen to solve\n");
+}
+
+  if (pAssembler) delete pAssembler;
+  pAssembler = new dofManager<double>(lsys);
+
+  std::cout <<  "Dirichlet BC"<< std::endl;
+  // we first do all fixations. the behavior of the dofManager is to
+  // give priority to fixations : when a dof is fixed, it cannot be
+  // numbered afterwards
+  // Fix dof to allow the numbering of Dof by dofManager
+  this->fixNodalDofs();
+  this->numberDofs(lsys);
+
+  // displacement field
+  unknownField *ufield = new unknownStaticField(pAssembler,domainVector,&_allContact,3,anoded,varcd);
+  this->restart(ufield); // CHANGE THIS
+  // Store stress and deformation at each gauss point
+  // IPState "declaration" reserve place for data
+  IPField ipf(&domainVector,pAssembler, pModel, ufield, vaip); // Todo fix this
+  ipf.compute1state(IPStateBase::initial);
+  ipf.copy(IPStateBase::initial,IPStateBase::current); // initialization of Bvector and LocalBasis
+  this->initTerms(ufield,&ipf);
+
+  // Now we start the assembly process
+  // First build the force vector
+  std::cout <<  "Neumann BC"<< std::endl;
+  this->computeExternalForces(&ipf,ufield);
+  this->computeStiffMatrix(ufield);
+  printf("-- done assembling!\n");
+  lsys->systemSolve();
+  printf("-- done solving!\n");
+
+  // compute stress after solve
+  ufield->update();
+  ipf.compute1state(IPStateBase::current);
+  // save solution (for visualisation)
+  ipf.buildView(domainVector,0.,1,"VonMises",-1,false);
+  ufield->buildView(domainVector,0.,1,"displacement",-1,false);
+  ufield->archiving(1.);
+  ipf.archive(1.);
+  delete ufield;
+}
+
+void nonLinearMechSolver::computeExternalForces(IPField *ipf, const unknownField *ufield){
+  for(std::vector<partDomain*>::iterator itdom=domainVector.begin(); itdom!=domainVector.end();++itdom){
+    partDomain *dom = *itdom;
+    for(partDomain::neuContainer::iterator it=dom->neuBegin(); it!=dom->neuEnd();++it){
+      nonLinearNeumannBC *neu = *it;
+      Assemble(neu->_term,*(neu->_space),neu->g->begin(),neu->g->end(),*(neu->integ),ufield,*pAssembler);
+    }
+  }
+}
+
+void nonLinearMechSolver::snlData(const int ns, const double et, const double reltol){
+  if(whatScheme==StaticNonLinear){
+    numstep=ns;endtime=et;_tol=reltol;
+  }
+  else{
+    Msg::Error("Impossible to set data for Static Non Linear scheme because another is chosen to solve the problem");
+  }
+}
+
+void nonLinearMechSolver::explicitData(const double ftime, const double gams, const double beta, const double gamma, const double alpham){
+  endtime = ftime;
+  _beta=beta;
+  _gamma=gamma;
+  _alpham = alpham;
+  // depends on numerical damping
+  double omegas;
+  _rhoinfty = (alpham+1.)/(2.-alpham);
+  omegas = sqrt((12.*(1.+_rhoinfty)*(1.+_rhoinfty)*(1.+_rhoinfty)*(2.-_rhoinfty))/(10.+15.*_rhoinfty-_rhoinfty*_rhoinfty+_rhoinfty*_rhoinfty*_rhoinfty-_rhoinfty*_rhoinfty*_rhoinfty*_rhoinfty));
+    _gammas = gams*omegas;
+}
+
+void nonLinearMechSolver::explicitSpectralRadius(const double ftime,const double gams, const double rho){
+  endtime = ftime;
+  _rhoinfty=rho;
+  _beta = (5.-3.*_rhoinfty)/((1.+_rhoinfty)*(1.+_rhoinfty)*(2.-_rhoinfty));
+  _alpham = (2.*_rhoinfty-1.)/(1.+_rhoinfty);
+  _gamma = 1.5-_alpham;
+  double omegas = sqrt((12.*(1.+_rhoinfty)*(1.+_rhoinfty)*(1.+_rhoinfty)*(2.-_rhoinfty))/(10.+15.*_rhoinfty-_rhoinfty*_rhoinfty+_rhoinfty*_rhoinfty*_rhoinfty-_rhoinfty*_rhoinfty*_rhoinfty*_rhoinfty));
+    _gammas = gams*omegas;
+}
+
+void nonLinearMechSolver::explicitTimeStepEvaluation(const int nst){
+  numstep = nst;
+}
+
+void nonLinearMechSolver::solve(){
+  switch(whatScheme){
+    case StaticLinear :
+      this->solveStaticLinar();
+      break;
+    case StaticNonLinear :
+      this->solveSNL();
+      break;
+    case Explicit:
+      this->solveExplicit();
+  }
+}
+
+void nonLinearMechSolver::displacementBC(std::string onwhat, const int numphys, const int comp, const double value){
+  nonLinearDirichletBC diri;
+  const std::string node("Node");
+  const std::string edge("Edge");
+  const std::string face("Face");
+  if(onwhat==node){
+    diri.g = new groupOfElements (0, numphys);
+    diri.onWhat=nonLinearBoundaryCondition::ON_VERTEX;
+  }
+  else if(onwhat==edge){
+    diri.g = new groupOfElements (1, numphys);
+    diri.onWhat=nonLinearBoundaryCondition::ON_EDGE;
+  }
+  else if(onwhat==face){
+    diri.g = new groupOfElements (2, numphys);
+    diri.onWhat=nonLinearBoundaryCondition::ON_FACE;
+  }
+  else Msg::Error("Impossible to prescribe a displacement on a %s\n",onwhat.c_str());
+  diri._f= simpleFunctionTime<double>(value);
+  diri._comp=comp;
+  diri._tag=numphys;
+  allDirichlet.push_back(diri);
+}
+
+void nonLinearMechSolver::displacementRigidContactBC(const int numphys, const int comp_, const double value){
+  rigidContactBC diri(numphys);
+  diri.onWhat = nonLinearBoundaryCondition::RIGIDCONTACT;
+  diri._comp = comp_;
+  diri._f = simpleFunctionTime<double>(value);
+  allContactBC.push_back(diri);
+}
+
+void nonLinearMechSolver::initialBC(std::string onwhat, std::string whichC, const int numphys,
+                                          const int comp, const double value){
+
+  const std::string node("Node");
+  const std::string edge("Edge");
+  const std::string face("Face");
+  const std::string position("Position");
+  const std::string velocity("Velocity");
+  const std::string acceleration("Acceleration");
+
+  nonLinearBoundaryCondition::location ow;
+  groupOfElements *gr;
+  if(onwhat == node){
+    ow = nonLinearBoundaryCondition::ON_VERTEX;
+    gr = new groupOfElements(0,numphys);
+  }
+  else if(onwhat == edge){
+    ow = nonLinearBoundaryCondition::ON_EDGE;
+    gr = new groupOfElements(1,numphys);
+  }
+  else if(onwhat == face){
+    ow = nonLinearBoundaryCondition::ON_FACE;
+    gr = new groupOfElements(2,numphys);
+  }
+  else{
+    ow = nonLinearBoundaryCondition::UNDEF;
+    gr = new groupOfElements(2,numphys);
+  }
+
+  initialCondition::whichCondition wc;
+  if(whichC == position)
+    wc = initialCondition::position;
+  else if(whichC == velocity)
+    wc = initialCondition::velocity;
+  else if(whichC == acceleration)
+    wc = initialCondition::acceleration;
+  else{
+    Msg::Warning("Impossible to prescribed an initial condition %d",numphys);
+    //return;
+  }
+  initialCondition initc(value,comp,wc);
+  initc.onWhat = ow;
+  initc.g = gr;
+  initc._tag = numphys;
+  allinitial.push_back(initc);
+}
+
+void nonLinearMechSolver::independentDisplacementBC(std::string onwhat, const int numphys, const int comp, const double value){
+  nonLinearDirichletBC diri;
+  const std::string node("Node");
+  const std::string edge("Edge");
+  const std::string face("Face");
+  if(onwhat==node){
+    diri.g = new groupOfElements (0, numphys);
+    diri.onWhat=nonLinearBoundaryCondition::ON_VERTEX;
+  }
+  else if(onwhat==edge){
+    diri.g = new groupOfElements (1, numphys);
+    diri.onWhat=nonLinearBoundaryCondition::ON_EDGE;
+  }
+  else if(onwhat==face){
+    diri.g = new groupOfElements (2, numphys);
+    diri.onWhat=nonLinearBoundaryCondition::ON_FACE;
+  }
+  else Msg::Error("Impossible to prescribe a displacement on a %s\n",onwhat.c_str());
+  diri._f= simpleFunctionTime<double>(value,false);
+  diri._comp=comp;
+  diri._tag=numphys;
+  allDirichlet.push_back(diri);
+}
+
+void nonLinearMechSolver::forceBC(std::string onwhat, const int numphys, const int comp, const double val){
+  nonLinearNeumannBC neu;
+  const std::string node("Node");
+  const std::string edge("Edge");
+  const std::string face("Face");
+  const std::string volume("Volume");
+  if(onwhat==node){
+    neu.g = new groupOfElements (0, numphys);
+    neu.onWhat=nonLinearBoundaryCondition::ON_VERTEX;
+  }
+  else if(onwhat==edge){
+    neu.g = new groupOfElements (1, numphys);
+    neu.onWhat=nonLinearBoundaryCondition::ON_EDGE;
+  }
+  else if(onwhat==face){
+    neu.g = new groupOfElements (2, numphys);
+    neu.onWhat=nonLinearBoundaryCondition::ON_FACE;
+  }
+  else if(onwhat==volume){
+    neu.g = new groupOfElements (3, numphys);
+    neu.onWhat=nonLinearBoundaryCondition::ON_VOLUME;
+  }
+  else  Msg::Error("Impossible to prescribe a force on a %s\n",onwhat.c_str());
+  neu._f= new simpleFunctionTimeWithConstant<double>(val);
+  neu._tag=numphys;
+  neu._comp=comp;
+  allNeumann.push_back(neu);
+}
+
+void nonLinearMechSolver::independentForceBC(std::string onwhat, const int numphys, const int comp, const double val){
+  nonLinearNeumannBC neu;
+  const std::string node("Node");
+  const std::string edge("Edge");
+  const std::string face("Face");
+  const std::string volume("Volume");
+  if(onwhat==node){
+    neu.g = new groupOfElements (0, numphys);
+    neu.onWhat=nonLinearBoundaryCondition::ON_VERTEX;
+  }
+  else if(onwhat==edge){
+    neu.g = new groupOfElements (1, numphys);
+    neu.onWhat=nonLinearBoundaryCondition::ON_EDGE;
+  }
+  else if(onwhat==face){
+    neu.g = new groupOfElements (2, numphys);
+    neu.onWhat=nonLinearBoundaryCondition::ON_FACE;
+  }
+  else if(onwhat==volume){
+    neu.g = new groupOfElements (3, numphys);
+    neu.onWhat=nonLinearBoundaryCondition::ON_VOLUME;
+  }
+  else  Msg::Error("Impossible to prescribe a force on a %s\n",onwhat.c_str());
+  neu._f= new simpleFunctionTimeWithConstant<double>(val,false);
+  neu._tag=numphys;
+  neu._comp = comp;
+  allNeumann.push_back(neu);
+}
+
+void nonLinearMechSolver::pressureOnPhysicalGroupBC(const int numphys, const double press, const double p0){
+  nonLinearNeumannBC neu;
+  neu.g = new groupOfElements(2,numphys); // Always group of face ??
+  neu.onWhat = nonLinearBoundaryCondition::PRESSURE;
+  neu._f = new simpleFunctionTimeWithConstant<double>(press,true,1.,p0); // Use a SVector3 because it was defined like this in
+  neu._tag=numphys;
+  allNeumann.push_back(neu);
+}
+
+void nonLinearMechSolver::blastPressureBC(const int numphys,const double p0,const double p1, const double plexp,
+                                       const double t0, const double t1){
+  powerDecreasingFunctionTime *pdl = new powerDecreasingFunctionTime(p0,p1,plexp,t0,t1,this->endtime);
+  nonLinearNeumannBC neu(numphys,5,pdl);
+  allNeumann.push_back(neu);
+}
+
+void nonLinearMechSolver::archivingForceOnPhysicalGroup(const std::string onwhat, const int numphys, const int comp){
+  // get the node of the edge
+  std::string node("Node");
+  std::string edge("Edge");
+  std::string face("Face");
+  std::string volu("Volume");
+  int dim=0;
+  if(onwhat == node )
+    dim = 0;
+  else if(onwhat == edge)
+    dim = 1;
+  else if(onwhat == face)
+    dim = 2;
+  else if(onwhat == volu)
+    dim = 3;
+
+  vaf.push_back(archiveForce(numphys,dim,comp));
+
+  // remove old file (linux only ??)
+  std::ostringstream oss;
+  oss << numphys;
+  std::string s = oss.str();
+  oss.str("");
+  oss << comp;
+  std::string s2 = oss.str();
+  std::string rfname = "rm force"+s+"comp"+s2+".csv";
+  system(rfname.c_str());
+}
+
+void nonLinearMechSolver::initArchiveForce(){
+  for(std::vector<archiveForce>::iterator itf=vaf.begin(); itf!=vaf.end(); ++itf){
+    archiveForce &af = *itf;
+    std::vector<MVertex*> vv;
+    pModel->getMeshVerticesForPhysicalGroup(af.dim,af.numphys,vv);
+    std::vector<Dof> vdof;// all dof include in the edge
+
+    // shell element
+    // loop on domain (to find the domain where the force is applied)
+    for(std::vector<partDomain*>::iterator itdom=domainVector.begin(); itdom!=domainVector.end(); ++itdom){
+      partDomain *dom = *itdom;
+      FunctionSpaceBase *sp = dom->getFunctionSpace();
+      std::vector<Dof> R;
+      FilterDof* filter = dom->createFilterDof(af.comp);
+      if(!(dom->getFormulation())){  // Cg/Dg
+        for(groupOfElements::vertexContainer::iterator itv=dom->g->vbegin(); itv!=dom->g->vend(); ++itv){
+          MVertex *ver = *itv;
+          for(std::vector<MVertex*>::iterator it=vv.begin(); it!=vv.end(); ++it){
+            MVertex *vver = *it;
+            if(ver == vver){
+              MPoint ele = MPoint(ver,-1); // We don't care about element number it's just to have the vertex keys
+              // build the dof
+              sp->getKeys(&ele,R);
+              for(int j=0;j<R.size(); j++)
+                if(filter->operator()(R[j]))
+                  vdof.push_back(R[j]);
+              R.clear();
+              break;
+            }
+          }
+        }
+      }
+      else{ // full Dg
+        for(groupOfElements::elementContainer::iterator ite = dom->g->begin(); ite!=dom->g->end(); ++ite){
+          MElement *ele = *ite;
+          int nbvertex = ele->getNumVertices();
+          sp->getKeys(ele,R);
+          for(std::vector<MVertex*>::iterator it=vv.begin(); it!=vv.end(); ++it){
+            for(int j=0;j<nbvertex; j++){
+              if(ele->getVertex(j) == *it){
+                vdof.push_back(R[j+nbvertex*af.comp]);
+                break;
+              }
+            }
+          }
+          R.clear();
+        }
+      }
+    }
+    // keys = 10*numphys + comp otherwise no way to archive different components
+    int key = 10*af.numphys+af.comp;
+    aef[key] = vdof;
+    aefvalue[key] = 0.;
+  }
+  // force on prescribed displacement (needed to compute external work)
+  for(std::vector<partDomain*>::iterator itdom = domainVector.begin(); itdom!= domainVector.end(); ++itdom){
+    partDomain *dom = *itdom;
+    std::vector<Dof> R;
+    bool flag;
+    for(partDomain::diriContainer::iterator itd = dom->diriBegin(); itd!=dom->diriEnd(); ++itd){
+      nonLinearDirichletBC *diri = *itd;
+      if(diri->_f(0.,0.,0.) != 0.){ // f = simplke Function independant of position otherwise wext = 0
+        FunctionSpaceBase *sp = diri->_space;
+        for(groupOfElements::elementContainer::iterator it = diri->g->begin(); it!=diri->g->end(); ++it){
+          MElement *ele = *it;
+          sp->getKeys(ele,R);
+          for(int i=0; i<R.size(); i++){
+            flag = true;
+            for(std::vector<fextPrescribedDisp>::iterator it2 = _allaef.begin(); it2 != _allaef.end(); ++it2){
+              if(R[i] == (*it2).D){
+                flag = false;
+                break;
+              }
+            }
+            if(flag)
+            {
+              fextPrescribedDisp fpd = fextPrescribedDisp(R[i]);
+              _allaef.push_back(fpd);
+            }
+          }
+          R.clear();
+        }
+      }
+    }
+  }
+}
+
+void nonLinearMechSolver::archivingNodeDisplacement(const int numphys, const int comp){
+  this->archivingNode(numphys,comp,initialCondition::position);
+}
+
+void nonLinearMechSolver::archivingNodeVelocity(const int numphys, const int comp){
+  this->archivingNode(numphys,comp,initialCondition::velocity);
+}
+
+void nonLinearMechSolver::archivingNodeAcceleration(const int numphys, const int comp){
+  this->archivingNode(numphys,comp,initialCondition::acceleration);
+}
+
+void nonLinearMechSolver::archivingNode(const int numphys, const int comp, initialCondition::whichCondition wc){
+  // no distinction between cG/dG and full Dg formulation. class Displacement Field manage it
+  std::vector<MVertex*> vv;
+  pModel->getMeshVerticesForPhysicalGroup(0,numphys,vv);
+
+  if(vv.size() !=0){
+    std::pair< Dof,initialCondition::whichCondition > pai(Dof(vv[0]->getNum(),Dof3IntType::createTypeWithThreeInts(comp,_tag)),wc);
+    anoded.push_back(pai);
+    // remove old file (linux only ??)
+    std::ostringstream oss;
+    oss << vv[0]->getNum(); // Change this
+    std::string s = oss.str();
+    oss.str("");
+    oss << comp;
+    std::string s2 = oss.str();
+    std::string rfname;
+    switch(wc){
+     case initialCondition::position:
+      rfname= "rm NodalDisplacement"+s+"comp"+s2+".csv";
+      break;
+     case initialCondition::velocity:
+      rfname= "rm NodalVelocity"+s+"comp"+s2+".csv";
+      break;
+     case initialCondition::acceleration:
+      rfname= "rm NodalAcceleration"+s+"comp"+s2+".csv";
+      break;
+    }
+    system(rfname.c_str());
+  }
+  else{
+    Msg::Warning("No physical group %d So it is impossible to archive nodal displacement",numphys);
+  }
+}
+
+void nonLinearMechSolver::archivingRigidContact(const int numphys, const int comp, const int wc){
+ initialCondition::whichCondition whc;
+ switch(wc){
+  case 0:
+   whc = initialCondition::position;
+   break;
+  case 1:
+   whc = initialCondition::velocity;
+   break;
+  case 2:
+   whc = initialCondition::acceleration;
+   break;
+  default:
+   whc = initialCondition::position;
+ }
+  // find domain
+  partDomain *domf=NULL;
+  for(contactContainer::const_iterator it = _allContact.begin(); it!=_allContact.end(); ++it){
+    contactDomain *cdom = *it;
+    if(cdom->getPhys() == numphys){
+      int physDom = cdom->getPhysSlave();
+      for(std::vector<partDomain*>::iterator itdom = domainVector.begin(); itdom!=domainVector.end(); ++itdom){
+        partDomain *dom = *itdom;
+        if(dom->getPhysical() == physDom){
+          domf = dom;
+          break;
+        }
+      }
+      break;
+    }
+  }
+  if(domf != NULL){
+    archiveRigidContactDisp ar(numphys,comp,whc,domf);
+    varcd.push_back(ar);
+
+    // remove of csv file Linux only
+    std::ostringstream oss;
+    oss << numphys; // Change this
+    std::string s = oss.str();
+    oss.str("");
+    oss << comp;
+    std::string s2 = oss.str();
+    std::string rfname;
+    switch(whc){
+     case initialCondition::position:
+      rfname= "rm NodalDisplacement"+s+"comp"+s2+".csv";
+      break;
+     case initialCondition::velocity:
+      rfname= "rm NodalVelocity"+s+"comp"+s2+".csv";
+      break;
+     case initialCondition::acceleration:
+      rfname= "rm NodalAcceleration"+s+"comp"+s2+".csv";
+      break;
+    }
+    system(rfname.c_str());
+  }
+  else{
+    Msg::Error("Impossible to archive displacement for contact number %d",numphys);
+  }
+}
+
+void nonLinearMechSolver::archivingNodeIP(const int numphys, const int ipval){
+  vaip.push_back(archiveIPVariable(numphys,ipval));
+}
+
+void nonLinearMechSolver::contactInteraction(contactDomain *cdom){
+  _allContact.insert(cdom);
+}
+
+
+//
+// C++ Interface: terms explicit
+//
+// Description: Files with definition of function : nonLinearMechSolver::solveExplicit()
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+double distanceMin(const double x1, const double x2, const double x3,
+                    const double y1, const double y2, const double y3,
+                    const double z1, const double z2, const double z3){
+  double dist1 = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
+  double dist2 = sqrt((x2-x3)*(x2-x3)+(y2-y3)*(y2-y3)+(z2-z3)*(z2-z3));
+  if(dist1 > dist2)
+    dist1 = sqrt((x3-x1)*(x3-x1)+(y3-y1)*(y3-y1)+(z3-z1)*(z3-z1));
+  else
+    dist2 = sqrt((x3-x1)*(x3-x1)+(y3-y1)*(y3-y1)+(z3-z1)*(z3-z1));
+  if(dist1 > dist2)
+    return dist2;
+  else
+    return dist1;
+}
+// PUT THIS IN MELEMENT ??
+double triangleCharacteristicSize(MElement *ele, unknownField *ufield, std::vector<Dof> &R){
+  std::vector<double> disp;
+  ufield->get(R,disp);
+  double x1 = ele->getVertex(0)->x() + disp[0];
+  double x2 = ele->getVertex(1)->x() + disp[1];
+  double x3 = ele->getVertex(2)->x() + disp[2];
+  double y1 = ele->getVertex(0)->y() + disp[3];
+  double y2 = ele->getVertex(1)->y() + disp[4];
+  double y3 = ele->getVertex(2)->y() + disp[5];
+  double z1 = ele->getVertex(0)->z() + disp[6];
+  double z2 = ele->getVertex(1)->z() + disp[7];
+  double z3 = ele->getVertex(2)->z() + disp[8];
+  return distanceMin(x1,x2,x3,y1,y2,y3,z1,z2,z3);
+/*  double dist1 = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
+  double dist2 = sqrt((x2-x3)*(x2-x3)+(y2-y3)*(y2-y3)+(z2-z3)*(z2-z3));
+  if(dist1 > dist2)
+    dist1 = sqrt((x3-x1)*(x3-x1)+(y3-y1)*(y3-y1)+(z3-z1)*(z3-z1));
+  else
+    dist2 = sqrt((x3-x1)*(x3-x1)+(y3-y1)*(y3-y1)+(z3-z1)*(z3-z1));
+  if(dist1 > dist2)
+    return dist2;
+  else
+    return dist1;*/
+}
+
+// For quadrangle make the search for 2 triangle
+double quadrangleCharacteriticSize(MElement *ele,unknownField *ufield, std::vector<Dof> &R){
+  double hmin1,hmin2;
+  // first triangle node 1,2,3
+  std::vector<Dof> R2;
+
+  R2.push_back(R[0]); R2.push_back(R[1]); R2.push_back(R[2]);
+  R2.push_back(R[4]); R2.push_back(R[5]); R2.push_back(R[6]);
+  R2.push_back(R[8]); R2.push_back(R[9]); R2.push_back(R[10]);
+  MTriangle etri = MTriangle(ele->getVertex(0),ele->getVertex(1),ele->getVertex(2),-1,0);
+  hmin1 = triangleCharacteristicSize(&etri,ufield,R2);
+
+  R2[0] = R[0]; R2[1] = R[2]; R2[2] = R[3];
+  R2[3] = R[4]; R2[4] = R[6]; R2[5] = R[7];
+  R2[6] = R[8]; R2[7] = R[10]; R2[8] = R[11];
+  etri = MTriangle(ele->getVertex(0),ele->getVertex(2),ele->getVertex(3),-1,0);
+  hmin2 = triangleCharacteristicSize(&etri,ufield,R2);
+
+  if(hmin1 > hmin2) return hmin2;
+  else return hmin1;
+}
+
+double quadrangle2orderCharacteristicSize(MElement *ele,unknownField *ufield, std::vector<Dof> &R){
+  double hmin1, hmin2;
+  // make 4 simple quadrangles
+  std::vector<Dof> R2;
+
+  R2.push_back(R[0]); R2.push_back(R[4]); R2.push_back(R[8]); R2.push_back(R[7]);
+  R2.push_back(R[9]); R2.push_back(R[13]); R2.push_back(R[17]); R2.push_back(R[16]);
+  R2.push_back(R[18]);R2.push_back(R[22]); R2.push_back(R[26]); R2.push_back(R[25]);
+  MQuadrangle equad = MQuadrangle(ele->getVertex(0),ele->getVertex(4),ele->getVertex(8),ele->getVertex(7),-1,0);
+  hmin1 = quadrangleCharacteriticSize(&equad,ufield,R2);
+
+  R2[0] = R[4];  R2[1] = R[1];  R2[2] =  R[5];  R2[3] = R[8];
+  R2[4] = R[13]; R2[5] = R[10]; R2[6] =  R[14]; R2[7] = R[17];
+  R2[8] = R[22]; R2[9] = R[19]; R2[10] = R[23]; R2[11] = R[26];
+  equad = MQuadrangle(ele->getVertex(4),ele->getVertex(1),ele->getVertex(5),ele->getVertex(8),-1,0);
+  hmin2 = quadrangleCharacteriticSize(&equad,ufield,R2);
+  if(hmin1 > hmin2) hmin1 = hmin2;
+
+  R2[0] = R[8];  R2[1] = R[5];  R2[2] =  R[2];  R2[3] = R[6];
+  R2[4] = R[17]; R2[5] = R[14]; R2[6] =  R[11]; R2[7] = R[15];
+  R2[8] = R[26]; R2[9] = R[23]; R2[10] = R[20]; R2[11] = R[24];
+  equad = MQuadrangle(ele->getVertex(8),ele->getVertex(5),ele->getVertex(1),ele->getVertex(6),-1,0);
+  hmin2 = quadrangleCharacteriticSize(&equad,ufield,R2);
+  if(hmin1 > hmin2) hmin1 = hmin2;
+
+  R2[0] = R[8];  R2[1] = R[6];  R2[2] =  R[3];  R2[3] = R[7];
+  R2[4] = R[17]; R2[5] = R[15]; R2[6] =  R[12]; R2[7] = R[16];
+  R2[8] = R[26]; R2[9] = R[24]; R2[10] = R[21]; R2[11] = R[25];
+  equad = MQuadrangle(ele->getVertex(8),ele->getVertex(6),ele->getVertex(3),ele->getVertex(7),-1,0);
+  hmin2 = quadrangleCharacteriticSize(&equad,ufield,R2);
+  if(hmin1 > hmin2) hmin1 = hmin2;
+
+  return hmin1;
+}
+
+double quadrangle3orderCharacteristicSize(MElement *ele,unknownField *ufield, std::vector<Dof> &R){
+  // 5 quadrangles of 1st order + One second order quadrangle
+  double hmin1,hmin2;
+  std::vector<Dof> R2;
+
+  R2.push_back(R[0]);  R2.push_back(R[4]); R2.push_back(R[12]); R2.push_back(R[11]);
+  R2.push_back(R[16]); R2.push_back(R[20]); R2.push_back(R[28]); R2.push_back(R[27]);
+  R2.push_back(R[32]); R2.push_back(R[36]); R2.push_back(R[44]); R2.push_back(R[43]);
+  MQuadrangle equad = MQuadrangle(ele->getVertex(0),ele->getVertex(4), ele->getVertex(12), ele->getVertex(11),-1,0);
+  hmin1 = quadrangleCharacteriticSize(&equad,ufield,R2);
+
+  R2[0] = R[4];  R2[1] = R[5];  R2[2] =  R[3];  R2[13] = R[12];
+  R2[4] = R[20]; R2[5] = R[21]; R2[6] =  R[19]; R2[7] = R[28];
+  R2[8] = R[36]; R2[9] = R[37]; R2[10] = R[35]; R2[11] = R[44];
+  equad = MQuadrangle(ele->getVertex(4),ele->getVertex(5),ele->getVertex(13),ele->getVertex(12),-1,0);
+  hmin2 = quadrangleCharacteriticSize(&equad,ufield,R2);
+  if(hmin1 > hmin2) hmin1 = hmin2;
+
+  R2[0] = R[5];  R2[1] = R[1];  R2[2] =  R[6];  R2[13] = R[13];
+  R2[4] = R[21]; R2[5] = R[17]; R2[6] =  R[22]; R2[7] =  R[29];
+  R2[8] = R[37]; R2[9] = R[33]; R2[10] = R[38]; R2[11] = R[45];
+  equad = MQuadrangle(ele->getVertex(5),ele->getVertex(1),ele->getVertex(6),ele->getVertex(13),-1,0);
+  hmin2 = quadrangleCharacteriticSize(&equad,ufield,R2);
+  if(hmin1 > hmin2) hmin1 = hmin2;
+
+  R2[0] = R[13];  R2[1] = R[6];  R2[2] =  R[7];  R2[13] = R[14];
+  R2[4] = R[29]; R2[5] = R[22]; R2[6] =  R[23]; R2[7] = R[30];
+  R2[8] = R[45]; R2[9] = R[38]; R2[10] = R[39]; R2[11] = R[46];
+  equad = MQuadrangle(ele->getVertex(13),ele->getVertex(6),ele->getVertex(7),ele->getVertex(14),-1,0);
+  hmin2 = quadrangleCharacteriticSize(&equad,ufield,R2);
+  if(hmin1 > hmin2) hmin1 = hmin2;
+
+  R2[0] = R[14];  R2[1] = R[7];  R2[2] =  R[2];  R2[13] = R[8];
+  R2[4] = R[30]; R2[5] = R[23]; R2[6] =  R[18]; R2[7] = R[24];
+  R2[8] = R[46]; R2[9] = R[39]; R2[10] = R[34]; R2[11] = R[40];
+  equad = MQuadrangle(ele->getVertex(14),ele->getVertex(7),ele->getVertex(2),ele->getVertex(8),-1,0);
+  hmin2 = quadrangleCharacteriticSize(&equad,ufield,R2);
+  if(hmin1 > hmin2) hmin1 = hmin2;
+
+  // second order quadrangle
+  R2.clear();
+
+  R2.push_back(R[11]); R2.push_back(R[13]); R2.push_back(R[8]); R2.push_back(R[3]); R2.push_back(R[12]); R2.push_back(R[14]);    R2.push_back(R[9]);   R2.push_back(R[10]); R2.push_back(R[15]);
+  R2.push_back(R[27]); R2.push_back(R[29]); R2.push_back(R[24]); R2.push_back(R[19]); R2.push_back(R[28]); R2.push_back(R[30]);  R2.push_back(R[25]);  R2.push_back(R[26]); R2.push_back(R[31]);
+  R2.push_back(R[43]); R2.push_back(R[45]); R2.push_back(R[40]); R2.push_back(R[35]); R2.push_back(R[44]); R2.push_back(R[46]);  R2.push_back(R[41]);  R2.push_back(R[42]); R2.push_back(R[47]);
+
+  MQuadrangle9 equad2 = MQuadrangle9(ele->getVertex(11),ele->getVertex(13),ele->getVertex(8),ele->getVertex(3),
+                                     ele->getVertex(12),ele->getVertex(14),ele->getVertex(9),ele->getVertex(10),
+                                     ele->getVertex(15),-1,0);
+  hmin2 = quadrangle2orderCharacteristicSize(&equad2,ufield,R2);
+  if(hmin1 > hmin2) hmin1 = hmin2;
+  return hmin1;
+
+}
+
+// dont use previous function change this ?
+double triangular3orderCharacteristicSize(MElement *ele,unknownField *ufield,std::vector<Dof> &R){
+  std::vector<double> disp;
+  ufield->get(R,disp);
+  double x0 = ele->getVertex(0)->x() + disp[0];
+  double x1 = ele->getVertex(1)->x() + disp[1];
+  double x2 = ele->getVertex(2)->x() + disp[2];
+  double x3 = ele->getVertex(3)->x() + disp[3];
+  double x4 = ele->getVertex(4)->x() + disp[4];
+  double x5 = ele->getVertex(5)->x() + disp[5];
+  double x6 = ele->getVertex(6)->x() + disp[6];
+  double x7 = ele->getVertex(7)->x() + disp[7];
+  double x8 = ele->getVertex(8)->x() + disp[8];
+  double x9 = ele->getVertex(9)->x() + disp[9];
+
+  double y0 = ele->getVertex(0)->y() + disp[10];
+  double y1 = ele->getVertex(1)->y() + disp[11];
+  double y2 = ele->getVertex(2)->y() + disp[12];
+  double y3 = ele->getVertex(3)->y() + disp[13];
+  double y4 = ele->getVertex(4)->y() + disp[14];
+  double y5 = ele->getVertex(5)->y() + disp[15];
+  double y6 = ele->getVertex(6)->y() + disp[16];
+  double y7 = ele->getVertex(7)->y() + disp[17];
+  double y8 = ele->getVertex(8)->y() + disp[18];
+  double y9 = ele->getVertex(9)->y() + disp[19];
+
+  double z0 = ele->getVertex(0)->z() + disp[20];
+  double z1 = ele->getVertex(1)->z() + disp[21];
+  double z2 = ele->getVertex(2)->z() + disp[22];
+  double z3 = ele->getVertex(3)->z() + disp[23];
+  double z4 = ele->getVertex(4)->z() + disp[24];
+  double z5 = ele->getVertex(5)->z() + disp[25];
+  double z6 = ele->getVertex(6)->z() + disp[26];
+  double z7 = ele->getVertex(7)->z() + disp[27];
+  double z8 = ele->getVertex(8)->z() + disp[28];
+  double z9 = ele->getVertex(9)->z() + disp[29];
+  double dist, distmin;
+  distmin = distanceMin(x0,x3,x8,y0,y3,y8,z0,z3,z8);
+  dist = distanceMin(x3,x9,x8,y3,y9,y8,z3,z9,z8);
+  if (dist < distmin) distmin = dist;
+  dist = distanceMin(x9,x3,x4,y9,y3,y4,z9,z3,z4);
+  if (dist < distmin) distmin = dist;
+  dist = distanceMin(x4,x5,x9,y4,y5,y9,z4,z5,z9);
+  if (dist < distmin) distmin = dist;
+  dist = distanceMin(x4,x5,x1,y4,y5,y1,z4,z5,z1);
+  if (dist < distmin) distmin = dist;
+  dist = distanceMin(x5,x6,x9,y5,y6,y9,z5,z6,z9);
+  if (dist < distmin) distmin = dist;
+  dist = distanceMin(x6,x9,x7,y6,y9,y7,z6,z9,z7);
+  if (dist < distmin) distmin = dist;
+  dist = distanceMin(x7,x8,x9,y7,y8,y9,z7,z8,z9);
+  if (dist < distmin) distmin = dist;
+  dist = distanceMin(x7,x6,x2,y7,y6,y2,z7,z6,z2);
+  if (dist < distmin) distmin = dist;
+  return distmin;
+}
+
+double nonLinearMechSolver::criticalExplicitTimeStep(unknownField *ufield){
+  // evaluate the critical time step carachteristic length = hs
+  // criteria = distance min between 2 nodes
+  double hs;
+  double dtmin=1.e100; // Initialization to infinity
+  for(std::vector<partDomain*>::iterator itdom=domainVector.begin(); itdom!=domainVector.end(); ++itdom){
+    partDomain *dom = *itdom;
+    double hsmin= 1.e100; // Initialization to infinity
+    FunctionSpaceBase *spdom = dom->getFunctionSpace();
+    std::vector<Dof> R;
+    // As time step is compute on element the dom is not an "interface domain"
+    // so getMaterialLawMinus() == getMaterialLawPlus()
+    materialLaw *mlt = dom->getMaterialLaw();
+    double celerity = mlt->soundSpeed();
+    double scaleTimeStep = dom->scaleTimeStep();
+    for(groupOfElements::elementContainer::iterator it=dom->g->begin(); it!=dom->g->end(); ++it){
+      MElement *e = *it;
+      // nodal displacement
+      spdom->getKeys(e,R);
+
+      // Unfortunally, computation of characteristic length depends on the element type
+      // Element are cut in several triangles of degree one
+      // ADD THIS FUNCTIONS directly in gmsh (method of MELEMENT)
+      switch(e->getTypeForMSH()){
+       case MSH_TRI_3:
+        hs = triangleCharacteristicSize(e,ufield,R);
+        break;
+       case MSH_QUA_4:
+        hs = quadrangleCharacteriticSize(e,ufield,R);
+        break;
+       case MSH_QUA_9 :
+        hs = quadrangle2orderCharacteristicSize(e,ufield,R);
+        break;
+       case MSH_QUA_16:
+        hs = quadrangle3orderCharacteristicSize(e,ufield,R);
+        break;
+       case MSH_TRI_10:
+        hs = triangular3orderCharacteristicSize(e,ufield,R);
+        break;
+       default :
+        // default criteria area/(degree*perimter);
+        Msg::Warning("Use a invariant time step predictor because rule for time step computation is unknow for this element type");
+        hs = MInterfaceElement::characSize(e);
+        hs/= e->getPolynomialOrder();
+      }
+
+      if(hs<hsmin) hsmin = hs;
+      R.clear();
+    }
+    double dt = 0.5*scaleTimeStep*hsmin/celerity;  // WHY 0.5 ??
+    if(dt < dtmin ) dtmin = dt;
+  }
+
+  // Delta t of contact
+/*  explicitHCDofManager<double>* dynass = dynamic_cast<explicitHCDofManager<double>*>(pAssembler);
+  // filter because one component is needed (same mass in all direction)
+  DgC0ShellFilterDofComponent filDof(0);
+  for(nonLinearMechSolver::contactContainer::iterator itc = _allContact.begin(); itc!=_allContact.end(); ++itc){
+    contactDomain *cdom = *itc;
+    DgC0rigidContactSpace *csp = dynamic_cast<DgC0rigidContactSpace*>(spaceManager->get(cdom));
+    double penalty = cdom->getPenalty();
+    for(groupOfElements::elementContainer::iterator it = cdom->gSlave->begin(); it!=cdom->gSlave->end(); ++it){
+      MElement *ele = *it;
+      // get mass
+//      int nbdofs = csp->getNumKeys(ele);
+      int nbvertex = ele->getNumVertices();
+//      int nbdofsGC = csp->getNumKeysOfGravityCenter();
+//      int nbcomp = (nbdofs-nbdofsGC)/nbvertex;
+      std::vector<Dof> R;
+      std::vector<double> vmass;
+      csp->getKeys(ele,R);
+      std::vector<Dof> Rfilter;
+      filDof.filter(R,Rfilter);
+      dynass->getVertexMass(Rfilter,vmass);
+      double Mmaster = vmass[nbvertex];
+      for(int i=0; i<nbvertex; i++){
+        double dt = 10000.*sqrt(0.5*Mmaster*vmass[i]/penalty/(Mmaster+vmass[i]));
+        if(dt < dtmin ){
+          dtmin = dt;
+          Msg::Info("Dtc is fixed by contact");
+        }
+      }
+    }
+  }*/
+  return dtmin;
+}
+
+void nonLinearMechSolver::setInitialCondition(){
+  for(std::vector<partDomain*>::iterator itdom=domainVector.begin(); itdom!=domainVector.end(); ++itdom){
+    partDomain *dom = *itdom;
+    for(partDomain::initContainer::iterator it=dom->initCBegin(); it!=dom->initCEnd(); ++it){
+      initialCondition *initC = *it;
+      SetInitialDofs(initC->_space,initC->g->begin(),initC->g->end(),initC->_value,initC->_wc,*pAssembler,*initC->_filter,dom->getFormulation());
+    }
+  }
+  // Eventually read file with initial position
+/*  if(initOrResartfname != ""){
+    // loop on all elements on all domain
+    FunctionSpaceBase *sp; // to create the dofs
+    std::vector<Dof> R;
+    std::vector<double> val;
+    for(std::vector<partDomain*>::iterator itdom = domainVector.begin(); itdom != domainVector.end(); ++itdom){
+      partDomain *dom = *itdom;
+      sp = spaceManager->get(dom);
+      for(groupOfElements::elementContainer::iterator it = dom->g->begin(); it != dom->g->end(); ++it){
+        MElement *ele = *it;
+        // create dof of element
+        sp->getKeys(ele,R);
+
+        // clear
+        R.clear();
+      }
+
+    }
+
+  }*/
+}
+
+void nonLinearMechSolver::solveExplicit(){
+#if defined(HAVE_PETSC)
+  Msg::Info("Explicit Data: endtime = %lf beta=%f gamma=%f alpha_m=%f",this->getEndTime(), this->_beta, this->_gamma, this->_alpham);
+
+  //init
+  this->init();
+
+  // Creation of system
+  if(nonLinearMechSolver::whatSolver!= Petsc)
+    Msg::Warning("Explicit scheme uses Petsc only!");
+
+  explicitHulbertChung<double> *esys = new explicitHulbertChung<double>(_alpham,_beta,_gamma);
+
+  // dof Manager
+  if(pAssembler) delete pAssembler;
+  pAssembler = new explicitHCDofManager<double>(esys);
+
+  // time initialization
+  double curtime = 0.;
+  // Fix Dof
+  this->setTimeForBC(curtime); // otherwise BC which depend on time are put to t=1; and initial value are wrong
+  this->fixNodalDofs();
+  this->numberDofs(esys);
+
+  // System is allocated by numberDofs
+  // so now initial condition can be given to system
+  this->setInitialCondition();
+
+  // definition of ufield and ipfield
+  unknownField *ufield = new unknownDynamicField(pAssembler,domainVector,&_allContact,3,anoded,varcd); // 3 components by nodes User choice ??
+  unknownDynamicField *dynufield = dynamic_cast<unknownDynamicField*>(ufield);
+  this->restart(ufield); // CHANGE THIS
+  IPField ipf(&domainVector,pAssembler,pModel,ufield,vaip); // Field for GaussPoint
+  energeticField efield(esys,&ipf,ufield,pAssembler,domainVector,_allaef);
+  ipf.compute1state(IPStateBase::initial);
+  ipf.initialBroken(pModel, initbrokeninter);
+  ipf.copy(IPStateBase::initial,IPStateBase::current);
+  this->initTerms(ufield,&ipf);
+
+  // compute mass Matrix (outside loop)
+  for(std::vector<partDomain*>::iterator it = domainVector.begin(); it!=domainVector.end(); ++it){
+    partDomain *dom = *it;
+    AssembleMass(dom->getBilinearMassTerm(),*(dom->getFunctionSpace()),dom->g->begin(),dom->g->end(),
+                 *(dom->getBulkGaussIntegrationRule()),*pAssembler);
+  }
+
+  for(nonLinearMechSolver::contactContainer::iterator itc = _allContact.begin(); itc!= _allContact.end(); ++itc){
+    contactDomain *cdom = *itc;
+    if(cdom->isRigid()){
+      rigidContactSpace *rcsp = dynamic_cast<rigidContactSpace*>(cdom->getSpace());
+      AssembleMass(cdom->getMassTerm(),rcsp,pAssembler);
+    }
+  }
+
+  // masse OK
+//  double mas = esys->getSystemMass();
+
+  // initial forces
+  this->computeRightHandSide(esys,pAssembler,ufield,&ipf);
+  esys->nextStep();
+  long int step=0;
+  double timeStep;
+
+
+  while(curtime<endtime){
+
+    // compute time step and current time
+    if(step%numstep ==0 ){
+      timeStep = _gammas * this->criticalExplicitTimeStep(ufield);
+      Msg::Info("time step value: %e",timeStep);
+      esys->setTimeStep(timeStep);
+    }
+    curtime+=timeStep;
+    if(curtime>endtime) curtime = endtime;
+    esys->systemSolve();
+
+  // new forces
+    // Update Boundary Conditions
+    this->setTimeForBC(curtime);
+    this->fixNodalDofs();
+    dynufield->updateFixedDof(timeStep);
+    ipf.compute1state(IPStateBase::current);
+    // eval fracture
+//    ipf.evalFracture(IPState::current,curtime);
+    this->computeRightHandSide(esys,pAssembler,ufield,&ipf);
+  // Archiving
+    if((step+1)%nsba == 0){
+      Msg::Info("Archiving view at time %e",curtime);
+      ufield->buildView(domainVector,curtime,step+1,"displacement",-1,false);
+      ufield->buildView(domainVector,curtime,step+1,"velocity",1,false);
+      ipf.buildView(domainVector,curtime,step+1,"VonMises",-1,false);
+      ipf.buildView(domainVector,curtime,step+1,"sigmaxx",0,false);
+      ipf.buildView(domainVector,curtime,step+1,"sigmayy",1,false);
+      ipf.buildView(domainVector,curtime,step+1,"tauxy",3,false);
+      ipf.buildView(domainVector,curtime,step+1,"VonMisesMax",4,false);
+      efield.buildView(domainVector,curtime,step+1,"total",-1,false);
+    }
+    ufield->archiving(curtime);
+    ipf.archive(curtime);
+    efield.archive(curtime);
+    // Edge force value;
+    FILE *fp;
+    for(std::map<int,double>::iterator it=aefvalue.begin(); it!=aefvalue.end(); ++it){
+      std::ostringstream oss;
+      oss << (it->first)/10;
+      std::string s = oss.str();
+      oss.str("");
+      oss << (it->first)%10;
+      std::string s2 = oss.str();
+      std::string fname = "force"+s+"comp"+s2+".csv";
+      fp = fopen(fname.c_str(),"a");
+      fprintf(fp,"%e;%e\n",curtime,it->second);
+      fclose(fp);
+    }
+
+
+    // next step
+    ipf.nextStep(curtime);
+    esys->nextStep();
+    step++;
+  }
+  delete ufield;
+  Msg::Info("Explicit OK");
+#else
+  Msg::Error("Petsc is not available and so it is impossible to solve the problem. Please install PETsc correctly");
+#endif
+}
+
+
+//
+// C++ Interface: terms Quasi Static
+//
+// Description: Files with definition of function : nonLinearMechSolver::solveSNL()
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+// Function to compute the initial norm
+double nonLinearMechSolver::computeNorm0(linearSystem<double> *lsys, dofManager<double> *pAssembler,
+                                     unknownField *ufield, IPField *ipf){
+  double normFext,normFint;
+  // Set all component of RightHandSide to zero (only RightHandSide is used to compute norm
+  lsys->zeroRightHandSide();
+
+  // fext norm
+  // compute ext forces
+  this->computeExternalForces(ipf,ufield);
+
+  // Contact forces
+  this->computeContactForces();
+
+  // norm
+  normFext = lsys->normInfRightHandSide();
+
+  // Internal forces
+  lsys->zeroRightHandSide();
+  // compute internal forces
+    this->computeInternalForces(ufield);
+    //norm
+    normFint = lsys->normInfRightHandSide();
+
+    // archive
+    return normFext+normFint;
+}
+// compute Fext-Fint
+double nonLinearMechSolver::computeRightHandSide(linearSystem<double> *lsys, dofManager<double> *pAssembler,
+                                    unknownField *ufield, IPField *ipf){
+  lsys->zeroRightHandSide();
+  staticDofManager<double> *pA2 = dynamic_cast<staticDofManager<double>*>(pAssembler);
+  pA2->clearRHSfixed();
+  this->computeInternalForces(ufield);
+  // save Fint component to archive ( write in file when Fint = Fext)
+  pA2->getForces(aef,aefvalue,_allaef);
+  // compute ext forces
+  this->computeExternalForces(ipf,ufield);
+  // compute contact forces
+  this->computeContactForces();
+  return lsys->normInfRightHandSide();
+}
+
+void nonLinearMechSolver::computeInternalForces(unknownField *ufield){
+  for(std::vector<partDomain*>::iterator itdom=domainVector.begin(); itdom!=domainVector.end();++itdom)
+  {
+    partDomain *dom = *itdom;
+    dom->inverseLinearTermSign(); // Because rightHandSide = Fext - Fint
+    Assemble(dom->getLinearBulkTerm(),*(dom->getFunctionSpace()),dom->g->begin(),dom->g->end(),
+             *(dom->getBulkGaussIntegrationRule()),ufield,*pAssembler);
+
+    if(dom->IsInterfaceTerms()){
+      dgPartDomain *dgdom = dynamic_cast<dgPartDomain*>(dom);
+      // Assembling loop on elementary interface terms
+      Assemble(dgdom->getLinearInterfaceTerm(),*(dgdom->getFunctionSpace()),dgdom->gi->begin(),dgdom->gi->end(),*(dgdom->getInterfaceGaussIntegrationRule()),
+                        ufield,*pAssembler); // Use the same GaussQuadrature rule than on the boundary
+      // Assembling loop on elementary boundary interface terms
+      Assemble(dgdom->getLinearVirtualInterfaceTerm(),*(dgdom->getFunctionSpace()),dgdom->gib->begin(),dgdom->gib->end(),
+                 *(dgdom->getInterfaceGaussIntegrationRule()),ufield,*pAssembler); // Use the same GaussQuadrature rule than on the boundary
+    }
+    dom->inverseLinearTermSign(); // Otherwise Fint has not the right sign
+  }
+}
+
+void nonLinearMechSolver::computeContactForces(){
+  for(contactContainer::iterator it = _allContact.begin(); it!=_allContact.end(); ++it){
+    contactDomain *cdom = *it;
+    Assemble(*(cdom->getForceTerm()),*(cdom->getSpace()),cdom->gSlave->begin(),
+            cdom->gSlave->end(),*(cdom->getGaussIntegration()),*pAssembler);
+  }
+}
+
+void nonLinearMechSolver::computeStiffMatrix(const unknownField *ufield){
+
+  for(std::vector<partDomain*>::iterator itdom=domainVector.begin(); itdom!=domainVector.end(); ++itdom)
+  {
+    partDomain* dom = *itdom;
+    // Assembling loop on Elementary terms
+    Assemble(*(dom->getBilinearBulkTerm()),*(dom->getFunctionSpace()),dom->g->begin(),dom->g->end(),
+             *(dom->getBulkGaussIntegrationRule()),*pAssembler);
+
+    if(dom->IsInterfaceTerms()){
+      dgPartDomain *dgdom = dynamic_cast<dgPartDomain*>(dom);
+      // Assembling loop on elementary interface terms
+      Assemble(*(dgdom->getBilinearInterfaceTerm()),*(dom->getFunctionSpace()),dgdom->gi->begin(),dgdom->gi->end(),
+                 *(dgdom->getInterfaceGaussIntegrationRule()),*pAssembler);
+      // Assembling loop on elementary boundary interface terms
+      Assemble(*(dgdom->getBilinearVirtualInterfaceTerm()),*(dom->getFunctionSpace()),dgdom->gib->begin(),dgdom->gib->end(),
+                 *(dgdom->getInterfaceGaussIntegrationRule()),*pAssembler);
+    }
+  }
+
+  // Contact
+  // little particular because it the term itself which know (via its linked linear term) the element
+  // where there is contact and so a bilinearterm != 0 as to be computed
+  for(contactContainer::iterator it = _allContact.begin(); it!=_allContact.end(); ++it){
+    contactDomain *cdom = *it;
+    contactBilinearTermBase<double> *sterm = dynamic_cast<contactBilinearTermBase<double>*>(cdom->getStiffnessTerm());
+    Assemble(*sterm,*(cdom->getSpace()),sterm->getContactNodes()->elemBegin(),
+                    sterm->getContactNodes()->elemEnd(),*(cdom->getGaussIntegration()),*pAssembler);
+    sterm->clearContactNodes();
+  }
+}
+
+// Newton Raphson scheme to solve one step
+void nonLinearMechSolver::NewtonRaphson(linearSystem<double> *lsys, dofManager<double> *pAssembler,unknownField *ufield,
+                                    IPField *ipf,const double Mtime){
+  // compute ipvariable
+  ipf->compute1state(IPStateBase::current);
+
+  // Compute the norm0 : norm(Fint) + norm(Fext) for relative convergence
+  double norm0 = this->computeNorm0(lsys,pAssembler,ufield,ipf);
+
+  // Compute Right Hand Side (Fext-Fint)
+  double normFinf = this->computeRightHandSide(lsys,pAssembler,ufield,ipf);
+
+  // loop until convergence
+  int iter=0;
+  double relnorm = normFinf/norm0;
+  printf("iteration n° %d : residu : %lf\n",iter,relnorm);
+  while(relnorm>_tol){
+    iter++;
+    // Compute Stiffness Matrix
+    this->computeStiffMatrix(ufield);
+
+    // Solve KDu = Fext-Fint
+    lsys->systemSolve();
+
+    // update displacement
+    ufield->update();
+
+    // update ipvariable
+    ipf->compute1state(IPStateBase::current);
+
+    // new forces
+    normFinf = this->computeRightHandSide(lsys,pAssembler,ufield,ipf);
+
+    // Check of convergence
+    relnorm = normFinf/norm0;
+    printf("iteration n° %d : residu : %lf\n",iter,relnorm);
+    lsys->zeroMatrix(); // here otherwise if it has been in computeMatrix the first iteration is very low HOW ??
+  }
+}
+
+// For now no initial displacement
+void nonLinearMechSolver::solveSNL()
+{
+  Msg::Info("SNL Data : nstep =%d endtime=%f",this->getNumStep(),this->getEndTime());
+  // init
+  this->init();
+  // Select the solver for linear system Ax=b (KDeltau = Fext-Fint)
+  linearSystem<double> *lsys;
+  if(nonLinearMechSolver::whatSolver == Taucs){
+    #if defined(HAVE_TAUCS)
+      lsys = new linearSystemCSRTaucs<double>;
+      Msg::Info("Taucs is chosen to solve\n");
+    #else
+      lsys = new linearSystemGmm<double>;
+      lsys = dynamic_cast<linearSystemGmm<double>*>(lsys);
+      dynamic_cast<linearSystemGmm<double>*>(lsys)->setNoisy(2);
+      Msg::Error("Taucs is not installed\n Gmm is chosen to solve\n");
+    #endif
+  }
+  else if(nonLinearMechSolver::whatSolver == Petsc){
+    #if defined(HAVE_PETSC)
+      lsys = new linearSystemPETSc<double>;
+      Msg::Info("PETSc is chosen to solve\n");
+    #else
+      lsys = new linearSystemGmm<double>;
+      lsys = dynamic_cast<linearSystemGmm<double>*>(lsys);
+      dynamic_cast<linearSystemGmm<double>*>(lsys)->setNoisy(2);
+      Msg::Error("PETSc is not installed\n Gmm is chosen to solve\n");
+    #endif
+  }
+  else{
+    lsys = new linearSystemGmm<double>;
+    dynamic_cast<linearSystemGmm<double>*>(lsys)->setNoisy(2);
+    Msg::Info("Gmm is chosen to solve\n");
+  }
+
+  // Creation of dof manager. The Dof where the displacement is prescribed are fixe to zero
+  // for initialization and numerotation of Dof (t=0 at initialization --> prescribed displacement =0)
+
+  if (pAssembler) delete pAssembler;
+  pAssembler = new staticDofManager<double>(lsys);
+
+  // we first do all fixations. the behavior of the dofManager is to
+  // give priority to fixations : when a dof is fixed, it cannot be
+  // numbered afterwards
+
+  // ATTENTION The BC must be rewriten to take into account different fields (CG/DG and fullDG field for exemple)
+  // Fix dof to allow the dofManager to number the dofs
+  this->fixNodalDofs();
+  this->numberDofs(lsys);
+
+  // iterative scheme (loop on timestep)
+  double curtime = 0.;
+  double dt = double(endtime)/double(numstep);
+  unknownField *ufield = new unknownStaticField(pAssembler,domainVector,&_allContact,3,anoded,varcd); // 3 components by nodes User choice ??
+  this->restart(ufield); // CHANGE THIS
+  IPField ipf(&domainVector,pAssembler,pModel,ufield,vaip); // Field for GaussPoint
+  energeticField enerfield(lsys,&ipf,ufield,pAssembler,domainVector,_allaef);
+  ipf.compute1state(IPStateBase::initial);
+  ipf.initialBroken(pModel, initbrokeninter);
+  ipf.copy(IPStateBase::initial,IPStateBase::previous); // if initial stress previous must be initialized before computation
+  this->initTerms(ufield,&ipf);
+
+  for(int ii=0;ii<numstep;ii++){
+    curtime+=dt;
+    printf("t= %lf on %lf\n",curtime,endtime);
+
+    this->setTimeForBC(curtime);
+
+    // Update prescribed Dof displacement
+    this->fixNodalDofs();
+    ufield->updateFixedDof();
+
+    // Solve one step by NR scheme
+    NewtonRaphson(lsys,pAssembler,ufield,&ipf,curtime);
+
+    if((ii+1)%nsba == 0){
+      ufield->buildView(domainVector,curtime,ii+1,"displacement",-1,false);
+      ipf.buildView(domainVector,curtime,ii+1,"VonMises",-1,false);
+      ipf.buildView(domainVector,curtime,ii+1,"sigmaxx",0,false);
+      ipf.buildView(domainVector,curtime,ii+1,"sigmayy",1,false);
+      ipf.buildView(domainVector,curtime,ii+1,"tauxy",3,false);
+      enerfield.buildView(domainVector,curtime,ii+1,"total",-1,false);
+    }
+
+    // Archiving
+    ufield->archiving(curtime);
+    ipf.archive(curtime);
+    enerfield.archive(curtime);
+    // Edge force value;
+    FILE *fp;
+    for(std::map<int,double>::iterator it=aefvalue.begin(); it!=aefvalue.end(); ++it){
+      std::ostringstream oss;
+      oss << (it->first)/10;
+      std::string s = oss.str();
+      oss.str("");
+      oss << (it->first)%10;
+      std::string s2 = oss.str();
+      std::string fname = "force"+s+"comp"+s2+".csv";
+      fp = fopen(fname.c_str(),"a");
+      fprintf(fp,"%lf;%lf\n",curtime,it->second);
+      fclose(fp);
+    }
+
+    // next step for ipvariable
+    ipf.nextStep(curtime);
+  }
+  delete ufield;
+}
+
diff --git a/NonLinearSolver/nlsolver/nonLinearMechSolver.h b/NonLinearSolver/nlsolver/nonLinearMechSolver.h
new file mode 100644
index 0000000000..50f9b75e19
--- /dev/null
+++ b/NonLinearSolver/nlsolver/nonLinearMechSolver.h
@@ -0,0 +1,254 @@
+// Gmsh - Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to <gmsh@geuz.org>.
+
+#ifndef _DGC0SHELL_SOLVER_H_
+#define _DGC0SHELL_SOLVER_H_
+#ifndef SWIG
+#include <map>
+#include <string>
+#include "SVector3.h"
+#include "dofManager.h"
+#include "simpleFunction.h"
+#include "functionSpace.h"
+#include "MInterfaceElement.h"
+#include "groupOfElements.h"
+#include "partDomain.h"
+#include "explicitHulbertChung.h"
+#include "contactDomain.h"
+
+
+class PView;
+class groupOfElements;
+class binding;
+class unknownField;
+class unknownDynamicField;
+class IPField;
+template<class T1,class T2> class DgC0BilinearTerm;
+template<class T1> class DgC0LinearTerm;
+
+struct archiveForce{
+  int numphys;
+  int dim;
+  int comp;
+  archiveForce() : numphys(0), dim(0), comp(0){}
+  archiveForce(const archiveForce &source){
+    numphys = source.numphys;
+    dim = source.dim;
+    comp = source.comp;
+  }
+  archiveForce(int np, int d, int c) : numphys(np), dim(d), comp(c){}
+  ~archiveForce(){}
+};
+
+struct archiveRigidContactDisp{
+  int _physmaster;
+  int _comp;
+  FilterDof *_fdof;
+  initialCondition::whichCondition _wc;
+  archiveRigidContactDisp() : _physmaster(0), _comp(0), _wc(initialCondition::position), _fdof(NULL){}
+  archiveRigidContactDisp(const int nphys, const int cmp,
+                          initialCondition::whichCondition wc, partDomain *dom) : _physmaster(nphys), _comp(cmp), _wc(wc)
+  {
+    // change this HOW
+    _fdof = dom->createFilterDof(cmp);
+  }
+  archiveRigidContactDisp(const archiveRigidContactDisp &source){
+    _physmaster = source._physmaster;
+    _comp = source._comp;
+    _wc = source._wc;
+    _fdof = source._fdof;
+  }
+  ~archiveRigidContactDisp(){}
+};
+
+struct archiveIPVariable{
+  int numphys; // physical number of the node
+  int ipval;   // num of the component to archive // must be defined for each ipvariable
+  archiveIPVariable() : numphys(0), ipval(0){}
+  archiveIPVariable(const archiveIPVariable &source){
+    numphys = source.numphys;
+    ipval = source.ipval;
+  }
+  archiveIPVariable(const int numphys_, const int ipval_) : numphys(numphys_), ipval(ipval_){}
+  ~archiveIPVariable(){}
+};
+
+struct fextPrescribedDisp{
+  Dof D;
+  double val;
+  fextPrescribedDisp(Dof D_) : D(D_), val(0.){}
+  fextPrescribedDisp(const fextPrescribedDisp &source) : D(source.D){
+    val = source.val;
+  }
+};
+#endif
+class nonLinearMechSolver
+{
+ public:
+  typedef std::set<contactDomain*> contactContainer;
+ protected:
+  GModel *pModel;
+  int _dim, _tag;
+  dofManager<double> *pAssembler;
+//  dgGroupCollection _groups;
+  std::vector<partDomain*> domainVector;
+  contactContainer _allContact;
+  // contact
+
+  // neumann BC
+  std::vector<nonLinearNeumannBC> allNeumann;
+  // dirichlet BC
+  std::vector<nonLinearDirichletBC> allDirichlet;
+
+  // initial BC
+  std::vector<initialCondition> allinitial;
+
+  // neumann BC theta (weak enforcement of rotation) regroup this with allNeumann
+  std::vector<nonLinearNeumannBC> allTheta;
+
+  // dirichlet BC on rigid surface (prescribed the motion of gravity center)
+  std::vector<rigidContactBC> allContactBC;
+
+  // set with virtual interfaceElements used to prescribed BC put this in an other place ??
+  std::map<int,groupOfElements> mapvinter;
+
+  // vector with material law
+  std::map<int,materialLaw*> maplaw;
+  // physical entities that are initialy broken
+  std::vector<int> initbrokeninter;
+
+  // map to archive force
+  std::map<int,std::vector<Dof> > aef;
+  std::map<int,double> aefvalue;
+  std::vector<fextPrescribedDisp> _allaef;
+  // std vector to archive a node displacement
+  std::vector<std::pair<Dof,initialCondition::whichCondition> > anoded;
+  // std::vector to archive a force (info musy be store before creation because functionSpace are not initialize)
+  std::vector<archiveForce> vaf;
+  // std vector to archive ipvariable
+  std::vector<archiveIPVariable> vaip;
+  // std vector to archive rigid contact disp
+  std::vector<archiveRigidContactDisp> varcd;
+
+  // specific data
+  int numstep; // Number of step not used for StaticLinearScheme and number of step between time step evaluation for Explicit Scheme
+  double endtime; // final time not used for StaticLinearScheme but it is not necesary to derive class because (small useless data)
+  double _tol; // relative tolerance for iteration not used for StaticLinearScheme but it is not necesary to derive class because (small useless data)
+  int nsba; // number of step between 2 archiving (=1 by default)
+
+  // specific data for explicit scheme
+  double _beta, _gamma, _alpham, _gammas, _rhoinfty;
+
+  // File name for restart or initial value
+  std::string initOrResartfname;
+  bool _restart;
+
+  // Function to initiate the solver before solve
+  // (create interfaceElement and link the materialLaw and dgLinearShellDomain)
+#ifndef SWIG
+  void init();
+  void initTerms(unknownField *ufield, IPField *ipf);
+
+  // Split Boundary Condition Between the different partDomain
+  void splitBoundaryConditions();
+
+  // Function used by non linear solver
+  void NewtonRaphson(linearSystem<double> *lsys, dofManager<double> *pAssembler, unknownField *ufield,
+                     IPField *ipf,const double time);
+
+  double computeNorm0(linearSystem<double> *lsys, dofManager<double> *pAssembler, unknownField *ufield,
+                      IPField *ipf);
+
+  double computeRightHandSide(linearSystem<double> *lsys, dofManager<double> *pAssembler, unknownField *ufield,
+                                    IPField *ipf);
+
+  void computeStiffMatrix(const unknownField *ufield);
+  void computeExternalForces(IPField *ipf, const unknownField *ufield);
+  void computeContactForces();
+  void computeInternalForces(unknownField *ufield);
+  void fixNodalDofs();
+  void numberDofs(linearSystem<double> *lsys);
+  void insertTheta(const int numphys, groupOfElements *goe);
+  double criticalExplicitTimeStep(unknownField *ufield);
+  void setInitialCondition();
+  void setTimeForBC(double time);
+  void initArchiveForce();
+  void initContactInteraction();
+#endif
+ public : //protected with lua ??
+  enum solver{ Gmm=0,Taucs=1,Petsc=2};
+  enum scheme{StaticLinear=0, StaticNonLinear=1, Explicit=2};
+  solver whatSolver; //  Solver used to solve
+  scheme whatScheme; // scheme used to solve equation
+ public:
+  nonLinearMechSolver(int tag) : _tag(tag), pAssembler(0), numstep(1), endtime(1.), _tol(1.e-6), nsba(1),
+                             whatSolver(nonLinearMechSolver::Gmm), whatScheme(nonLinearMechSolver::StaticLinear),
+                             _beta(0.), _gamma(0.5), _alpham(0.), _rhoinfty(1.), initOrResartfname(""), _restart(false)
+  {} // default Gmm and static linear scheme
+
+  virtual ~nonLinearMechSolver()
+  {
+    if (pAssembler) delete pAssembler;
+//    for(std::map<int,materialLaw*>::iterator it = maplaw.begin(); it!=maplaw.end();++it){ delete it->second;}
+    // I can't delete or problem at the end since swig.
+//    for(std::vector<partDomain*>::iterator it = domainVector.begin(); it!=domainVector.end(); ++it){delete *it;}
+  }
+#ifndef SWIG
+  int getStepBetweenArchiving() const{return nsba;}
+  int getNumStep() const{return numstep;}
+  double getEndTime() const{return endtime;}
+  scheme getScheme() const{return whatScheme;}
+  virtual void solveStaticLinar();
+  virtual void solveSNL();
+  virtual void solveExplicit();
+  virtual void createInterfaceElement();
+  virtual materialLaw* getMaterialLaw(const int num);
+  // create interfaceelement with dgGoupOfElement from dg project doesn't work (segmentation fault)
+  virtual void createInterfaceElement_2();
+#endif
+  // functions for lua interaction
+  void loadModel(const std::string meshFileName);
+  virtual void solve();
+//  virtual void addDgLinearElasticShellDomain(dgLinearShellDomain* dom);
+//  virtual void addInterShellDomain(interDomainBetweenShell *dom);
+  virtual void addDomain(partDomain *dom);
+//  virtual void addDomain(dgLinearShellDomain* dom);
+  virtual void addMaterialLaw(materialLaw *mlaw);
+//  virtual void addLinearElasticShellLaw(linearElasticShellLaw *mlaw);
+//  virtual void addShellLinearCohesiveLaw(shellLinearCohesiveLaw *mlaw);
+//  virtual void addLinearElasticOrthotropicShellLaw(linearElasticOrthotropicShellLaw *mlaw);
+//  virtual void addshellFractureByCohesiveLaw(shellFractureByCohesiveLaw *mlaw);
+  void Solver(const int s){whatSolver= (solver)s;}
+  void Scheme(const int s){whatScheme=(scheme)s;}
+  void snlData(const int ns, const double et, const double reltol);
+  void explicitData(const double ftime, const double gams=0.666667, const double beta=0, const double gamma=0.5, const double alpham=0.);
+  void explicitSpectralRadius(const double ftime,const double gams=0.666667,const double rho=1.);
+  void explicitTimeStepEvaluation(const int nst);
+  void stepBetweenArchiving(const int n){nsba = n;}
+  virtual void thetaBC(const int numphys);
+  virtual void displacementBC(std::string onwhat, const int numphys, const int comp, const double value);
+  virtual void displacementRigidContactBC(const int numphys, const int comp,const double value);
+  virtual void initialBC(std::string onwhat, std::string whichC, const int numphys, const int comp, const double value);
+  virtual void forceBC(std::string onwhat, const int numphys, const int comp, const double val);
+  virtual void independentDisplacementBC(std::string onwhat, const int numphys, const int comp, const double value);
+  virtual void independentForceBC(std::string onwhat, const int numphys, const int comp, const double val);
+  virtual void blastPressureBC(const int numphys,const double p0,const double p1, const double plexp, const double t0, const double t1);
+  virtual void pressureOnPhysicalGroupBC(const int numphys, const double press, const double p0);
+  virtual void archivingForceOnPhysicalGroup(const std::string onwhat, const int numphys, const int comp);
+  virtual void archivingNodeDisplacement(const int num, const int comp);
+  virtual void archivingNodeVelocity(const int num, const int comp);
+  virtual void archivingNodeAcceleration(const int num, const int comp);
+  virtual void archivingNode(const int num, const int comp, initialCondition::whichCondition);
+  virtual void archivingNodeIP(const int numphys, const int ipval);
+  virtual void physInitBroken(const int phys);
+  virtual void setInitOrRestartFileName(const std::string fname);
+  virtual void restart(unknownField *ufield);
+  virtual void contactInteraction(contactDomain *cdom);
+  virtual void archivingRigidContact(const int numphys, const int comp, const int wc=0);
+};
+
+
+#endif // nonLinearMechSolver
+
diff --git a/NonLinearSolver/nlsolver/staticDofManager.h b/NonLinearSolver/nlsolver/staticDofManager.h
new file mode 100644
index 0000000000..99950b79f0
--- /dev/null
+++ b/NonLinearSolver/nlsolver/staticDofManager.h
@@ -0,0 +1,157 @@
+//
+// C++ Interface: terms
+//
+// Description: dofManager for non linear system (rewritte of assemble(fullMatrix) no contribution for fixed Dof
+//              The contribution is taken into account in the assemble(fullvector) of RightHandSide
+//              More add functions to archiving force can be placed in dofManager but I put it here to not pollute gmsh code
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef _STATICDOFMANAGER_H_
+#define _STATICDOFMANAGER_H_
+
+#include "dofManager.h"
+#include "nonLinearMechSolver.h"
+template<class T>
+class staticDofManager : public dofManager<T>{
+ protected :
+  // map to retains the force of fixed dof (needed for archiving) the other RHS value are accessible in RHS
+  std::map<Dof, typename dofManager<T>::dataVec> RHSfixed;
+
+ public :
+
+ staticDofManager(linearSystem< typename dofManager<T>::dataMat > *l) : dofManager<T>(l){
+//    for(int i=0;i<varchdof.size();i++)
+//      RHSfixed[varchdof[i]] = value;
+
+}
+ staticDofManager(linearSystem< typename dofManager<T>::dataMat > *l1, linearSystem<typename dofManager<T>::dataMat> *l2) : dofManager<T>(l1,l2){
+//    for(int i=0;i<varchdof.size();i++)
+//      RHSfixed[varchdof[i]] = value;
+}
+
+ // this function is replaced to avoid a double contribution in right hand side for fixed dof
+  virtual inline void assemble(std::vector<Dof> &R, const fullMatrix<typename dofManager<T>::dataMat> &m)
+  {
+    if (!this->_current->isAllocated()) this->_current->allocate(this->unknown.size());
+    std::vector<int> NR(R.size());
+    for (unsigned int i = 0; i < R.size(); i++)
+    {
+      std::map<Dof, int>::iterator itR = this->unknown.find(R[i]);
+      if (itR != this->unknown.end()) NR[i] = itR->second;
+      else NR[i] = -1;
+    }
+    for (unsigned int i = 0; i < R.size(); i++)
+    {
+      if (NR[i] != -1)
+      {
+        for (unsigned int j = 0; j < R.size(); j++)
+        {
+          if (NR[j] != -1)
+          {
+            this->_current->addToMatrix(NR[i], NR[j], m(i, j));
+          }
+          else
+          {
+            typename std::map<Dof,  typename dofManager<T>::dataVec>::iterator itFixed = this->fixed.find(R[j]);
+            if (itFixed == this->fixed.end())
+              assembleLinConst(R[i],R[j],m(i,j));
+          }
+        }
+      }
+      else
+      {
+        for (unsigned int j = 0; j < R.size(); j++){
+        assembleLinConst(R[i],R[j],m(i,j));
+        }
+      }
+    }
+  }
+
+  //
+  // Function to fix dof (Create the key in RHS fixed too)
+  inline void fixDof(Dof key, const typename dofManager<T>::dataVec &value){
+     if(this->unknown.find(key) != this->unknown.end())
+      return;
+    this->fixed[key] = value;
+    this->RHSfixed[key]=0.;
+  }
+
+  // function assemble(vect) is rewritten to archiving rhs if needed
+  virtual inline void assemble(std::vector<Dof> &R, const fullVector<typename dofManager<T>::dataMat> &m) // for linear forms
+  {
+    if (!this->_current->isAllocated()) this->_current->allocate(this->unknown.size());
+    std::vector<int> NR(R.size());
+    // Archiving
+    for (unsigned int i = 0; i < R.size(); i++)
+    {
+      typename std::map<Dof,  typename dofManager<T>::dataVec>::iterator itR = RHSfixed.find(R[i]);
+      if (itR != RHSfixed.end()) itR->second += m(i); // add of contribution set to zero when the value is by a function FIX it
+      else NR[i] = -1;
+    }
+
+    for (unsigned int i = 0; i < R.size(); i++)
+    {
+      std::map<Dof, int>::iterator itR = this->unknown.find(R[i]);
+      if (itR != this->unknown.end()) NR[i] = itR->second;
+      else NR[i] = -1;
+    }
+    for (unsigned int i = 0; i < R.size(); i++)
+    {
+      if (NR[i] != -1)
+      {
+        this->_current->addToRightHandSide(NR[i], m(i));
+      }
+      else
+      {
+        typename std::map<Dof,DofAffineConstraint<typename dofManager<T>::dataVec> >::iterator itConstraint;
+        itConstraint = this->constraints.find(R[i]);
+        if (itConstraint != this->constraints.end())
+        {
+          for (unsigned i=0;i<(itConstraint->second).linear.size();i++)
+          {
+                  std::map<Dof, int>::iterator itC = this->unknown.find((itConstraint->second).linear[i].first); // lin dep in unknown ?!
+                  this->_current->addToRightHandSide(itC->second, m(i)*(itConstraint->second).linear[i].second);
+          }
+        }
+      }
+    }
+  }
+  // zero for RHSfixed
+  void clearRHSfixed(){
+    for(typename std::map<Dof,typename dofManager<T>::dataVec>::iterator itR = RHSfixed.begin();itR != RHSfixed.end(); ++itR)
+      itR->second = 0.;
+  }
+
+  void getForces(std::map<int,std::vector<Dof> > &aef, std::map<int,typename dofManager<T>::dataVec> &data,
+                 std::vector<fextPrescribedDisp> &allaef){
+    for(std::map<int,std::vector<Dof> >::iterator it = aef.begin(); it != aef.end(); ++it){
+      double Fint =0.;
+      for(int i=0;i<it->second.size();i++){
+        // look in RHSfixed
+        typename std::map<Dof, typename dofManager<T>::dataVec>::iterator itRHS = RHSfixed.find(it->second[i]);
+        if(itRHS != RHSfixed.end())
+          Fint -= itRHS->second; // as internal forces are computed with a minus sign in computeRightHandSide;
+        else{
+          typename std::map<Dof,int>::iterator itunk = this->unknown.find(it->second[i]);
+          if(itunk != this->unknown.end()){
+            double ff;
+            this->_current->getFromRightHandSide(itunk->second,ff);
+            Fint -= ff;
+          }
+        }
+      }
+      data[it->first] = Fint;
+
+    }
+    // needed to compute work of external force external => fixed ??
+    for(int i=0; i<allaef.size(); i++){
+      allaef[i].val = - RHSfixed[allaef[i].D];
+    }
+  }
+};
+
+#endif // STATICDOFMANAGERSYSTEM_H_
+
diff --git a/NonLinearSolver/nlsolver/timeFunction.h b/NonLinearSolver/nlsolver/timeFunction.h
new file mode 100644
index 0000000000..c2d94dabfb
--- /dev/null
+++ b/NonLinearSolver/nlsolver/timeFunction.h
@@ -0,0 +1,83 @@
+//
+// C++ Interface: terms
+//
+// Description: Derivate class of SimpleFunction to include a time dependency
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef TIMEFUNCTION_H_
+#define TIMEFUNCTION_H_
+#include "simpleFunction.h"
+template<class scalar>
+class simpleFunctionTime : public simpleFunction<scalar>{
+  protected :
+    double time;
+    bool timeDependency;
+  public :
+    simpleFunctionTime(scalar val=0, bool td=true, double t=1.) : simpleFunction<scalar>(val), time(t), timeDependency(td){}; // time=1 by default to avoid set time for Static linear Scheme
+    ~simpleFunctionTime(){};
+#ifndef SWIG
+    virtual scalar operator () (double x, double y, double z) const { if(timeDependency) return time*this->_val; else return this->_val;}
+    void setTime(const double t){time=t;}
+    void scaleVal(const double fac){this->_val*=fac;}
+#endif
+};
+#ifndef SWIG
+template<class scalar>
+class simpleFunctionTimeWithConstant : public simpleFunctionTime<scalar>{
+  protected:
+    scalar _b;
+  public:
+    simpleFunctionTimeWithConstant(scalar val=0, bool td=true, double t=1.,scalar b=0.) : simpleFunctionTime<scalar>(val,td,t), _b(b){};
+    ~simpleFunctionTimeWithConstant(){};
+    virtual scalar operator () (double x, double y, double z) const { if(this->timeDependency) return this->time*this->_val+_b; else return this->_val;}
+
+};
+#endif
+class powerDecreasingFunctionTime : public simpleFunctionTime<double>{
+ protected:
+// _val = p0  const double p0; // minimal pressure
+  const double _p1; // maximal pressure
+  const double _a;  // power exponent
+  const double _t0; // if t < t0 p = p0
+  const double _t1; // if t0 < t < t1 p = p0 + (p1-p0)*(t-t0)/(t1-t0)
+  const double _tf; // if t1 < t < tf p = (p1-p0)*(tf-t1)^-a*(tf-t)^a + p0
+ public:
+  powerDecreasingFunctionTime(double p0, const double p1, const double a, const double t0,
+                              const double t1, const double tf) : simpleFunctionTime<double>(p0,true,1.),
+                                                                     _p1(p1), _a(a), _t0(t0), _t1(t1), _tf(tf){}
+  ~powerDecreasingFunctionTime(){}
+  virtual double operator () (double x, double y, double z) const{
+    double p0 = _val;
+    if((_t0<time) and(time<_t1))
+      return p0 + (_p1-p0)*(time-_t0)/(_t1-_t0);
+    else if ((_t1<time) and (time<_tf))
+      return (_p1-p0)*pow(_tf-_t1,-_a)*pow(_tf-time,_a)+p0;
+    else
+      return p0;
+  }
+//  void setTime(const double t){time=t;}
+/*  static void registerBindings(binding *b){
+    classBinding *cb = b->addClass<powerDecreasingFunctionTime>("powerDecreasingTime");
+    cb->setDescription("Function power decreasing in time. Three parts: First one t<t0 value=cste=p0 , Second part t0<t<t1 value= (p1-p0)*(t-t0)/(t1-t0)+p0 Third part value = (p1-p0)*(tf-t1)^-a*(tf-t)^a+p0");
+    methodBinding *cm;
+    cm = cb->setConstructor<powerDecreasingFunctionTime,double,double,double,double,double,double>();
+    cm->setArgNames("p0","p1","a","t0","t1","tf",NULL);
+    cm->setDescription("power decresing law. See class description to see how it has to be used");
+
+    // use to validate
+//    cm = cb->addMethod("setTime", &powerDecreasingFunctionTime::setTime);
+//    cm->setArgNames("t",NULL);
+//    cm->setDescription("set time t");
+//    cm = cb->addMethod("get", &powerDecreasingFunctionTime::operator());
+//    cm->setArgNames("x","y","z",NULL);
+//    cm->setDescription("get value");
+  }
+*/
+};
+#endif // TIMEFUNCTION
+
diff --git a/NonLinearSolver/nlsolver/unknownDynamicField.cpp b/NonLinearSolver/nlsolver/unknownDynamicField.cpp
new file mode 100644
index 0000000000..38fe57ceb3
--- /dev/null
+++ b/NonLinearSolver/nlsolver/unknownDynamicField.cpp
@@ -0,0 +1,179 @@
+//
+// C++ Interface: terms
+//
+// Description: Class with the displacement field for a dynamic system
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+
+#include "unknownDynamicField.h"
+#include "nlsolAlgorithms.h"
+unknownDynamicField::unknownDynamicField(dofManager<double> *pas, std::vector<partDomain*> &vdom,
+                                                   nonLinearMechSolver::contactContainer *acontact,
+                                     const int nc, std::vector<std::pair<Dof,initialCondition::whichCondition> > &archiving,
+                                     std::vector<archiveRigidContactDisp> &contactarch, const bool view_, const std::string filen) : unknownField(pas,vdom,acontact,nc,archiving,contactarch,view_,filen)
+{
+  // to avoid constant dynamic cast
+  dynassembler = dynamic_cast<explicitHCDofManager<double>*>(pAssembler);
+}
+
+void unknownDynamicField::update(){
+  Msg::Warning("The update of displacement field is unnecessary for a dynamic scheme");
+}
+
+void unknownDynamicField::get(Dof &D,double &udof) const {
+  this->get(D,udof,initialCondition::position);
+}
+void unknownDynamicField::get(Dof &D, double &udof, initialCondition::whichCondition wv) const {
+  dynassembler->getDofValue(D,udof,wv);
+}
+
+void unknownDynamicField::get(std::vector<Dof> &R, std::vector<double> &udofs) const {
+  this->get(R,udofs,initialCondition::position);
+}
+
+void unknownDynamicField::get(std::vector<Dof> &R, fullVector<double> &udofs) const {
+  this->get(R,udofs,initialCondition::position);
+}
+
+void unknownDynamicField::get(std::vector<Dof> &R, std::vector<double> &udofs, initialCondition::whichCondition wv) const {
+  double du;
+  for(int i=0;i<R.size(); i++){
+    this->get(R[i],du,wv);
+    udofs.push_back(du);
+  }
+}
+void unknownDynamicField::get(std::vector<Dof> &R, fullVector<double> &udofs, initialCondition::whichCondition wv) const {
+  double du;
+  for(int i=0;i<R.size(); i++){
+    this->get(R[i],du,wv);
+    udofs(i) = du;
+  }
+}
+
+void unknownDynamicField::get(partDomain *dom,MElement *ele, std::vector<double> &udofs, const int cc){
+  // -1 or 0 = position
+  // 1 = velocity
+  // 2 = acceleration
+  initialCondition::whichCondition wv;
+  if (cc==1)
+    wv= initialCondition::velocity;
+  else if(cc==2)
+    wv= initialCondition::acceleration;
+  else
+    wv= initialCondition::position;
+  FunctionSpaceBase *sp = dom->getFunctionSpace();
+  std::vector<Dof> R;
+  sp->getKeys(ele,R);
+  this->get(R,udofs,wv);
+}
+
+void unknownDynamicField::get(partDomain *dom,MElement *ele, fullVector<double> &udofs, const int cc){
+  // -1 or 0 = position
+  // 1 = velocity
+  // 2 = acceleration
+  initialCondition::whichCondition wv;
+  if (cc==1)
+    wv= initialCondition::velocity;
+  else if(cc==2)
+    wv= initialCondition::acceleration;
+  else
+    wv= initialCondition::position;
+  FunctionSpaceBase *sp = dom->getFunctionSpace();
+  std::vector<Dof> R;
+  sp->getKeys(ele,R);
+  udofs.resize(sp->getNumKeys(ele));
+  this->get(R,udofs,wv);
+}
+
+void unknownDynamicField::get(partDomain *dom,MInterfaceElement *iele, std::vector<double> &udofs){
+  this->get(dom,iele,udofs,initialCondition::position);
+}
+
+void unknownDynamicField::get(partDomain *dom,MInterfaceElement *iele, std::vector<double> &udofs, initialCondition::whichCondition wv){
+  this->get(dom,iele->getElem(0),udofs,wv);
+  if(!(iele->getElem(0)==iele->getElem(1))){// Virtual interface element
+    this->get(dom,iele->getElem(1),udofs,wv);
+  }
+}
+
+void unknownDynamicField::get(partDomain *dom1, partDomain *dom2,
+                                   MInterfaceElement *iele, std::vector<double> &udofs){
+  this->get(dom1,dom2,iele,udofs,initialCondition::position);
+}
+
+void unknownDynamicField::get(FunctionSpaceBase*sp1, FunctionSpaceBase *sp2,
+                                   MInterfaceElement *iele, std::vector<double> &udofs){
+  this->get(sp1,sp2,iele,udofs,initialCondition::position);
+}
+
+void unknownDynamicField::get(partDomain *dom1, partDomain *dom2,
+                                   MInterfaceElement *iele, std::vector<double> &udofs, initialCondition::whichCondition wv){
+  this->get(dom1,iele->getElem(0),udofs,wv);
+  if(!(iele->getElem(0)==iele->getElem(1))){// Virtual interface element
+    this->get(dom2,iele->getElem(1),udofs,wv);
+  }
+}
+
+void unknownDynamicField::get(FunctionSpaceBase *sp1, FunctionSpaceBase *sp2,
+                                   MInterfaceElement *iele, std::vector<double> &udofs, initialCondition::whichCondition wv){
+  std::vector<Dof> R;
+  sp1->getKeys(iele->getElem(0),R);
+  this->get(R,udofs,wv);
+  if(!(iele->getElem(0)==iele->getElem(1))){// Virtual interface element
+    R.clear();
+    sp2->getKeys(iele->getElem(1),R);
+    this->get(R,udofs,wv);
+  }
+}
+
+void unknownDynamicField::updateFixedDof(){
+  Msg::Warning("Impossible to update the fixed dof because the time step is not passed in argument");
+}
+
+void unknownDynamicField::updateFixedDof(const double timeStep){
+  dynassembler->updateFixedDof(timeStep);
+}
+
+void unknownDynamicField::archiving(const double time){
+  FILE *fp;
+  double u;
+  for(std::vector<archiveNode>::iterator it = varch.begin(); it!=varch.end();++it){
+    Dof D = it->D;
+    dynassembler->getDofValue(D,u,it->wc);
+    // write in File
+      std::ostringstream oss;
+      oss << it->nodenum;
+      std::string s = oss.str();
+      // component of displacement
+      int field,comp,num;
+      Dof3IntType::getThreeIntsFromType(it->D.getType(),comp,field,num);
+      oss.str("");
+      oss << comp;
+      std::string s2 = oss.str();
+      std::string fname;
+      switch(it->wc){
+       case initialCondition::position:
+        fname = "NodalDisplacement"+s+"comp"+s2+".csv";
+        break;
+       case initialCondition::velocity:
+        fname = "NodalVelocity"+s+"comp"+s2+".csv";
+        break;
+       case initialCondition::acceleration:
+        fname = "NodalAcceleration"+s+"comp"+s2+".csv";
+        break;
+      }
+      fp = fopen(fname.c_str(),"a");
+      fprintf(fp,"%e;%e\n",time,u);
+      fclose(fp);
+  }
+}
+
+void unknownDynamicField::setInitial(const std::vector<Dof> &R, const std::vector<double> &disp){
+  for(int i=0;i<R.size();i++){
+    dynassembler->setInitialCondition(R[i],disp[i],initialCondition::position);
+  }
+}
diff --git a/NonLinearSolver/nlsolver/unknownDynamicField.h b/NonLinearSolver/nlsolver/unknownDynamicField.h
new file mode 100644
index 0000000000..e42eae29a7
--- /dev/null
+++ b/NonLinearSolver/nlsolver/unknownDynamicField.h
@@ -0,0 +1,51 @@
+//
+// C++ Interface: terms
+//
+// Description: Class with the displacement field for a dynamic system
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+#ifndef UNKNOWNDYNAMICFIELD_H_
+#define UNKNOWNDYNAMICFIELD_H_
+#include "unknownField.h"
+#include "explicitDofManager.h"
+#include "explicitHulbertChung.h"
+
+class unknownDynamicField : public unknownField{
+ protected:
+  explicitHCDofManager<double> *dynassembler;
+
+ public:
+  unknownDynamicField(dofManager<double> *pas, std::vector<partDomain*> &vdom,
+                           nonLinearMechSolver::contactContainer *acontact,
+                                     const int nc, std::vector<std::pair<Dof,initialCondition::whichCondition> > &archiving,
+                                     std::vector<archiveRigidContactDisp> &contactarch, const bool view_=true, const std::string filen="disp.msh");
+
+  virtual void update();
+  virtual void get(Dof &D, double &udof) const;
+  virtual void get(Dof &D, double &udof, initialCondition::whichCondition wv) const ;
+  virtual void get(std::vector<Dof> &R, std::vector<double> &disp) const;
+  virtual void get(std::vector<Dof> &R, fullVector<double> &disp) const;
+  virtual void get(std::vector<Dof> &R, std::vector<double> &disp,initialCondition::whichCondition wv) const ;
+  virtual void get(std::vector<Dof> &R, fullVector<double> &disp,initialCondition::whichCondition wv) const ;
+  virtual void get(partDomain *dom,MElement *ele, std::vector<double> &udofs, const int cc= -1);
+  virtual void get(partDomain *dom,MElement *ele, fullVector<double> &udofs, const int cc= -1);
+  virtual void get(partDomain *dom, MInterfaceElement *iele, std::vector<double> &udofs);
+
+  virtual void get(partDomain *dom, MInterfaceElement *iele, std::vector<double> &udofs, initialCondition::whichCondition);
+  virtual void get(partDomain *dom1, partDomain *dom2, MInterfaceElement *iele, std::vector<double> &udofs) ;
+  virtual void get(FunctionSpaceBase *sp1, FunctionSpaceBase *sp2, MInterfaceElement *iele, std::vector<double> &udofs) ;
+  virtual void get(partDomain *dom1, partDomain *dom2, MInterfaceElement *iele, std::vector<double> &udofs,
+                   initialCondition::whichCondition wv= initialCondition::position) ;
+  virtual void get(FunctionSpaceBase *sp1, FunctionSpaceBase *sp2, MInterfaceElement *iele, std::vector<double> &udofs,
+                   initialCondition::whichCondition wv= initialCondition::position) ;
+  virtual void updateFixedDof();
+  virtual void updateFixedDof(const double timeStep);
+  virtual void archiving(const double time);
+  virtual void setInitial(const std::vector<Dof> &R, const std::vector<double> &disp);
+};
+#endif // UNKNOWNDYNAMICFIELD_H_
+
diff --git a/NonLinearSolver/nlsolver/unknownField.cpp b/NonLinearSolver/nlsolver/unknownField.cpp
new file mode 100644
index 0000000000..a08cb504e2
--- /dev/null
+++ b/NonLinearSolver/nlsolver/unknownField.cpp
@@ -0,0 +1,106 @@
+//
+// C++ Interface: terms
+//
+// Description: Class with the displacement field
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "unknownField.h"
+#include "nonLinearMechSolver.h"
+#include "nlsolAlgorithms.h"
+#include "MPoint.h"
+// constructor
+
+unknownField::unknownField(dofManager<double> *pas, std::vector<partDomain*> &vdom, nonLinearMechSolver::contactContainer *acontact,
+                                     const int nc, std::vector<std::pair<Dof,initialCondition::whichCondition> > &archiving,
+                                     std::vector<archiveRigidContactDisp> &contactarch, const bool view_, const std::string filen): pAssembler(pas),
+                                                                            domainVector(&vdom),
+                                                                            _allContact(acontact),
+                                                                            elementField(filen,100000000,nc,elementField::ElementNodeData,view_)
+{
+
+
+  pAssembler->getFixedDof(fixedDof);
+  std::vector<bool> alfind;
+  for(int i=0;i<archiving.size(); i++)
+    alfind.push_back(false);
+  long int totelem=0;
+  for(std::vector<partDomain*>::iterator itdom=vdom.begin(); itdom!=vdom.end(); ++itdom){
+    partDomain *dom = *itdom;
+    bool fullDg = dom->getFormulation();
+    FunctionSpaceBase *sp = dom->getFunctionSpace();
+    std::vector<Dof> R;
+    totelem += dom->g->size();
+    if(!fullDg){
+      for(groupOfElements::vertexContainer::iterator it=dom->g->vbegin(); it!=dom->g->vend(); ++it){
+        MVertex *ver = *it;
+        MPoint ele = MPoint(ver,-1); // We don't care about element number it is just to have the vertex keys;
+        sp->getKeys(&ele,R);
+        // make dof for archiving node
+        for(int i=0;i<archiving.size();i++){
+          if( (alfind[i] == false) and (ver->getNum() == archiving[i].first.getEntity())){
+            // get the comp of the archiving node
+            int comp,field,num;
+            Dof3IntType::getThreeIntsFromType(archiving[i].first.getType(),comp,field,num);
+            FilterDof* filter = dom->createFilterDof(comp);
+            for(int j=0;j<R.size();j++){
+              if(filter->operator()(R[j])){
+                alfind[i] = true;
+                varch.push_back(archiveNode(R[j],ver->getNum(),archiving[i].second));
+              }
+            }
+          }
+        }
+        R.clear();
+      }
+    }
+    else{
+      // loop on element (entity of formulation)
+      for(groupOfElements::elementContainer::iterator it=dom->g->begin(); it!=dom->g->end(); ++it){
+        MElement *ele = *it;
+        sp->getKeys(ele,R);
+        // loop on vertex element (for archiving node)
+        int nbvertex = ele->getNumVertices();
+        for(int j=0;j<nbvertex;j++){
+          MVertex *ver = ele->getVertex(j);
+          for(int i=0; i<archiving.size(); i++){
+            if((alfind[i] == false) and(ver->getNum() == archiving[i].first.getEntity())){
+              // get the comp of the archiving node
+              int comp,field,num;
+              Dof3IntType::getThreeIntsFromType(archiving[i].first.getType(),comp,field,num);
+              alfind[i] = true;
+              varch.push_back(archiveNode(R[j+comp*nbvertex],ver->getNum(),archiving[i].second));
+              break;
+            }
+          }
+        }
+        R.clear();
+      }
+    }
+  }
+  // increment the total element with rigid contact and add archiving if necessary
+
+  for(nonLinearMechSolver::contactContainer::iterator it = _allContact->begin(); it!=_allContact->end(); ++it){
+    contactDomain *cdom = *it;
+    if(cdom->isRigid()){
+      totelem += cdom->gMaster->size();
+      int pMaster = cdom->getTag();
+      for(int i=0;i<contactarch.size(); i++){
+        if(contactarch[i]._physmaster == pMaster){
+          rigidContactSpace *sp = dynamic_cast<rigidContactSpace*>(cdom->getSpace());
+          std::vector<Dof> R;
+          sp->getKeysOfGravityCenter(R);
+          for(int j=0;j<R.size(); j++)
+            if(contactarch[i]._fdof->operator()(R[j]))
+              varch.push_back(archiveNode(R[j],pMaster,contactarch[i]._wc));
+        }
+      }
+    }
+  }
+  this->setTotElem(totelem);
+}
diff --git a/NonLinearSolver/nlsolver/unknownField.h b/NonLinearSolver/nlsolver/unknownField.h
new file mode 100644
index 0000000000..93c510554d
--- /dev/null
+++ b/NonLinearSolver/nlsolver/unknownField.h
@@ -0,0 +1,64 @@
+//
+// C++ Interface: terms
+//
+// Description: Class with the displacement field
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef UNKNOWNFIELD_H_
+#define UNKNOWNFIELD_H_
+#include "dofManager.h"
+#include "PView.h"
+#include "PViewData.h"
+#include <stdint.h>
+#include <stdlib.h>
+#include "elementField.h"
+#include "nonLinearBC.h"
+#include "MInterfaceElement.h"
+class contactDomain;
+class elementField;
+struct archiveRigidContactDisp;
+struct archiveNode{
+  long int nodenum;
+  Dof D;
+  initialCondition::whichCondition wc;
+  archiveNode(Dof R, int n, initialCondition::whichCondition wv=initialCondition::position) : nodenum(n), D(R), wc(wv){}
+  ~archiveNode(){};
+
+};
+
+class unknownField : public elementField{
+ protected:
+  dofManager<double> *pAssembler; // To access to component of equation system template this
+  std::vector<Dof> fixedDof;
+  std::vector<archiveNode> varch;
+  std::vector<partDomain*> *domainVector;
+  std::set<contactDomain*> *_allContact;
+ public:
+  // update all displacement value
+  unknownField(dofManager<double> *pas, std::vector<partDomain*> &elas, std::set<contactDomain*> *acontact,
+                      const int nc, std::vector<std::pair<Dof,initialCondition::whichCondition> > &archiving,
+                      std::vector<archiveRigidContactDisp> &contactarch, const bool =true, const std::string="disp.msh");
+  ~unknownField(){}
+  virtual void update()=0;
+  virtual void updateFixedDof()=0;
+  // get Operation
+  virtual void get(Dof &D,double &udof) const=0;
+  virtual void get(std::vector<Dof> &R, std::vector<double> &disp) const=0;
+  virtual void get(std::vector<Dof> &R, fullVector<double> &disp) const=0;
+  virtual void get(partDomain *dom, MElement *ele,std::vector<double> &udofs, const int=-1)=0;
+  virtual void get(partDomain *dom, MElement *ele,fullVector<double> &udofs, const int=-1)=0;
+  virtual void get(partDomain *dom, MInterfaceElement* iele, std::vector<double> &udofs)=0;
+  virtual void get(partDomain *dom1, partDomain*dom2, MInterfaceElement* iele, std::vector<double> &udofs)=0;
+  virtual void get(FunctionSpaceBase *sp1,FunctionSpaceBase *sp2, MInterfaceElement *iele,std::vector<double> &udofs)=0;
+  virtual void archiving(const double time)=0;
+  virtual void setInitial(const std::vector<Dof> &R,const std::vector<double> &disp)=0;
+//  virtual void buildView(std::vector<partDomain*> &vdom,const double time,
+//                const int nstep, const std::string &valuename, const int cc,const bool binary);
+};
+#endif // _UNKNOWNFIELD_H_
diff --git a/NonLinearSolver/nlsolver/unknownStaticField.cpp b/NonLinearSolver/nlsolver/unknownStaticField.cpp
new file mode 100644
index 0000000000..934d5c95eb
--- /dev/null
+++ b/NonLinearSolver/nlsolver/unknownStaticField.cpp
@@ -0,0 +1,298 @@
+//
+// C++ Interface: terms
+//
+// Description: Class with the displacement field
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "unknownStaticField.h"
+#include "nonLinearMechSolver.h"
+#include "MPoint.h"
+unknownStaticField::unknownStaticField(dofManager<double> *pas, std::vector<partDomain*> &vdom, nonLinearMechSolver::contactContainer *acontact,
+                                     const int nc, std::vector<std::pair<Dof,initialCondition::whichCondition> > &archiving,
+                                     std::vector<archiveRigidContactDisp> &contactarch, const bool view_, const std::string filen
+                                                                         ) : unknownField(pas,vdom,acontact,nc,archiving,contactarch,view_,filen)
+{
+  // build umap
+  for(std::vector<partDomain*>::iterator itdom=vdom.begin(); itdom!=vdom.end(); ++itdom){
+    partDomain *dom = *itdom;
+    FunctionSpaceBase *sp = dom->getFunctionSpace();
+    std::vector<Dof> R;
+    for(groupOfElements::elementContainer::iterator it=dom->g->begin(); it!=dom->g->end(); ++it){
+      MElement *ele = *it;
+      sp->getKeys(ele,R);
+      for(int i=0;i<R.size(); i++)
+        umap.insert(std::pair<Dof,double>(R[i],0.));
+      R.clear();
+    }
+  }
+
+  // insert rigid contact Dof in umap
+  for(nonLinearMechSolver::contactContainer::iterator it = acontact->begin(); it!=acontact->end(); ++it){
+    contactDomain *cdom = *it;
+    if(cdom->isRigid()){
+      std::vector<Dof> R;
+      rigidContactSpace *sp = dynamic_cast<rigidContactSpace*>(cdom->getSpace());
+      sp->getKeysOfGravityCenter(R);
+      for(int i=0;i<R.size(); i++)
+        umap.insert(std::pair<Dof,double>(R[i],0.));
+    }
+  }
+
+  this->buildView(vdom,0.,0,"displacement",-1,false);
+}
+
+void unknownStaticField::update(){
+  double du;
+  for(std::vector<partDomain*>::iterator itdom = domainVector->begin(); itdom!=domainVector->end(); ++itdom){
+    partDomain *dom = *itdom;
+    FunctionSpaceBase *sp = dom->getFunctionSpace();
+    std::vector<Dof> R;
+    if(!(dom->getFormulation())){
+      for(groupOfElements::vertexContainer::iterator it=dom->g->vbegin(); it!=dom->g->vend(); ++it){
+        MVertex *ver = *it;
+        MPoint ele = MPoint(ver,-1); // We don't care about element number it's just to have the vertex keys
+        sp->getKeys(&ele,R);
+        for(int i=0;i<R.size();i++){
+          pAssembler->getDofValue(R[i],du);
+          bool in=false;
+          for(std::vector<Dof>::iterator itD=fixedDof.begin(); itD<fixedDof.end();++itD)
+            if(*itD==R[i]){in=true;break;}
+          if(in) umap[R[i]] = du;
+          else   umap[R[i]] +=du;
+        }
+        R.clear();
+      }
+    }
+    else{
+
+      for(groupOfElements::elementContainer::iterator it=dom->g->begin(); it!=dom->g->end(); ++it){
+        MElement *ele = *it;
+        sp->getKeys(ele,R);
+        for(int i=0;i<R.size();i++){
+          pAssembler->getDofValue(R[i],du);
+          bool in=false;
+          for(std::vector<Dof>::iterator itD=fixedDof.begin(); itD<fixedDof.end();++itD)
+            if(*itD==R[i]){in=true;break;}
+          if(in) umap[R[i]] = du;
+          else   umap[R[i]] +=du;
+        }
+        R.clear();
+      }
+    }
+  }
+}
+
+
+void unknownStaticField::get(Dof &D,double &udof) const{
+  udof = umap.find(D)->second;
+}
+
+void unknownStaticField::get(std::vector<Dof> &R, std::vector<double> &disp) const{
+  double du;
+  for(int i=0;i<R.size(); i++){
+    this->get(R[i],du);
+    disp.push_back(du);
+  }
+}
+
+void unknownStaticField::get(std::vector<Dof> &R, fullVector<double> &disp) const{
+  double du;
+  for(int i=0;i<R.size(); i++){
+    this->get(R[i],du);
+    disp(i) = du;
+  }
+}
+
+/*void unknownStaticField:get(MVertex *ver,std::vector<double> &udofs){
+  long int ent;
+  if(!fullDg){
+    ent = ver->getNum();
+    udofs = umap.find(ent)->second;
+  }
+  else{
+    Msg::Error("Impossible to get displacement by vertex for full Dg formulation. Work only with MElement");
+  }
+}*/
+
+void unknownStaticField::get(partDomain *dom, MElement *ele,std::vector<double> &udofs, const int cc){
+  std::vector<Dof> R;
+  FunctionSpaceBase *sp = dom->getFunctionSpace();
+  sp->getKeys(ele,R);
+  this->get(R,udofs);
+}
+
+void unknownStaticField::get(partDomain *dom, MElement *ele,fullVector<double> &udofs, const int cc){
+  std::vector<Dof> R;
+  FunctionSpaceBase *sp = dom->getFunctionSpace();
+  udofs.resize(sp->getNumKeys(ele));
+  sp->getKeys(ele,R);
+  this->get(R,udofs);
+}
+
+void unknownStaticField::get(partDomain *dom,MInterfaceElement* iele, std::vector<double> &udofs){
+  this->get(dom,iele->getElem(0),udofs);
+  if(!(iele->getElem(0)==iele->getElem(1))){// Virtual interface element
+    this->get(dom,iele->getElem(1),udofs);
+  }
+}
+
+void unknownStaticField::get(partDomain *dom1, partDomain *dom2,MInterfaceElement* iele, std::vector<double> &udofs){
+  this->get(dom1,iele->getElem(0),udofs);
+  if(!(iele->getElem(0)==iele->getElem(1))){// Virtual interface element
+    this->get(dom2,iele->getElem(1),udofs);
+  }
+}
+
+void unknownStaticField::get(FunctionSpaceBase *sp1, FunctionSpaceBase *sp2,MInterfaceElement* iele, std::vector<double> &udofs){
+  std::vector<Dof> R;
+  sp1->getKeys(iele->getElem(0),R);
+  this->get(R,udofs);
+  if(!(iele->getElem(0)==iele->getElem(1))){// Virtual interface element
+    R.clear();
+    sp2->getKeys(iele->getElem(1),R);
+    this->get(R,udofs);
+  }
+}
+
+/*void unknownStaticField:getForPerturbation(FunctionSpaceBase &sp, MInterfaceElement* iele, const bool minus, Dof &D, double pert, std::vector<double> &udofs){
+  double eps = -pert;
+  std::vector<Dof> R;
+  sp.getKeys(iele->getElem(0),R);
+  if(!minus){
+    this->set(D,eps);
+    this->get(R,udofs);
+    this->set(D,pert);
+  }
+  else{
+    this->get(R,udofs);
+    this->set(D,eps);
+  }
+  if(!(iele->getElem(0)==iele->getElem(1)))// Virtual interface element
+    R.clear();
+    sp.getKeys(iele->getElem(1),R);
+    this->get(R,udofs);
+  if(minus)
+    this->set(D,pert);
+}*/
+
+void unknownStaticField::updateFixedDof(){
+  double u;
+  for(std::vector<Dof>::iterator itD=fixedDof.begin(); itD<fixedDof.end();++itD){
+    pAssembler->getDofValue(*itD,u);
+    umap.find(*itD)->second=u;
+  }
+
+}
+void unknownStaticField::archiving(const double time){
+  FILE *fp;
+  double u;
+  for(std::vector<archiveNode>::iterator it = varch.begin(); it!=varch.end();++it){
+    Dof D = it->D;
+    this->get(D,u);
+    // write in File
+      std::ostringstream oss;
+      oss << it->nodenum;
+      std::string s = oss.str();
+      // component of displacement
+      int field,comp,num;
+      Dof3IntType::getThreeIntsFromType(it->D.getType(),comp,field,num);
+      oss.str("");
+      oss << comp;
+      std::string s2 = oss.str();
+      std::string fname = "NodalDisplacement"+s+"comp"+s2+".csv";
+      fp = fopen(fname.c_str(),"a");
+      fprintf(fp,"%e;%e\n",time,u);
+      fclose(fp);
+  }
+}
+
+void unknownStaticField::setInitial(const std::vector<Dof> &R, const std::vector<double> &disp){
+  for(int i=0;i<R.size();i++){
+    umap[R[i]] = disp[i];
+  }
+}
+
+/*
+void unknownField::buildView(std::vector<partDomain*> &vdom,const double time,
+                              const int nstep, const std::string &valuename, const int cc=-1, const bool binary=false){
+  if(view){
+    // test file size (and create a new one if needed)
+    uint32_t fileSize;
+    FILE *fp = fopen(fileName.c_str(), "r");
+    if(!fp){
+      Msg::Error("Unable to open file '%s'", fileName.c_str());
+      return;
+    }
+    fseek (fp, 0, SEEK_END);
+    fileSize = (uint32_t) (ftell(fp));
+    if(fileSize > fmaxsize) this->updateFileName();
+    fclose(fp);
+    fp = fopen(fileName.c_str(), "a");
+
+    // compute the number of element
+    if(binary) Msg::Warning("Binary write not implemented yet");
+    fprintf(fp, "$%s\n",dataname.c_str());
+    fprintf(fp, "1\n\"%s\"\n",valuename.c_str());
+    fprintf(fp, "1\n%.16g\n", time);
+    fprintf(fp, "3\n%d\n%d\n%d\n", nstep, numcomp, totelem);
+    std::vector<double> fieldData;
+    if(type == ElementNodeData){
+      for(std::vector<partDomain*>::iterator itdom=vdom.begin(); itdom!=vdom.end(); ++itdom){
+        partDomain *dom = *itdom;
+        for (groupOfElements::elementContainer::const_iterator it = dom->g->begin(); it != dom->g->end(); ++it){
+          MElement *ele = *it;
+          int numv = ele->getNumVertices();
+          this->get(dom,ele,fieldData,cc);
+          fprintf(fp, "%d %d",ele->getNum(),numv);
+          for(int i=0;i<numv;i++)
+            for(int j=0;j<numcomp;j++)
+              fprintf(fp, " %.16g",fieldData[i+j*numv]);
+          fprintf(fp,"\n");
+          fieldData.clear();
+        }
+      }
+      // loop on contact domain
+      for(nonLinearMechSolver::contactContainer::iterator it=_allContact->begin(); it!=_allContact->end(); ++it){
+        contactDomain *cdom = *it;
+        if(cdom->isRigid()){
+          for (groupOfElements::elementContainer::const_iterator it = cdom->gMaster->begin(); it != cdom->gMaster->end(); ++it){
+            MElement *ele = *it;
+            int numv = ele->getNumVertices();
+            rigidContactSpace *spgc = dynamic_cast<rigidContactSpace*>(cdom->getSpace());
+            std::vector<Dof> R;
+            spgc->getKeysOfGravityCenter(R);
+            this->get(R,fieldData);
+            fprintf(fp, "%d %d",ele->getNum(),numv);
+            for(int i=0;i<numv;i++)
+              for(int j=0;j<numcomp;j++)
+                fprintf(fp, " %.16g",fieldData[j]);
+            fprintf(fp,"\n");
+            fieldData.clear();
+          }
+        }
+      }
+    }
+    else if(type == ElementData){
+      for (unsigned int i = 0; i < vdom.size(); ++i)
+        for (groupOfElements::elementContainer::const_iterator it = vdom[i]->g->begin(); it != vdom[i]->g->end(); ++it){
+          MElement *ele = *it;
+          fieldData.resize(numcomp);
+          this->get(vdom[i],ele,fieldData,cc);
+          fprintf(fp, "%d",ele->getNum());
+          for(int j=0;j<numcomp;j++)
+            fprintf(fp, " %.16g",fieldData[j]);
+          fprintf(fp,"\n");
+        }
+    }
+    fprintf(fp, "$End%s\n",dataname.c_str());
+    fclose(fp);
+  }
+  else Msg::Warning("No displacement view created because the variable view is set to false for this field\n");
+}
+*/
diff --git a/NonLinearSolver/nlsolver/unknownStaticField.h b/NonLinearSolver/nlsolver/unknownStaticField.h
new file mode 100644
index 0000000000..8ac8d04544
--- /dev/null
+++ b/NonLinearSolver/nlsolver/unknownStaticField.h
@@ -0,0 +1,53 @@
+//
+// C++ Interface: terms
+//
+// Description: Class with the displacement field
+//
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef UNKNOWNSTATICFIELD_H_
+#define UNKNOWNSTATICFIELD_H_
+#include "dofManager.h"
+#include "PView.h"
+#include "PViewData.h"
+#include <stdint.h>
+#include <stdlib.h>
+#include "elementField.h"
+#include "contactDomain.h"
+
+class unknownStaticField : public unknownField{
+  protected :
+    std::map<Dof,double> umap; // One Entry by Dof allow to manage more than 1 domain
+  public :
+    unknownStaticField(dofManager<double> *pas, std::vector<partDomain*> &elas, std::set<contactDomain*> *acontact,
+                      const int nc, std::vector<std::pair<Dof,initialCondition::whichCondition> > &archiving,
+                      std::vector<archiveRigidContactDisp> &contactarch, const bool =true, const std::string="disp.msh"
+                                                    ) ;
+    // update all displacement value
+    virtual void update();
+    virtual void updateFixedDof();
+    // get Operation
+    virtual void get(Dof &D,double &udof) const;
+    virtual void get(std::vector<Dof> &R, std::vector<double> &disp) const;
+    virtual void get(std::vector<Dof> &R, fullVector<double> &disp) const;
+//    virtual void get(MVertex *ver,std::vector<double> &udofs); // works only for cG/dG (TODO fullDg case)
+    virtual void get(partDomain *dom, MElement *ele,std::vector<double> &udofs, const int=-1);
+    virtual void get(partDomain *dom, MElement *ele,fullVector<double> &udofs, const int=-1);
+    virtual void get(partDomain *dom, MInterfaceElement* iele, std::vector<double> &udofs);
+    virtual void get(partDomain *dom1, partDomain*dom2, MInterfaceElement* iele, std::vector<double> &udofs);
+    virtual void get(FunctionSpaceBase *sp1,FunctionSpaceBase *sp2, MInterfaceElement *iele,std::vector<double> &udofs);
+    virtual void set(Dof &D, double &val){
+      umap[D] += val;
+    }
+//    virtual void getForPerturbation(FunctionSpaceBase &sp,MInterfaceElement* iele, const bool minus, Dof &D, double pert, std::vector<double> &udofs);
+    virtual void archiving(const double time);
+    virtual void setInitial(const std::vector<Dof> &R,const std::vector<double> &disp);
+//    virtual void buildView(std::vector<partDomain*> &vdom,const double time,
+//                  const int nstep, const std::string &valuename, const int cc,const bool binary);
+};
+#endif // DISPLACEMENTFIELD_H_
diff --git a/NonLinearSolver/space/CMakeLists.txt b/NonLinearSolver/space/CMakeLists.txt
new file mode 100644
index 0000000000..4e6e8449eb
--- /dev/null
+++ b/NonLinearSolver/space/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Gmsh - Copyright (C) 1997-2010 C. Geuzaine, J.-F. Remacle
+#
+# See the LICENSE.txt file for license information. Please report all
+# bugs and problems to <gmsh@geuz.org>.
+
+set(SRC
+  functionSpaceType.h
+)
+
+file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) 
+append_gmsh_src(NonLinearSolver/space "${SRC};${HDR}")
diff --git a/NonLinearSolver/space/functionSpaceType.h b/NonLinearSolver/space/functionSpaceType.h
new file mode 100644
index 0000000000..c0f8448eeb
--- /dev/null
+++ b/NonLinearSolver/space/functionSpaceType.h
@@ -0,0 +1,22 @@
+//
+// group for interface element
+//
+// Description: Choose a function space. Can be integrated in functionSpace.h
+//
+// Author:  <Gauthier BECKER>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef FUNCTIONSPACETYPE_H_
+#define FUNCTIONSPACETYPE_H_
+// Enum that allow to choose a function space
+class functionSpaceType{
+ public :
+  // To chosen the space type
+  enum whichSpace{Lagrange, Inter};
+  functionSpaceType(){};
+  ~functionSpaceType(){}; // rewrite to delete object
+};
+#endif // FUNCTIONSPACETYPE_H_
diff --git a/Numeric/simpleFunction.h b/Numeric/simpleFunction.h
index c833015189..883f717603 100644
--- a/Numeric/simpleFunction.h
+++ b/Numeric/simpleFunction.h
@@ -11,6 +11,7 @@
 
 template <class scalar>
 class simpleFunction {
+ protected:
   scalar _val;
  public :
   simpleFunction(scalar val=0.0) : _val(val) {}
diff --git a/Solver/quadratureRules.h b/Solver/quadratureRules.h
index 880bfbb37f..fbcc755317 100644
--- a/Solver/quadratureRules.h
+++ b/Solver/quadratureRules.h
@@ -24,6 +24,16 @@ class QuadratureBase
   virtual int getIntPoints(MElement *e, IntPt **GP) =0;
 };
 
+// For rigid contact no need of Gauss'integration
+// but to use classcal get function in term npts and IntPt are needed
+// so use a empty gaussQuadrature rule
+class QuadratureVoid : public QuadratureBase
+{
+ public:
+  QuadratureVoid() : QuadratureBase(){}
+  ~QuadratureVoid(){}
+  int getIntPoints(MElement *e, IntPt **GP){GP=NULL; return 0;}
+} ;
 
 class GaussQuadrature : public QuadratureBase
 {
@@ -36,7 +46,7 @@ class GaussQuadrature : public QuadratureBase
   GaussQuadrature(int order_ = 0) : order(order_), info(Other) {}
   GaussQuadrature(IntegCases info_) : order(0), info(info_) {}
   virtual ~GaussQuadrature(){}
-  int getIntPoints(MElement *e, IntPt **GP)
+  virtual int getIntPoints(MElement *e, IntPt **GP)
   {
     int integrationOrder;
     int npts;
@@ -65,5 +75,4 @@ class GaussQuadrature : public QuadratureBase
   }
 };
 
-
 #endif //_QUADRATURERULES_H_
diff --git a/Solver/terms.h b/Solver/terms.h
index e3540ec8ee..4721f09014 100644
--- a/Solver/terms.h
+++ b/Solver/terms.h
@@ -65,7 +65,7 @@ public :
   ScalarTermConstant(T2 val_ = T2()) : cst(val_) {}
   virtual ~ScalarTermConstant() {}
   virtual void get(MElement *ele, int npts, IntPt *GP, T2 &val) const;
-  virtual void get(MElement *ele, int npts, IntPt *GP, std::vector<T2> &vval) const;  
+  virtual void get(MElement *ele, int npts, IntPt *GP, std::vector<T2> &vval) const;
   virtual void get(MVertex *ver, T2 &val) const;
   virtual ScalarTermBase<T2>* clone () const {return new ScalarTermConstant<T2>(cst);}
 };
@@ -259,7 +259,7 @@ public :
   }
   virtual ~LagrangeMultiplierTerm() {}
   virtual void get(MElement *ele, int npts, IntPt *GP, fullMatrix<double> &m) const;
-  virtual void get(MElement *ele, int npts, IntPt *GP, std::vector< fullMatrix<double> > &vm) const{};  
+  virtual void get(MElement *ele, int npts, IntPt *GP, std::vector< fullMatrix<double> > &vm) const{};
   virtual BilinearTermBase* clone () const {return new LagrangeMultiplierTerm(BilinearTerm<SVector3, double>::space1,BilinearTerm<SVector3, double>::space2,_d);}
 };
 
-- 
GitLab