diff --git a/src/scheme/ScalarNodalScheme.cpp b/src/scheme/ScalarNodalScheme.cpp
index 06fe956c09ea9e03fddb41a9abf6e5c170e5f4e6..9367249f71b20a049156aee7557d5c35cb48a736 100644
--- a/src/scheme/ScalarNodalScheme.cpp
+++ b/src/scheme/ScalarNodalScheme.cpp
@@ -386,8 +386,20 @@ class ScalarNodalSchemeHandler::ScalarNodalScheme : public ScalarNodalSchemeHand
               const unsigned int i_node = node_local_number_in_its_cell[i_cell];
               const CellId cell_id      = node_to_cell[i_cell];
               const auto& cell_nodes    = cell_to_node_matrix[cell_id];
-              const NodeId prev_node_id = cell_to_node_matrix[cell_id][(i_node - 1) % cell_nodes.size()];
-              const NodeId next_node_id = cell_to_node_matrix[cell_id][(i_node + 1) % cell_nodes.size()];
+              NodeId i_node_prev;
+              NodeId i_node_next;
+              if (i_node == 0) {
+                i_node_prev = cell_nodes.size() - 1;
+              } else {
+                i_node_prev = i_node - 1;
+              }
+              if (i_node == cell_nodes.size() - 1) {
+                i_node_next = 0;
+              } else {
+                i_node_next = i_node + 1;
+              }
+              const NodeId prev_node_id = cell_to_node_matrix[cell_id][i_node_prev];
+              const NodeId next_node_id = cell_to_node_matrix[cell_id][i_node_next];
               if (is_boundary_node[prev_node_id] and is_boundary_node[next_node_id]) {
                 compute_node_is_corner[node_id] = true;
               }
@@ -411,6 +423,7 @@ class ScalarNodalSchemeHandler::ScalarNodalScheme : public ScalarNodalSchemeHand
           }
           const double norm_exterior_normal = l2Norm(compute_exterior_normal[node_id]);
           compute_exterior_normal[node_id] *= 1. / norm_exterior_normal;
+          // std::cout << node_id << "  " << compute_exterior_normal[node_id] << "\n";
         }
       }
       return compute_exterior_normal;
@@ -451,7 +464,6 @@ class ScalarNodalSchemeHandler::ScalarNodalScheme : public ScalarNodalSchemeHand
                   }
                 }
               }
-
             } else if constexpr (std::is_same_v<T, DirichletBoundaryCondition>) {
               const auto& face_list  = bc.faceList();
               const auto& value_list = bc.valueList();
@@ -480,6 +492,7 @@ class ScalarNodalSchemeHandler::ScalarNodalScheme : public ScalarNodalSchemeHand
         } else if ((not node_is_neumann[node_id]) && (node_is_dirichlet[node_id])) {
           compute_node_boundary_values[node_id] /= sum_mes_l[node_id];
         }
+        // std::cout << node_id << "  " << compute_node_boundary_values[node_id] << "\n";
       }
       return compute_node_boundary_values;
     }();
@@ -709,15 +722,17 @@ class ScalarNodalSchemeHandler::ScalarNodalScheme : public ScalarNodalSchemeHand
       }();
 
       const Array<int> non_zeros{mesh->numberOfCells()};
-      non_zeros.fill(Dimension);   // Modif pour optimiser
-      CRSMatrixDescriptor<double> S(mesh->numberOfCells(), mesh->numberOfCells(), non_zeros);
+      non_zeros.fill(4);   // Modif pour optimiser
+      CRSMatrixDescriptor<double> S1(mesh->numberOfCells(), mesh->numberOfCells(), non_zeros);
+      CRSMatrixDescriptor<double> S2(mesh->numberOfCells(), mesh->numberOfCells(), non_zeros);
       for (NodeId node_id = 0; node_id < mesh->numberOfNodes(); ++node_id) {
         const auto& node_to_cell = node_to_cell_matrix[node_id];
         for (size_t i_cell_j = 0; i_cell_j < node_to_cell.size(); ++i_cell_j) {
           const CellId cell_id_j = node_to_cell[i_cell_j];
           for (size_t i_cell_k = 0; i_cell_k < node_to_cell.size(); ++i_cell_k) {
-            const CellId cell_id_k  = node_to_cell[i_cell_k];
-            S(cell_id_j, cell_id_k) = 0;
+            const CellId cell_id_k   = node_to_cell[i_cell_k];
+            S1(cell_id_j, cell_id_k) = 0;
+            S2(cell_id_j, cell_id_k) = 0;
           }
         }
       }
@@ -734,8 +749,12 @@ class ScalarNodalSchemeHandler::ScalarNodalScheme : public ScalarNodalSchemeHand
               const CellId cell_id_k = node_to_cell[i_cell_k];
               const size_t i_node_k  = node_local_number_in_its_cells[i_cell_k];
 
