diff --git a/srcs/FEM/complex_validation.geo b/srcs/FEM/complex_validation.geo
index 47e62fe7faf89f96039b9b0497e4db00896d6c36..2c7851a8f2a460fc47db4ba3bc424a65a27e20be 100644
--- a/srcs/FEM/complex_validation.geo
+++ b/srcs/FEM/complex_validation.geo
@@ -2,10 +2,10 @@
 
 Lx = 5;
 Ly = 2;
-nx = 50;
-ny = 20;
+nx = 250;
+ny = 100;
 
-Point(1) = {0, 0, 0, 0.1};
+Point(1) = {0, 0, 0, 0.1}; //4th number is mesh density
 Point(2) = {Lx, 0, 0, 0.2};
 Point(3) = {Lx, Ly, 0, 0.2};
 Point(4) = {0, Ly, 0, 0.1};
@@ -52,6 +52,8 @@ SetNumber("Boundary Conditions/right_edge/tx", 21e3); //for simple tension condi
 SetNumber("Boundary Conditions/right_edge/ty", 0.);
 SetNumber("Volumic Forces/FEM_domain/bx",0.);
 SetNumber("Volumic Forces/FEM_domain/by",0.); //set to -9.81 for gravity
-SetNumber("Boundary Conditions/fixed_node/uy",0.);
+SetNumber("Boundary Conditions/fixed_node/uy",2);
 
 Physical Curve("BEM_FEM_boundary", 10) = {1,2,3,4,5,6};
+
+SetNumber("Non_linear_solver", 1);
\ No newline at end of file
diff --git a/srcs/FEM/functionsFEM.cpp b/srcs/FEM/functionsFEM.cpp
index 27ec51c66f0290e3b5486ea01358e326146865f2..e6cb0bde065691b4898abcfb4dcad297221b1d84 100644
--- a/srcs/FEM/functionsFEM.cpp
+++ b/srcs/FEM/functionsFEM.cpp
@@ -20,6 +20,30 @@
 #endif
 #define PI M_PI
 