-              S(cell_id_j, cell_id_k) +=
-                dt / Vj[cell_id_j] * dot(kappar_invBetar[node_id] * Cjr(cell_id_k, i_node_k), Cjr(cell_id_j, i_node_j));
+              S1(cell_id_j, cell_id_k) +=
+                dt * (1. - cn_coeff / 2.) / Vj[cell_id_j] *
+                dot(kappar_invBetar[node_id] * Cjr(cell_id_k, i_node_k), Cjr(cell_id_j, i_node_j));
+              S2(cell_id_j, cell_id_k) -=
+                dt * (cn_coeff / 2.) / Vj[cell_id_j] *
+                dot(kappar_invBetar[node_id] * Cjr(cell_id_k, i_node_k), Cjr(cell_id_j, i_node_j));
             }
           }
         } else if ((node_is_neumann[node_id]) && (not node_is_corner[node_id]) && (not node_is_dirichlet[node_id])) {
@@ -752,8 +771,13 @@ class ScalarNodalSchemeHandler::ScalarNodalScheme : public ScalarNodalSchemeHand
               const CellId cell_id_k = node_to_cell[i_cell_k];
               const size_t i_node_k  = node_local_number_in_its_cells[i_cell_k];
 
-              S(cell_id_j, cell_id_k) +=
-                dt / Vj[cell_id_j] *
+              S1(cell_id_j, cell_id_k) +=
+                dt * (1. - cn_coeff / 2.) / Vj[cell_id_j] *
+                dot(kappar_invBetar[node_id] *
+                      (Cjr(cell_id_k, i_node_k) - theta(cell_id_k, i_node_k) / sum_theta[node_id] * sum_Cjr[node_id]),
+                    Q * Cjr(cell_id_j, i_node_j));
+              S2(cell_id_j, cell_id_k) -=
+                dt * (cn_coeff / 2.) / Vj[cell_id_j] *
                 dot(kappar_invBetar[node_id] *
                       (Cjr(cell_id_k, i_node_k) - theta(cell_id_k, i_node_k) / sum_theta[node_id] * sum_Cjr[node_id]),
                     Q * Cjr(cell_id_j, i_node_j));
@@ -768,8 +792,12 @@ class ScalarNodalSchemeHandler::ScalarNodalScheme : public ScalarNodalSchemeHand
               const CellId cell_id_k = node_to_cell[i_cell_k];
               const size_t i_node_k  = node_local_number_in_its_cells[i_cell_k];
 
-              S(cell_id_j, cell_id_k) +=
-                dt / Vj[cell_id_j] * dot(kappar_invBetar[node_id] * Cjr(cell_id_k, i_node_k), Cjr(cell_id_j, i_node_j));
+              S1(cell_id_j, cell_id_k) +=
+                dt * (1. - cn_coeff / 2.) / Vj[cell_id_j] *
+                dot(kappar_invBetar[node_id] * Cjr(cell_id_k, i_node_k), Cjr(cell_id_j, i_node_j));
+              S2(cell_id_j, cell_id_k) -=
+                dt * (cn_coeff / 2.) / Vj[cell_id_j] *
+                dot(kappar_invBetar[node_id] * Cjr(cell_id_k, i_node_k), Cjr(cell_id_j, i_node_j));
             }
           }
         } else if (node_is_dirichlet[node_id] && node_is_corner[node_id]) {
@@ -781,8 +809,11 @@ class ScalarNodalSchemeHandler::ScalarNodalScheme : public ScalarNodalSchemeHand
               const CellId cell_id_k = node_to_cell[i_cell_k];
               const size_t i_node_k  = node_local_number_in_its_cells[i_cell_k];
 
-              S(cell_id_j, cell_id_k) +=
-                dt / Vj[cell_id_j] *
+              S1(cell_id_j, cell_id_k) +=
+                dt * (1. - cn_coeff / 2.) / Vj[cell_id_j] *
+                dot(corner_kappar_invBetar[node_id] * Cjr(cell_id_k, i_node_k), Cjr(cell_id_j, i_node_j));
+              S2(cell_id_j, cell_id_k) -=
+                dt * (cn_coeff / 2.) / Vj[cell_id_j] *
                 dot(corner_kappar_invBetar[node_id] * Cjr(cell_id_k, i_node_k), Cjr(cell_id_j, i_node_j));
             }
           }
@@ -790,13 +821,22 @@ class ScalarNodalSchemeHandler::ScalarNodalScheme : public ScalarNodalSchemeHand
       }
 
       for (CellId cell_id = 0; cell_id < mesh->numberOfCells(); ++cell_id) {
-        S(cell_id, cell_id) += 1;
+        S1(cell_id, cell_id) += 1;
+        S2(cell_id, cell_id) += 1;
       }
 
-      CellValue<const double> fj = f->cellValues();
-      CellValue<const double> Ph = P->cellValues();
+      CellValue<const double> fj      = f->cellValues();
+      CellValue<const double> fj_prev = f_prev->cellValues();
+      CellValue<const double> Pj      = P->cellValues();
 
-      CRSMatrix A{S.getCRSMatrix()};
+      Vector<double> Ph{mesh->numberOfCells()};
+      Ph = zero;
+      for (CellId cell_id = 0; cell_id < mesh->numberOfCells(); ++cell_id) {
+        Ph[cell_id] = Pj[cell_id];
+      };
+
+      CRSMatrix A1{S1.getCRSMatrix()};
+      CRSMatrix A2{S2.getCRSMatrix()};
 
       Vector<double> b{mesh->numberOfCells()};
       b = zero;
@@ -804,6 +844,12 @@ class ScalarNodalSchemeHandler::ScalarNodalScheme : public ScalarNodalSchemeHand
         b[cell_id] = fj[cell_id];
       };
 
+      Vector<double> b_prev{mesh->numberOfCells()};
+      b_prev = zero;
+      for (CellId cell_id = 0; cell_id < mesh->numberOfCells(); ++cell_id) {
+        b_prev[cell_id] = fj_prev[cell_id];
+      };
+
       for (NodeId node_id = 0; node_id < mesh->numberOfNodes(); ++node_id) {
         const auto& node_to_cell                   = node_to_cell_matrix[node_id];
         const auto& node_local_number_in_its_cells = node_local_numbers_in_their_cells.itemArray(node_id);
@@ -821,6 +867,10 @@ class ScalarNodalSchemeHandler::ScalarNodalScheme : public ScalarNodalSchemeHand
                             (1. / (sum_theta[node_id] * l2Norm(node_kappar[node_id] * n)) *
                                dot(kappar_invBetar[node_id] * sum_Cjr[node_id], Q * Cjr(cell_id, i_node)) +
                              dot(Cjr(cell_id, i_node), n));
+              b_prev[cell_id] += 1. / Vj[cell_id] * node_boundary_prev_values[node_id] *
+                                 (1. / (sum_theta[node_id] * l2Norm(node_kappar[node_id] * n)) *
+                                    dot(kappar_invBetar[node_id] * sum_Cjr[node_id], Q * Cjr(cell_id, i_node)) +
+                                  dot(Cjr(cell_id, i_node), n));
             }
           } else if (node_is_corner[node_id]) {
             const auto& node_to_face = node_to_face_matrix[node_id];
@@ -831,6 +881,7 @@ class ScalarNodalSchemeHandler::ScalarNodalScheme : public ScalarNodalSchemeHand
               sum_mes_l += mes_l[face_id];
             }
             b[cell_id] += 1. / Vj[cell_id] * 0.5 * node_boundary_values[node_id] * sum_mes_l;
+            b_prev[cell_id] += 1. / Vj[cell_id] * 0.5 * node_boundary_prev_values[node_id] * sum_mes_l;
           }
         } else if (node_is_dirichlet[node_id]) {
           if (not node_is_corner[node_id]) {
@@ -845,6 +896,10 @@ class ScalarNodalSchemeHandler::ScalarNodalScheme : public ScalarNodalSchemeHand
                 b[cell_id_j] += 1. / Vj[cell_id_j] *
                                 dot(node_boundary_values[node_id] * kappar_invBetar[node_id] * Cjr(cell_id_k, i_node_k),
                                     Cjr(cell_id_j, i_node_j));
+                b_prev[cell_id_j] +=
+                  1. / Vj[cell_id_j] *
+                  dot(node_boundary_prev_values[node_id] * kappar_invBetar[node_id] * Cjr(cell_id_k, i_node_k),
+                      Cjr(cell_id_j, i_node_j));
               }
             }
 
@@ -861,6 +916,10 @@ class ScalarNodalSchemeHandler::ScalarNodalScheme : public ScalarNodalSchemeHand
                   1. / Vj[cell_id_j] *
                   dot(node_boundary_values[node_id] * corner_kappar_invBetar[node_id] * Cjr(cell_id_k, i_node_k),
                       Cjr(cell_id_j, i_node_j));
+                b_prev[cell_id_j] +=
+                  1. / Vj[cell_id_j] *
+                  dot(node_boundary_prev_values[node_id] * corner_kappar_invBetar[node_id] * Cjr(cell_id_k, i_node_k),
+                      Cjr(cell_id_j, i_node_j));
               }
             }
           }
@@ -870,14 +929,19 @@ class ScalarNodalSchemeHandler::ScalarNodalScheme : public ScalarNodalSchemeHand
       Vector<double> T{mesh->numberOfCells()};
       T = zero;
 
+      // Array<double> Ph2  = Ph;
+      Vector<double> A2P = A2 * Ph;
+
       Vector<double> B{mesh->numberOfCells()};
       parallel_for(
-        mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { B[cell_id] = dt * b[cell_id] + Ph[cell_id]; });
+        mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) {
+          B[cell_id] = dt * ((1. - cn_coeff / 2.) * b[cell_id] + cn_coeff / 2. * b_prev[cell_id]) + A2P[cell_id];
+        });
 
       // std::cout << "g = " << node_boundary_values << "\n";
 
       LinearSolver solver;
-      solver.solveLocalSystem(A, T, B);
+      solver.solveLocalSystem(A1, T, B);
 
       m_solution     = std::make_shared<DiscreteFunctionP0<Dimension, double>>(mesh);
       auto& solution = *m_solution;