+bool getNonLinearParameter()
+{
+    std::vector<std::string> keys;
+    gmsh::onelab::getNames(keys, "Non_linear_solver");
+    if(keys.size())
+    {
+        std::vector<double> value;
+        gmsh::onelab::getNumber(keys[0], value);
+        if(value[0])
+        {
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+    else
+    {
+        std::cout << "you did not choose the type of solver (linear or not) in the .geo file, 'SetNumber('Non_linear_solver',x);'. Automatically set to non linear type \n";
+        return true;
+    }
+}
+
 //Compute the matrix H
 Eigen::Matrix<double, 3, 3> computeHmatrix(const double E, const double nu)
 {
@@ -572,8 +596,6 @@ void computeStressStrainElNodal(int & dim, std::vector<int> & tags,
 
         elementData* element;
         double theta;
-        //double dN_dx_local;
-        //double dN_dy_local;
 
         Eigen::Matrix<double, 2, 2> strain_tensor;
         Eigen::Matrix<double, 2, 2> stress_tensor;
diff --git a/srcs/FEM/functionsFEM.hpp b/srcs/FEM/functionsFEM.hpp
index 7c162cfa64d4c089fb811350dd3e09de44de560b..4572228eb2bb786d47ea61f12e49f5f2dd2ed86f 100644
--- a/srcs/FEM/functionsFEM.hpp
+++ b/srcs/FEM/functionsFEM.hpp
@@ -41,6 +41,7 @@ struct elementData{
     Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> B;
 };
 
+bool getNonLinearParameter();
 Eigen::Matrix<double, 3, 3> computeHmatrix(const double E, const double nu);
 void assembleFlocal(const int &i, const int &el, const std::vector<std::vector<std::size_t>> & nodeTags, const int &numNodes, std::map<int, int> & nodeIndexMap, std::vector<double> & full_f_vector, std::vector<double> & f_vector);
 void computeBmatrix(const int &j, const int &numNodes, const std::vector<double> & basisFunctionsGradient, const std::vector<double> & determinants, const Eigen::Matrix<double, 2, 2> & jacobinvtrans, Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> & B_matrix);
diff --git a/srcs/FEM/large_rotation_validation.geo b/srcs/FEM/large_rotation_validation.geo
index d10805c5adbfd18f62b5b180e270b426f6e8bfef..f2bcf8057a4af3a6fe7e181587a90ccd4f1aaebc 100644
--- a/srcs/FEM/large_rotation_validation.geo
+++ b/srcs/FEM/large_rotation_validation.geo
@@ -2,19 +2,23 @@
 h = 1;
 H = 10;
 
-n = 20;
+n = 48;
 
 Point(1) = {0, 0, 0, 0.5};
 Point(2) = {0.9*H, 0, 0, 0.5};
 Point(3) = {0.9*H, h, 0, 0.5};
 Point(4) = {0, h, 0, 0.5};
 
-Point(5) = {H, 0, 0, 0.5};
-Point(6) = {H, h, 0, 0.5};
+Point(5) = {0.95*H, 0, 0, 0.5};
+Point(6) = {0.95*H, h, 0, 0.5};
 
-Point(7) = {H, H, 0, 0.5};
+Point(7) = {0.95*H, H, 0, 0.5};
 Point(8) = {0.9*H, H, 0, 0.5};
 
+Point(9) = {H, 0, 0, 0.5};
+Point(10) = {H, h, 0, 0.5};
+Point(11) = {H, H, 0, 0.5};
+
 Line(1) = {1, 2};
 Line(2) = {2, 3};
 Line(3) = {3, 4};
@@ -34,21 +38,39 @@ Line(10) = {8, 3};
 Curve Loop(3) = {-7, 8, 9, 10};
 Plane Surface(3) = {3};
 
-Transfinite Curve {1, 3, 8, 10} = 9*n+1 Using Progression 1;
-Transfinite Curve {2, 4, 5, 6, 7, 9} = n+1 Using Progression 1;
+Line(11) = {5, 9};
+Line(12) = {9, 10};
+Line(13) = {10, 6};
+Curve Loop(4) = {11, 12, 13, -6};
+Plane Surface(4) = {4};
+
+Line(14) = {10, 11};
+Line(15) = {11, 7};
+Curve Loop(5) = {14, 15, -8, -13};
+Plane Surface(5) = {5};
+
+Transfinite Curve {1, 3, 8, 10, 14} = 18*n+1 Using Progression 1;
+Transfinite Curve {2, 4, 6, 12} = 2*n+1 Using Progression 1;
+Transfinite Curve {5, 7, 9, 11, 13, 15} = n+1 Using Progression 1;
 Transfinite Surface {1};
 Transfinite Surface {2};
 Transfinite Surface {3};
+Transfinite Surface {4};
+Transfinite Surface {5};
 
 Recombine Surface {1};
 Recombine Surface {2};
 Recombine Surface {3};
+Recombine Surface {4};
+Recombine Surface {5};
 
 Physical Curve("left_edge", 1) = {4};
-Physical Surface("FEM_domain", 2) = {1, 2, 3}; // the trick is to include both plane surfaces in one single domain
-Physical Curve("top_edge", 3) = {9};
+Physical Surface("FEM_domain", 2) = {1, 2, 3, 4, 5}; // the trick is to include both plane surfaces in one single domain
+Physical Curve("top_edge", 3) = {9, 15};
 
-F = 500;
+Physical Point("point_A", 5) = {7};
+
+F = 40000;
 
 // additional parameters given to the solver
 SetNumber("Boundary Conditions/left_edge/ux", 0.); // ALWAYS NEED TO IMPOSE BOTH ux AND uy ON A GIVEN EDGE !! (pas très réaliste, faut y réfléchir)
@@ -61,4 +83,6 @@ SetNumber("Boundary Conditions/top_edge/ty", 0); //set to some other value for v
 SetNumber("Volumic Forces/FEM_domain/bx",0.);
 SetNumber("Volumic Forces/FEM_domain/by",0.); //set to -9.81 for gravity
 
+SetNumber("Non_linear_solver",1); // activate non linear solver
+
 Physical Curve("BEM_FEM_boundary", 4) = {4};
\ No newline at end of file
diff --git a/srcs/FEM/mainFEM.cpp b/srcs/FEM/mainFEM.cpp
index 00beeaab76d93e3887b078e0a836bc941ec46e7e..02b644c7b50b97264c33f519de48f169856dcb0d 100644
--- a/srcs/FEM/mainFEM.cpp
+++ b/srcs/FEM/mainFEM.cpp
@@ -6,9 +6,6 @@
 
 int main(int argc, char **argv)
 {
-
-    bool nonLinearSolver = true; // use non-linear solver or not
-
     if (argc < 2)
     {
         std::cout << "Usage: " << argv[0] << " <geo_file>\n";
@@ -28,6 +25,9 @@ int main(int argc, char **argv)
 
     Eigen::initParallel();
 
+    // determine if non linear solver must be set
+    bool nonLinearSolver = getNonLinearParameter(); 
+
     std::map<int, double> electrostaticPressure;
 
     int nbViews = 0;
diff --git a/srcs/FEM/my_geo.geo b/srcs/FEM/my_geo.geo
index 5c0005f48a4cc907279bccaf78d0ca08318e49da..fde90809eae403a3dd4574e691689a4ee1ed5da6 100644
--- a/srcs/FEM/my_geo.geo
+++ b/srcs/FEM/my_geo.geo
@@ -1,7 +1,7 @@
 Lx = 2;
 Ly = 1;
-nx = 2; // prend beaucoup de temps àpd de 200x40
-ny = 1;
+nx = 16; // prend beaucoup de temps àpd de 200x40
+ny = 8;
 
 Point(1) = {0, 0, 0, 0.1};
 Point(2) = {Lx, 0, 0, 0.1};
@@ -21,7 +21,7 @@ Recombine Surface {1}; // quads instead of triangles
 
 Mesh.ElementOrder = 1;
 
-Physical Curve("left_edge", 5) = {4,5};
+Physical Curve("left_edge", 5) = {4};
 Physical Surface("FEM_domain", 6) = {1};
 Physical Curve("top_edge", 7) = {3};
 Physical Curve("right_edge", 8) = {2};
@@ -29,17 +29,17 @@ Physical Point("fixed_node", 9) = {1};
 
 // additional parameters given to the solver
 SetNumber("Boundary Conditions/left_edge/ux", 0.); // HERE YOU DO NOT HAVE TO IMPOSE BOTH ux and uy simultaneously ! (permet aussi de simuler appuis à roulettes)
-SetNumber("Boundary Conditions/left_edge/uy", 0.);
+//SetNumber("Boundary Conditions/left_edge/uy", 0.);
 SetNumber("Materials/FEM_domain/Young", 210e3);
 SetNumber("Materials/FEM_domain/Poisson", 0.3);
 SetNumber("Materials/FEM_domain/rho",7800); //volumic mass of acier
 SetNumber("Boundary Conditions/top_edge/tx", 0.); // ALWAYS NEED TO IMPOSE BOTH tx AND ty ON A GIVEN EDGE (realiste, OK) !
 SetNumber("Boundary Conditions/top_edge/ty", 0.); //set to some non-zero value to induce vertical deflection
-SetNumber("Boundary Conditions/right_edge/tx", 40); // for simple tension conditions
+SetNumber("Boundary Conditions/right_edge/tx", 21e3); // for simple tension conditions
 SetNumber("Boundary Conditions/right_edge/ty", 0);
 SetNumber("Volumic Forces/FEM_domain/bx",0);
 SetNumber("Volumic Forces/FEM_domain/by",0.); //set to -9.81 for gravity
 //SetNumber("Boundary Conditions/fixed_node/ux",0.);
-//SetNumber("Boundary Conditions/fixed_node/uy",0.);
+SetNumber("Boundary Conditions/fixed_node/uy",2.);
 
 Physical Curve("BEM_FEM_boundary", 10) = {1,2,3};
\ No newline at end of file
diff --git a/srcs/FEM/self_weight.geo b/srcs/FEM/self_weight.geo
index d50925376b3a42a31e2508c7fa480d9ccdfba644..c04a6a8a44f4dd0dc62137b00f36ea44a94cd666 100644
--- a/srcs/FEM/self_weight.geo
+++ b/srcs/FEM/self_weight.geo
@@ -37,4 +37,6 @@ SetNumber("Boundary Conditions/right_edge/ty", 0.);
 SetNumber("Volumic Forces/FEM_domain/bx",0.);
 SetNumber("Volumic Forces/FEM_domain/by",-9.81); //set to -9.81 for gravity
 
-Physical Curve("BEM_FEM_boundary", 9) = {1,2,3}; // useless but necessary to make it work
\ No newline at end of file
+Physical Curve("BEM_FEM_boundary", 9) = {1,2,3}; // useless but necessary to make it work
+
+SetNumber("Non_linear_solver", 1);
\ No newline at end of file
diff --git a/srcs/FEM/simple_tension.geo b/srcs/FEM/simple_tension.geo
index 18783ae0b69b461a559836c84cbd892676cec6a4..f1452e518608936d6c4b17101e93a32c0f296abd 100644
--- a/srcs/FEM/simple_tension.geo
+++ b/srcs/FEM/simple_tension.geo
@@ -1,7 +1,7 @@
 Lx = 5;
 Ly = 2;
-nx = 5;
-ny = 2;
+nx = 50;
+ny = 20;
 
 Point(1) = {0, 0, 0, 1.0};
 Point(2) = {Lx, 0, 0, 1.0};
@@ -39,6 +39,8 @@ SetNumber("Boundary Conditions/right_edge/tx", 21e3); // for simple tension cond
 SetNumber("Boundary Conditions/right_edge/ty", 0.);
 SetNumber("Volumic Forces/FEM_domain/bx",0.);
 SetNumber("Volumic Forces/FEM_domain/by",0.); //set to -9.81 for gravity
-SetNumber("Boundary Conditions/fixed_node/uy",0.);
+SetNumber("Boundary Conditions/fixed_node/uy",2.);
 
 Physical Curve("BEM_FEM_boundary", 10) = {1,2,3}; // useless in this case but necessary to make it work
+
+SetNumber("Non_linear_solver",1);
\ No newline at end of file
diff --git a/srcs/FEM/solverFEM.cpp b/srcs/FEM/solverFEM.cpp
index 770715a40ae1e3bb34fd00708b8ade10787d0626..05eb54d07ea8f3b8876a329b8d072da8e46c4d43 100644
--- a/srcs/FEM/solverFEM.cpp
+++ b/srcs/FEM/solverFEM.cpp
@@ -27,6 +27,7 @@ void solverFEMnonLinear(std::map<int, double> &electrostaticPressure, std::map<i
     - important remark: in pg we focus only on the free DOFs (we do not focus on the DOFs fixed by dirichlet BCs)*/
 
     bool display_time = false;
+    bool validation = false;
 
     double start = omp_get_wtime();
     //int max_threads = omp_get_max_threads();
@@ -217,13 +218,14 @@ void solverFEMnonLinear(std::map<int, double> &electrostaticPressure, std::map<i
 
     Eigen::Matrix<double, Eigen::Dynamic, 1> residual(nb_free_DOFs, 1);
 
-    double residualTolerance = 1e-11; // empirical
+    double residualTolerance = 1e-12; // empirical
 
     // implementation of second stopping criterion
     std::vector<double> previousTotalNodalForces(2*FEM_nodeTags.size());
     std::vector<double> currentTotalNodalForces(2*FEM_nodeTags.size());
     std::vector<double> relativeDifference(2*FEM_nodeTags.size());
     double relativeForces = 1e17;
+    double previousRelativeForces = 1e17;
     double currentMaxNodalForce;
     for(size_t i = 0; i < 2*FEM_nodeTags.size(); i++)
     {
@@ -237,8 +239,12 @@ void solverFEMnonLinear(std::map<int, double> &electrostaticPressure, std::map<i
 
 
     /*---------ITERATIVE PART---------------*/
-    int max_number_of_steps = 50; // purely arbitrary
-    for(int step = 0; step < max_number_of_steps; step++)
+    int max_number_of_steps = 200; // purely arbitrary
+    int step = 0;
+
+    double num_diverged_steps = 0; // stores the number of times the residual has increased between two steps, after 5 times,
+    // we take the assumption it has converged towards an other value
+    for(step = 0; step < max_number_of_steps; step++)
     {
         /*------------STEP 2 of the algorithm----------------*/
         /* 
@@ -266,6 +272,7 @@ void solverFEMnonLinear(std::map<int, double> &electrostaticPressure, std::map<i
 
         if(step > 1)
         {
+            previousRelativeForces = relativeForces;
             relativeForces = 0;
             currentMaxNodalForce = 0;
             for(size_t i = 0; i < 2*FEM_nodeTags.size(); i++)
@@ -285,6 +292,16 @@ void solverFEMnonLinear(std::map<int, double> &electrostaticPressure, std::map<i
             else
                 relativeForces = 1e17;
             std::cout << "step: " << step << ", relativeForces: " << relativeForces << "\n";
+
+            if(previousRelativeForces < relativeForces)
+            {
+                num_diverged_steps++;
+                if(num_diverged_steps == 5)
+                {
+                    std::cout << "-----------------------------------------\n";
+                    std::cout << "Pay attention, the differential residual has not reached the tolerance of " << residualTolerance << ", it has converged towards: " << relativeForces << ", after " << step <<" steps\n";
+                }
+            }
         }
 
 
@@ -303,7 +320,7 @@ void solverFEMnonLinear(std::map<int, double> &electrostaticPressure, std::map<i
         displayTime(end_retrieveTotalForces, end_assembleglobalf, step_name, display_time);
 
         /*------------STEP 3: EVALUATING THE RESIDUAL, have we converged ??----------*/
-        if (relativeForces < residualTolerance && step > 0)
+        if ((relativeForces < residualTolerance && step > 0) || num_diverged_steps == 5)
            break;
 
         /*------------STEP 4: ASSEMBLING THE GLOBAL TANGENT STIFFNESS MATRIX----------*/
@@ -342,6 +359,12 @@ void solverFEMnonLinear(std::map<int, double> &electrostaticPressure, std::map<i
         displayTime(end_solve, end_updateNodalDisp, step_name, display_time);
     }
 
+    if(step == max_number_of_steps)
+    {
+        std::cout << "-----------------------------------------\n";
+        std::cout << "Pay attention, the differential residual has not reached the tolerance of " << residualTolerance << ", final value: " << relativeForces << "\n";
+    }
+
     double start_postPro = omp_get_wtime();
     
     //updating the kinematics according to the results of last iteration
@@ -522,6 +545,22 @@ void solverFEMnonLinear(std::map<int, double> &electrostaticPressure, std::map<i
             gmsh::model::mesh::setNode(FEM_nodeTags[i], total_disp, {});
         }
     }
+
+    if(validation)
+    {
+        // point A
+        std::string groupname = "point_A"; // we consider the domain as containing the FEM 2d model
+        int dim = groups[groupname].first;
+        int tag = groups[groupname].second;
+        std::vector<int> tags;
+        gmsh::model::getEntitiesForPhysicalGroup(dim, tag, tags);
+        std::vector<std::size_t> A_nodeTag;
+        std::vector<double> A_nodecoord;
+        std::vector<double> A_nodeparametricCoord;
+        gmsh::model::mesh::getNodes(A_nodeTag, A_nodecoord, A_nodeparametricCoord, dim, tags[0], true); 
+        std::cout << "-----------------------------------------\n";
+        std::cout << "point A displacement: u = " << full_d_vector[nodeIndexMap[A_nodeTag[0]]] << ", v = " << full_d_vector[nodeIndexMap[A_nodeTag[0]] + 1] << "\n";
+    }
 }
 
 
diff --git a/srcs/FEM/uniform_charge.geo b/srcs/FEM/uniform_charge.geo
index 1b19a8ee9cef22b003fa155be8fb51442f9bf7ea..930e4410c83958dd777d5c1f19e42af13acb4e13 100644
--- a/srcs/FEM/uniform_charge.geo
+++ b/srcs/FEM/uniform_charge.geo
@@ -38,3 +38,5 @@ SetNumber("Volumic Forces/FEM_domain/bx",0.);
 SetNumber("Volumic Forces/FEM_domain/by",0.); //set to -9.81 for gravity
 
 Physical Curve("BEM_FEM_boundary", 9) = {1,2,3};
+
+SetNumber("Non_linear_solver", 1);
\ No newline at end of file
diff --git a/srcs/clampedMicroBeam.geo b/srcs/clampedMicroBeam.geo
index da4f0c45e65e7e57f358781ba04573d3d516dc7f..ddbf181966070c65ed1c270d4ec0db1718712afa 100644
--- a/srcs/clampedMicroBeam.geo
+++ b/srcs/clampedMicroBeam.geo
@@ -73,11 +73,13 @@ SetNumber("Volumic Forces/FEM_domain/bx",0.);
 SetNumber("Volumic Forces/FEM_domain/by",0.); //set to -9.81 for gravity
 //SetNumber("Boundary Conditions/fixed_node/uy",2.);
 
+SetNumber("Non_linear_solver",1);
+
 // BEM geometry
 Physical Curve("BEM_FEM_boundary", 11) = {1,2,3};
 Physical Curve("mass", 12) = {10}; //lower electrode
 Physical Curve("rest_of_outside", 13) = {5,6,7,8,9};
-phi_top = 35; 
+phi_top = 35.5; 
 SetNumber("Boundary Conditions/mass/BEM_domain_1/dirichlet", 0);
 SetNumber("Boundary Conditions/BEM_FEM_boundary/BEM_domain_1/dirichlet", phi_top);
 SetNumber("Boundary Conditions/rest_of_outside/BEM_domain_1/neumann", 0);
diff --git a/srcs/coupling_validation.geo b/srcs/coupling_validation.geo
index 6a558ca2be560a6d4f8aa23e2baf8e43dad0150b..e5510d1e2ee35de5eebe1b186d0f0be9839fefe1 100644
--- a/srcs/coupling_validation.geo
+++ b/srcs/coupling_validation.geo
@@ -60,4 +60,6 @@ phi = 30;
 SetNumber("Boundary Conditions/right_BEM/BEM_domain_1/dirichlet", 0);
 SetNumber("Boundary Conditions/BEM_FEM_boundary/BEM_domain_1/dirichlet", phi);
 SetNumber("Boundary Conditions/homogeneous_field/BEM_domain_1/neumann", 0);
-SetNumber("Materials/BEM_domain_1/Epsilon", 8.8541878128e-12); // dielectric permittivity
\ No newline at end of file
+SetNumber("Materials/BEM_domain_1/Epsilon", 8.8541878128e-12); // dielectric permittivity
+
+SetNumber("Non_linear_solver", 0);
\ No newline at end of file
diff --git a/srcs/longitudinal_comb.geo b/srcs/longitudinal_comb.geo
index 35aec87e3c670ffb3d33f36eee98cd9429209f66..6c89eec081168abdcadd2fbd9403a00c051875fd 100644
--- a/srcs/longitudinal_comb.geo
+++ b/srcs/longitudinal_comb.geo
@@ -141,4 +141,7 @@ phi_2 = 25;
 SetNumber("Boundary Conditions/BEM_FEM_boundary_2/BEM_domain_2/dirichlet", 0);
 SetNumber("Boundary Conditions/electrode_2/BEM_domain_2/dirichlet", phi_2);
 SetNumber("Boundary Conditions/outside_2/BEM_domain_2/neumann", 0);
-SetNumber("Materials/BEM_domain_2/Epsilon", 8.8541878128e-12); // dielectric permittivity
\ No newline at end of file
+SetNumber("Materials/BEM_domain_2/Epsilon", 8.8541878128e-12); // dielectric permittivity
+
+
+Mesh.Algorithm = 8;
\ No newline at end of file
diff --git a/srcs/main.cpp b/srcs/main.cpp
index 711679cf5aff5fae0f0ea2453b7b057baf4948d9..90b59b98a2b0a7e9c02385c2057e14ed35a6be14 100644
--- a/srcs/main.cpp
+++ b/srcs/main.cpp
@@ -13,7 +13,6 @@ int main(int argc, char **argv)
         return 0;
     }
 
-    bool nonLinearSolver = true; // use non-linear solver or not -> SET AS AN ARGUMENT OF MAIN, much easier
     bool untangleMesh = false; // untangle geometry (deformed geometry, only available for nonLinear)
 
     // If compiled with OpenMP support, gmsh::initialize 
@@ -28,6 +27,9 @@ int main(int argc, char **argv)
 
     Eigen::initParallel();
 
+    // determine if non linear solver must be set
+    bool nonLinearSolver = getNonLinearParameter(); 
+
     if(nonLinearSolver)
     {